| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/browser_feature_extractor.h" | 5 #include "chrome/browser/safe_browsing/browser_feature_extractor.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 GURL("http://google.com/"), | 295 GURL("http://google.com/"), |
| 296 content::PageTransitionFromInt( | 296 content::PageTransitionFromInt( |
| 297 content::PAGE_TRANSITION_AUTO_BOOKMARK | | 297 content::PAGE_TRANSITION_AUTO_BOOKMARK | |
| 298 content::PAGE_TRANSITION_FORWARD_BACK)); | 298 content::PAGE_TRANSITION_FORWARD_BACK)); |
| 299 | 299 |
| 300 EXPECT_TRUE(ExtractFeatures(&request)); | 300 EXPECT_TRUE(ExtractFeatures(&request)); |
| 301 std::map<std::string, double> features; | 301 std::map<std::string, double> features; |
| 302 GetFeatureMap(request, &features); | 302 GetFeatureMap(request, &features); |
| 303 | 303 |
| 304 EXPECT_EQ(1.0, | 304 EXPECT_EQ(1.0, |
| 305 features[StringPrintf("%s=%s", | 305 features[base::StringPrintf("%s=%s", |
| 306 features::kReferrer, | 306 features::kReferrer, |
| 307 "http://google.com/")]); | 307 "http://google.com/")]); |
| 308 EXPECT_EQ(1.0, | 308 EXPECT_EQ(1.0, |
| 309 features[StringPrintf("%s[0]=%s", | 309 features[base::StringPrintf("%s[0]=%s", |
| 310 features::kRedirect, | 310 features::kRedirect, |
| 311 "http://somerandomwebsite.com/")]); | 311 "http://somerandomwebsite.com/")]); |
| 312 // We shouldn't have a feature for the last redirect in the chain, since it | 312 // We shouldn't have a feature for the last redirect in the chain, since it |
| 313 // should always be the URL that we navigated to. | 313 // should always be the URL that we navigated to. |
| 314 EXPECT_EQ(0.0, | 314 EXPECT_EQ(0.0, |
| 315 features[StringPrintf("%s[1]=%s", | 315 features[base::StringPrintf("%s[1]=%s", |
| 316 features::kRedirect, | 316 features::kRedirect, |
| 317 "http://foo.com/")]); | 317 "http://foo.com/")]); |
| 318 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); | 318 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); |
| 319 EXPECT_EQ(2.0, features[features::kPageTransitionType]); | 319 EXPECT_EQ(2.0, features[features::kPageTransitionType]); |
| 320 EXPECT_EQ(1.0, features[features::kIsFirstNavigation]); | 320 EXPECT_EQ(1.0, features[features::kIsFirstNavigation]); |
| 321 EXPECT_EQ(200.0, features[features::kHttpStatusCode]); | 321 EXPECT_EQ(200.0, features[features::kHttpStatusCode]); |
| 322 | 322 |
| 323 request.Clear(); | 323 request.Clear(); |
| 324 request.set_url("http://www.foo.com/page.html"); | 324 request.set_url("http://www.foo.com/page.html"); |
| 325 request.set_client_score(0.5); | 325 request.set_client_score(0.5); |
| 326 redirect_chain.clear(); | 326 redirect_chain.clear(); |
| 327 redirect_chain.push_back(GURL("http://www.foo.com/redirect")); | 327 redirect_chain.push_back(GURL("http://www.foo.com/redirect")); |
| 328 redirect_chain.push_back(GURL("http://www.foo.com/second_redirect")); | 328 redirect_chain.push_back(GURL("http://www.foo.com/second_redirect")); |
| 329 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); | 329 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); |
| 330 SetRedirectChain(redirect_chain, false); | 330 SetRedirectChain(redirect_chain, false); |
| 331 browse_info_->http_status_code = 404; | 331 browse_info_->http_status_code = 404; |
| 332 NavigateAndCommit(GURL("http://www.foo.com/page.html"), | 332 NavigateAndCommit(GURL("http://www.foo.com/page.html"), |
| 333 GURL("http://www.foo.com"), | 333 GURL("http://www.foo.com"), |
| 334 content::PageTransitionFromInt( | 334 content::PageTransitionFromInt( |
| 335 content::PAGE_TRANSITION_TYPED | | 335 content::PAGE_TRANSITION_TYPED | |
| 336 content::PAGE_TRANSITION_CHAIN_START | | 336 content::PAGE_TRANSITION_CHAIN_START | |
| 337 content::PAGE_TRANSITION_CLIENT_REDIRECT)); | 337 content::PAGE_TRANSITION_CLIENT_REDIRECT)); |
| 338 | 338 |
| 339 EXPECT_TRUE(ExtractFeatures(&request)); | 339 EXPECT_TRUE(ExtractFeatures(&request)); |
| 340 features.clear(); | 340 features.clear(); |
| 341 GetFeatureMap(request, &features); | 341 GetFeatureMap(request, &features); |
| 342 | 342 |
| 343 EXPECT_EQ(1, | 343 EXPECT_EQ(1, |
| 344 features[StringPrintf("%s=%s", | 344 features[base::StringPrintf("%s=%s", |
| 345 features::kReferrer, | 345 features::kReferrer, |
| 346 "http://www.foo.com/")]); | 346 "http://www.foo.com/")]); |
| 347 EXPECT_EQ(1.0, | 347 EXPECT_EQ(1.0, |
| 348 features[StringPrintf("%s[0]=%s", | 348 features[base::StringPrintf("%s[0]=%s", |
| 349 features::kRedirect, | 349 features::kRedirect, |
| 350 "http://www.foo.com/redirect")]); | 350 "http://www.foo.com/redirect")]); |
| 351 EXPECT_EQ(1.0, | 351 EXPECT_EQ(1.0, |
| 352 features[StringPrintf("%s[1]=%s", | 352 features[base::StringPrintf("%s[1]=%s", |
| 353 features::kRedirect, | 353 features::kRedirect, |
| 354 "http://www.foo.com/second_redirect")]); | 354 "http://www.foo.com/second_redirect")]); |
| 355 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); | 355 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); |
| 356 EXPECT_EQ(1.0, features[features::kPageTransitionType]); | 356 EXPECT_EQ(1.0, features[features::kPageTransitionType]); |
| 357 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); | 357 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); |
| 358 EXPECT_EQ(1.0, | 358 EXPECT_EQ(1.0, |
| 359 features[StringPrintf("%s%s=%s", | 359 features[base::StringPrintf("%s%s=%s", |
| 360 features::kHostPrefix, | 360 features::kHostPrefix, |
| 361 features::kReferrer, | 361 features::kReferrer, |
| 362 "http://google.com/")]); | 362 "http://google.com/")]); |
| 363 EXPECT_EQ(1.0, | 363 EXPECT_EQ(1.0, |
| 364 features[StringPrintf("%s%s[0]=%s", | 364 features[base::StringPrintf("%s%s[0]=%s", |
| 365 features::kHostPrefix, | 365 features::kHostPrefix, |
| 366 features::kRedirect, | 366 features::kRedirect, |
| 367 "http://somerandomwebsite.com/")]); | 367 "http://somerandomwebsite.com/")]); |
| 368 EXPECT_EQ(2.0, | 368 EXPECT_EQ(2.0, |
| 369 features[StringPrintf("%s%s", | 369 features[base::StringPrintf("%s%s", |
| 370 features::kHostPrefix, | 370 features::kHostPrefix, |
| 371 features::kPageTransitionType)]); | 371 features::kPageTransitionType)]); |
| 372 EXPECT_EQ(1.0, | 372 EXPECT_EQ(1.0, |
| 373 features[StringPrintf("%s%s", | 373 features[base::StringPrintf("%s%s", |
| 374 features::kHostPrefix, | 374 features::kHostPrefix, |
| 375 features::kIsFirstNavigation)]); | 375 features::kIsFirstNavigation)]); |
| 376 EXPECT_EQ(404.0, features[features::kHttpStatusCode]); | 376 EXPECT_EQ(404.0, features[features::kHttpStatusCode]); |
| 377 | 377 |
| 378 request.Clear(); | 378 request.Clear(); |
| 379 request.set_url("http://www.bar.com/"); | 379 request.set_url("http://www.bar.com/"); |
| 380 request.set_client_score(0.5); | 380 request.set_client_score(0.5); |
| 381 redirect_chain.clear(); | 381 redirect_chain.clear(); |
| 382 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); | 382 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); |
| 383 redirect_chain.push_back(GURL("http://www.bar.com/")); | 383 redirect_chain.push_back(GURL("http://www.bar.com/")); |
| 384 SetRedirectChain(redirect_chain, true); | 384 SetRedirectChain(redirect_chain, true); |
| 385 NavigateAndCommit(GURL("http://www.bar.com/"), | 385 NavigateAndCommit(GURL("http://www.bar.com/"), |
| 386 GURL("http://www.foo.com/page.html"), | 386 GURL("http://www.foo.com/page.html"), |
| 387 content::PageTransitionFromInt( | 387 content::PageTransitionFromInt( |
| 388 content::PAGE_TRANSITION_LINK | | 388 content::PAGE_TRANSITION_LINK | |
| 389 content::PAGE_TRANSITION_CHAIN_END | | 389 content::PAGE_TRANSITION_CHAIN_END | |
| 390 content::PAGE_TRANSITION_CLIENT_REDIRECT)); | 390 content::PAGE_TRANSITION_CLIENT_REDIRECT)); |
| 391 | 391 |
| 392 EXPECT_TRUE(ExtractFeatures(&request)); | 392 EXPECT_TRUE(ExtractFeatures(&request)); |
| 393 features.clear(); | 393 features.clear(); |
| 394 GetFeatureMap(request, &features); | 394 GetFeatureMap(request, &features); |
| 395 | 395 |
| 396 EXPECT_EQ(1.0, | 396 EXPECT_EQ(1.0, |
| 397 features[StringPrintf("%s=%s", | 397 features[base::StringPrintf("%s=%s", |
| 398 features::kReferrer, | 398 features::kReferrer, |
| 399 "http://www.foo.com/page.html")]); | 399 "http://www.foo.com/page.html")]); |
| 400 EXPECT_EQ(1.0, | 400 EXPECT_EQ(1.0, |
| 401 features[StringPrintf("%s[0]=%s", | 401 features[base::StringPrintf("%s[0]=%s", |
| 402 features::kRedirect, | 402 features::kRedirect, |
| 403 "http://www.foo.com/page.html")]); | 403 "http://www.foo.com/page.html")]); |
| 404 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); | 404 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); |
| 405 EXPECT_EQ(0.0, features[features::kPageTransitionType]); | 405 EXPECT_EQ(0.0, features[features::kPageTransitionType]); |
| 406 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); | 406 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); |
| 407 | 407 |
| 408 // Should not have host features. | 408 // Should not have host features. |
| 409 EXPECT_EQ(0U, | 409 EXPECT_EQ(0U, |
| 410 features.count(StringPrintf("%s%s", | 410 features.count(base::StringPrintf("%s%s", |
| 411 features::kHostPrefix, | 411 features::kHostPrefix, |
| 412 features::kPageTransitionType))); | 412 features::kPageTransitionType))); |
| 413 EXPECT_EQ(0U, | 413 EXPECT_EQ(0U, |
| 414 features.count(StringPrintf("%s%s", | 414 features.count(base::StringPrintf("%s%s", |
| 415 features::kHostPrefix, | 415 features::kHostPrefix, |
| 416 features::kIsFirstNavigation))); | 416 features::kIsFirstNavigation))); |
| 417 | 417 |
| 418 request.Clear(); | 418 request.Clear(); |
| 419 request.set_url("http://www.bar.com/other_page.html"); | 419 request.set_url("http://www.bar.com/other_page.html"); |
| 420 request.set_client_score(0.5); | 420 request.set_client_score(0.5); |
| 421 redirect_chain.clear(); | 421 redirect_chain.clear(); |
| 422 redirect_chain.push_back(GURL("http://www.bar.com/other_page.html")); | 422 redirect_chain.push_back(GURL("http://www.bar.com/other_page.html")); |
| 423 SetRedirectChain(redirect_chain, false); | 423 SetRedirectChain(redirect_chain, false); |
| 424 NavigateAndCommit(GURL("http://www.bar.com/other_page.html"), | 424 NavigateAndCommit(GURL("http://www.bar.com/other_page.html"), |
| 425 GURL("http://www.bar.com/"), | 425 GURL("http://www.bar.com/"), |
| 426 content::PAGE_TRANSITION_LINK); | 426 content::PAGE_TRANSITION_LINK); |
| 427 | 427 |
| 428 EXPECT_TRUE(ExtractFeatures(&request)); | 428 EXPECT_TRUE(ExtractFeatures(&request)); |
| 429 features.clear(); | 429 features.clear(); |
| 430 GetFeatureMap(request, &features); | 430 GetFeatureMap(request, &features); |
| 431 | 431 |
| 432 EXPECT_EQ(1.0, | 432 EXPECT_EQ(1.0, |
| 433 features[StringPrintf("%s=%s", | 433 features[base::StringPrintf("%s=%s", |
| 434 features::kReferrer, | 434 features::kReferrer, |
| 435 "http://www.bar.com/")]); | 435 "http://www.bar.com/")]); |
| 436 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); | 436 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); |
| 437 EXPECT_EQ(0.0, features[features::kPageTransitionType]); | 437 EXPECT_EQ(0.0, features[features::kPageTransitionType]); |
| 438 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); | 438 EXPECT_EQ(0.0, features[features::kIsFirstNavigation]); |
| 439 EXPECT_EQ(1.0, | 439 EXPECT_EQ(1.0, |
| 440 features[StringPrintf("%s%s=%s", | 440 features[base::StringPrintf("%s%s=%s", |
| 441 features::kHostPrefix, | 441 features::kHostPrefix, |
| 442 features::kReferrer, | 442 features::kReferrer, |
| 443 "http://www.foo.com/page.html")]); | 443 "http://www.foo.com/page.html")]); |
| 444 EXPECT_EQ(1.0, | 444 EXPECT_EQ(1.0, |
| 445 features[StringPrintf("%s%s[0]=%s", | 445 features[base::StringPrintf("%s%s[0]=%s", |
| 446 features::kHostPrefix, | 446 features::kHostPrefix, |
| 447 features::kRedirect, | 447 features::kRedirect, |
| 448 "http://www.foo.com/page.html")]); | 448 "http://www.foo.com/page.html")]); |
| 449 EXPECT_EQ(0.0, | 449 EXPECT_EQ(0.0, |
| 450 features[StringPrintf("%s%s", | 450 features[base::StringPrintf("%s%s", |
| 451 features::kHostPrefix, | 451 features::kHostPrefix, |
| 452 features::kPageTransitionType)]); | 452 features::kPageTransitionType)]); |
| 453 EXPECT_EQ(0.0, | 453 EXPECT_EQ(0.0, |
| 454 features[StringPrintf("%s%s", | 454 features[base::StringPrintf("%s%s", |
| 455 features::kHostPrefix, | 455 features::kHostPrefix, |
| 456 features::kIsFirstNavigation)]); | 456 features::kIsFirstNavigation)]); |
| 457 request.Clear(); | 457 request.Clear(); |
| 458 request.set_url("http://www.baz.com/"); | 458 request.set_url("http://www.baz.com/"); |
| 459 request.set_client_score(0.5); | 459 request.set_client_score(0.5); |
| 460 redirect_chain.clear(); | 460 redirect_chain.clear(); |
| 461 redirect_chain.push_back(GURL("https://bankofamerica.com")); | 461 redirect_chain.push_back(GURL("https://bankofamerica.com")); |
| 462 redirect_chain.push_back(GURL("http://www.baz.com/")); | 462 redirect_chain.push_back(GURL("http://www.baz.com/")); |
| 463 SetRedirectChain(redirect_chain, true); | 463 SetRedirectChain(redirect_chain, true); |
| 464 NavigateAndCommit(GURL("http://www.baz.com"), | 464 NavigateAndCommit(GURL("http://www.baz.com"), |
| 465 GURL("https://bankofamerica.com"), | 465 GURL("https://bankofamerica.com"), |
| 466 content::PAGE_TRANSITION_GENERATED); | 466 content::PAGE_TRANSITION_GENERATED); |
| 467 | 467 |
| 468 browse_info_->ips.insert("193.5.163.8"); | 468 browse_info_->ips.insert("193.5.163.8"); |
| 469 browse_info_->ips.insert("23.94.78.1"); | 469 browse_info_->ips.insert("23.94.78.1"); |
| 470 EXPECT_CALL(*service_, IsBadIpAddress("193.5.163.8")).WillOnce(Return(true)); | 470 EXPECT_CALL(*service_, IsBadIpAddress("193.5.163.8")).WillOnce(Return(true)); |
| 471 EXPECT_CALL(*service_, IsBadIpAddress("23.94.78.1")).WillOnce(Return(false)); | 471 EXPECT_CALL(*service_, IsBadIpAddress("23.94.78.1")).WillOnce(Return(false)); |
| 472 | 472 |
| 473 EXPECT_TRUE(ExtractFeatures(&request)); | 473 EXPECT_TRUE(ExtractFeatures(&request)); |
| 474 features.clear(); | 474 features.clear(); |
| 475 GetFeatureMap(request, &features); | 475 GetFeatureMap(request, &features); |
| 476 | 476 |
| 477 EXPECT_EQ(1.0, | 477 EXPECT_EQ(1.0, |
| 478 features[StringPrintf("%s[0]=%s", | 478 features[base::StringPrintf("%s[0]=%s", |
| 479 features::kRedirect, | 479 features::kRedirect, |
| 480 features::kSecureRedirectValue)]); | 480 features::kSecureRedirectValue)]); |
| 481 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); | 481 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); |
| 482 EXPECT_EQ(5.0, features[features::kPageTransitionType]); | 482 EXPECT_EQ(5.0, features[features::kPageTransitionType]); |
| 483 // Should not have redirect or host features. | 483 // Should not have redirect or host features. |
| 484 EXPECT_EQ(0U, | 484 EXPECT_EQ(0U, |
| 485 features.count(StringPrintf("%s%s", | 485 features.count(base::StringPrintf("%s%s", |
| 486 features::kHostPrefix, | 486 features::kHostPrefix, |
| 487 features::kPageTransitionType))); | 487 features::kPageTransitionType))); |
| 488 EXPECT_EQ(0U, | 488 EXPECT_EQ(0U, |
| 489 features.count(StringPrintf("%s%s", | 489 features.count(base::StringPrintf("%s%s", |
| 490 features::kHostPrefix, | 490 features::kHostPrefix, |
| 491 features::kIsFirstNavigation))); | 491 features::kIsFirstNavigation))); |
| 492 EXPECT_EQ(5.0, features[features::kPageTransitionType]); | 492 EXPECT_EQ(5.0, features[features::kPageTransitionType]); |
| 493 EXPECT_EQ(1.0, features[std::string(features::kBadIpFetch) + "193.5.163.8"]); | 493 EXPECT_EQ(1.0, features[std::string(features::kBadIpFetch) + "193.5.163.8"]); |
| 494 EXPECT_FALSE(features.count(std::string(features::kBadIpFetch) + | 494 EXPECT_FALSE(features.count(std::string(features::kBadIpFetch) + |
| 495 "23.94.78.1")); | 495 "23.94.78.1")); |
| 496 } | 496 } |
| 497 | 497 |
| 498 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) { | 498 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) { |
| 499 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html")); | 499 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html")); |
| 500 ClientPhishingRequest request; | 500 ClientPhishingRequest request; |
| 501 request.set_url("http://www.foo.com/malware.html"); | 501 request.set_url("http://www.foo.com/malware.html"); |
| 502 request.set_client_score(0.5); | 502 request.set_client_score(0.5); |
| 503 | 503 |
| 504 browse_info_->unsafe_resource.reset( | 504 browse_info_->unsafe_resource.reset( |
| 505 new SafeBrowsingUIManager::UnsafeResource); | 505 new SafeBrowsingUIManager::UnsafeResource); |
| 506 browse_info_->unsafe_resource->url = GURL("http://www.malware.com/"); | 506 browse_info_->unsafe_resource->url = GURL("http://www.malware.com/"); |
| 507 browse_info_->unsafe_resource->original_url = GURL("http://www.good.com/"); | 507 browse_info_->unsafe_resource->original_url = GURL("http://www.good.com/"); |
| 508 browse_info_->unsafe_resource->is_subresource = true; | 508 browse_info_->unsafe_resource->is_subresource = true; |
| 509 browse_info_->unsafe_resource->threat_type = SB_THREAT_TYPE_URL_MALWARE; | 509 browse_info_->unsafe_resource->threat_type = SB_THREAT_TYPE_URL_MALWARE; |
| 510 | 510 |
| 511 ExtractFeatures(&request); | 511 ExtractFeatures(&request); |
| 512 std::map<std::string, double> features; | 512 std::map<std::string, double> features; |
| 513 GetFeatureMap(request, &features); | 513 GetFeatureMap(request, &features); |
| 514 EXPECT_TRUE(features.count(StringPrintf("%s%s", | 514 EXPECT_TRUE(features.count(base::StringPrintf( |
| 515 features::kSafeBrowsingMaliciousUrl, | 515 "%s%s", |
| 516 "http://www.malware.com/"))); | 516 features::kSafeBrowsingMaliciousUrl, |
| 517 EXPECT_TRUE(features.count(StringPrintf("%s%s", | 517 "http://www.malware.com/"))); |
| 518 features::kSafeBrowsingOriginalUrl, | 518 EXPECT_TRUE(features.count(base::StringPrintf( |
| 519 "http://www.good.com/"))); | 519 "%s%s", |
| 520 features::kSafeBrowsingOriginalUrl, |
| 521 "http://www.good.com/"))); |
| 520 EXPECT_DOUBLE_EQ(1.0, features[features::kSafeBrowsingIsSubresource]); | 522 EXPECT_DOUBLE_EQ(1.0, features[features::kSafeBrowsingIsSubresource]); |
| 521 EXPECT_DOUBLE_EQ(2.0, features[features::kSafeBrowsingThreatType]); | 523 EXPECT_DOUBLE_EQ(2.0, features[features::kSafeBrowsingThreatType]); |
| 522 } | 524 } |
| 523 } // namespace safe_browsing | 525 } // namespace safe_browsing |
| OLD | NEW |