| 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 |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 15 #include "chrome/browser/history/history_backend.h" | 15 #include "chrome/browser/history/history_backend.h" |
| 16 #include "chrome/browser/history/history_service.h" | 16 #include "chrome/browser/history/history_service.h" |
| 17 #include "chrome/browser/history/history_service_factory.h" | 17 #include "chrome/browser/history/history_service_factory.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/safe_browsing/browser_features.h" | 19 #include "chrome/browser/safe_browsing/browser_features.h" |
| 20 #include "chrome/browser/safe_browsing/client_side_detection_host.h" | 20 #include "chrome/browser/safe_browsing/client_side_detection_host.h" |
| 21 #include "chrome/browser/safe_browsing/database_manager.h" | 21 #include "chrome/browser/safe_browsing/database_manager.h" |
| 22 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 22 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 23 #include "chrome/browser/safe_browsing/ui_manager.h" | 23 #include "chrome/browser/safe_browsing/ui_manager.h" |
| 24 #include "chrome/common/safe_browsing/csd.pb.h" | 24 #include "chrome/common/safe_browsing/csd.pb.h" |
| 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 26 #include "chrome/test/base/testing_profile.h" | 26 #include "chrome/test/base/testing_profile.h" |
| 27 #include "content/public/browser/navigation_controller.h" | 27 #include "content/public/browser/navigation_controller.h" |
| 28 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 29 #include "content/public/common/page_transition_types.h" | |
| 30 #include "content/public/common/referrer.h" | 29 #include "content/public/common/referrer.h" |
| 31 #include "content/public/test/test_browser_thread.h" | 30 #include "content/public/test/test_browser_thread.h" |
| 32 #include "content/public/test/web_contents_tester.h" | 31 #include "content/public/test/web_contents_tester.h" |
| 33 #include "testing/gmock/include/gmock/gmock.h" | 32 #include "testing/gmock/include/gmock/gmock.h" |
| 34 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
| 34 #include "ui/base/page_transition_types.h" |
| 35 #include "url/gurl.h" | 35 #include "url/gurl.h" |
| 36 | 36 |
| 37 using content::BrowserThread; | 37 using content::BrowserThread; |
| 38 using content::ResourceType; | 38 using content::ResourceType; |
| 39 using content::WebContentsTester; | 39 using content::WebContentsTester; |
| 40 | 40 |
| 41 using testing::DoAll; | 41 using testing::DoAll; |
| 42 using testing::Return; | 42 using testing::Return; |
| 43 using testing::StrictMock; | 43 using testing::StrictMock; |
| 44 | 44 |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 browse_info_->host_redirects = redirect_chain; | 114 browse_info_->host_redirects = redirect_chain; |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Wrapper around NavigateAndCommit that also sets the redirect chain to | 118 // Wrapper around NavigateAndCommit that also sets the redirect chain to |
| 119 // a sane value. | 119 // a sane value. |
| 120 void SimpleNavigateAndCommit(const GURL& url) { | 120 void SimpleNavigateAndCommit(const GURL& url) { |
| 121 std::vector<GURL> redirect_chain; | 121 std::vector<GURL> redirect_chain; |
| 122 redirect_chain.push_back(url); | 122 redirect_chain.push_back(url); |
| 123 SetRedirectChain(redirect_chain, true); | 123 SetRedirectChain(redirect_chain, true); |
| 124 NavigateAndCommit(url, GURL(), content::PAGE_TRANSITION_LINK); | 124 NavigateAndCommit(url, GURL(), ui::PAGE_TRANSITION_LINK); |
| 125 } | 125 } |
| 126 | 126 |
| 127 // This is similar to NavigateAndCommit that is in WebContentsTester, but | 127 // This is similar to NavigateAndCommit that is in WebContentsTester, but |
| 128 // allows us to specify the referrer and page_transition_type. | 128 // allows us to specify the referrer and page_transition_type. |
| 129 void NavigateAndCommit(const GURL& url, | 129 void NavigateAndCommit(const GURL& url, |
| 130 const GURL& referrer, | 130 const GURL& referrer, |
| 131 content::PageTransition type) { | 131 ui::PageTransition type) { |
| 132 web_contents()->GetController().LoadURL( | 132 web_contents()->GetController().LoadURL( |
| 133 url, content::Referrer(referrer, blink::WebReferrerPolicyDefault), | 133 url, content::Referrer(referrer, blink::WebReferrerPolicyDefault), |
| 134 type, std::string()); | 134 type, std::string()); |
| 135 | 135 |
| 136 static int page_id = 0; | 136 static int page_id = 0; |
| 137 content::RenderFrameHost* rfh = | 137 content::RenderFrameHost* rfh = |
| 138 WebContentsTester::For(web_contents())->GetPendingMainFrame(); | 138 WebContentsTester::For(web_contents())->GetPendingMainFrame(); |
| 139 if (!rfh) { | 139 if (!rfh) { |
| 140 rfh = web_contents()->GetMainFrame(); | 140 rfh = web_contents()->GetMainFrame(); |
| 141 } | 141 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 history::SOURCE_BROWSED); // same host HTTPS. | 262 history::SOURCE_BROWSED); // same host HTTPS. |
| 263 history_service()->AddPage(GURL("http://www.foo.com/gaa.html"), | 263 history_service()->AddPage(GURL("http://www.foo.com/gaa.html"), |
| 264 base::Time::Now(), | 264 base::Time::Now(), |
| 265 history::SOURCE_BROWSED); // same host HTTP. | 265 history::SOURCE_BROWSED); // same host HTTP. |
| 266 history_service()->AddPage(GURL("http://bar.foo.com/gaa.html"), | 266 history_service()->AddPage(GURL("http://bar.foo.com/gaa.html"), |
| 267 base::Time::Now(), | 267 base::Time::Now(), |
| 268 history::SOURCE_BROWSED); // different host. | 268 history::SOURCE_BROWSED); // different host. |
| 269 history_service()->AddPage(GURL("http://www.foo.com/bar.html?a=b"), | 269 history_service()->AddPage(GURL("http://www.foo.com/bar.html?a=b"), |
| 270 base::Time::Now() - base::TimeDelta::FromHours(23), | 270 base::Time::Now() - base::TimeDelta::FromHours(23), |
| 271 NULL, 0, GURL(), history::RedirectList(), | 271 NULL, 0, GURL(), history::RedirectList(), |
| 272 content::PAGE_TRANSITION_LINK, | 272 ui::PAGE_TRANSITION_LINK, |
| 273 history::SOURCE_BROWSED, false); | 273 history::SOURCE_BROWSED, false); |
| 274 history_service()->AddPage(GURL("http://www.foo.com/bar.html"), | 274 history_service()->AddPage(GURL("http://www.foo.com/bar.html"), |
| 275 base::Time::Now() - base::TimeDelta::FromHours(25), | 275 base::Time::Now() - base::TimeDelta::FromHours(25), |
| 276 NULL, 0, GURL(), history::RedirectList(), | 276 NULL, 0, GURL(), history::RedirectList(), |
| 277 content::PAGE_TRANSITION_TYPED, | 277 ui::PAGE_TRANSITION_TYPED, |
| 278 history::SOURCE_BROWSED, false); | 278 history::SOURCE_BROWSED, false); |
| 279 history_service()->AddPage(GURL("https://www.foo.com/goo.html"), | 279 history_service()->AddPage(GURL("https://www.foo.com/goo.html"), |
| 280 base::Time::Now() - base::TimeDelta::FromDays(5), | 280 base::Time::Now() - base::TimeDelta::FromDays(5), |
| 281 NULL, 0, GURL(), history::RedirectList(), | 281 NULL, 0, GURL(), history::RedirectList(), |
| 282 content::PAGE_TRANSITION_TYPED, | 282 ui::PAGE_TRANSITION_TYPED, |
| 283 history::SOURCE_BROWSED, false); | 283 history::SOURCE_BROWSED, false); |
| 284 | 284 |
| 285 SimpleNavigateAndCommit(GURL("http://www.foo.com/bar.html")); | 285 SimpleNavigateAndCommit(GURL("http://www.foo.com/bar.html")); |
| 286 | 286 |
| 287 ClientPhishingRequest request; | 287 ClientPhishingRequest request; |
| 288 request.set_url("http://www.foo.com/bar.html"); | 288 request.set_url("http://www.foo.com/bar.html"); |
| 289 request.set_client_score(0.5); | 289 request.set_client_score(0.5); |
| 290 EXPECT_TRUE(ExtractFeatures(&request)); | 290 EXPECT_TRUE(ExtractFeatures(&request)); |
| 291 std::map<std::string, double> features; | 291 std::map<std::string, double> features; |
| 292 GetFeatureMap(request, &features); | 292 GetFeatureMap(request, &features); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 ClientPhishingRequest request; | 365 ClientPhishingRequest request; |
| 366 request.set_url("http://www.foo.com/"); | 366 request.set_url("http://www.foo.com/"); |
| 367 request.set_client_score(0.5); | 367 request.set_client_score(0.5); |
| 368 std::vector<GURL> redirect_chain; | 368 std::vector<GURL> redirect_chain; |
| 369 redirect_chain.push_back(GURL("http://somerandomwebsite.com/")); | 369 redirect_chain.push_back(GURL("http://somerandomwebsite.com/")); |
| 370 redirect_chain.push_back(GURL("http://www.foo.com/")); | 370 redirect_chain.push_back(GURL("http://www.foo.com/")); |
| 371 SetRedirectChain(redirect_chain, true); | 371 SetRedirectChain(redirect_chain, true); |
| 372 browse_info_->http_status_code = 200; | 372 browse_info_->http_status_code = 200; |
| 373 NavigateAndCommit(GURL("http://www.foo.com/"), | 373 NavigateAndCommit(GURL("http://www.foo.com/"), |
| 374 GURL("http://google.com/"), | 374 GURL("http://google.com/"), |
| 375 content::PageTransitionFromInt( | 375 ui::PageTransitionFromInt( |
| 376 content::PAGE_TRANSITION_AUTO_BOOKMARK | | 376 ui::PAGE_TRANSITION_AUTO_BOOKMARK | |
| 377 content::PAGE_TRANSITION_FORWARD_BACK)); | 377 ui::PAGE_TRANSITION_FORWARD_BACK)); |
| 378 | 378 |
| 379 EXPECT_TRUE(ExtractFeatures(&request)); | 379 EXPECT_TRUE(ExtractFeatures(&request)); |
| 380 std::map<std::string, double> features; | 380 std::map<std::string, double> features; |
| 381 GetFeatureMap(request, &features); | 381 GetFeatureMap(request, &features); |
| 382 | 382 |
| 383 EXPECT_EQ(1.0, | 383 EXPECT_EQ(1.0, |
| 384 features[base::StringPrintf("%s=%s", | 384 features[base::StringPrintf("%s=%s", |
| 385 features::kReferrer, | 385 features::kReferrer, |
| 386 "http://google.com/")]); | 386 "http://google.com/")]); |
| 387 EXPECT_EQ(1.0, | 387 EXPECT_EQ(1.0, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 403 request.set_url("http://www.foo.com/page.html"); | 403 request.set_url("http://www.foo.com/page.html"); |
| 404 request.set_client_score(0.5); | 404 request.set_client_score(0.5); |
| 405 redirect_chain.clear(); | 405 redirect_chain.clear(); |
| 406 redirect_chain.push_back(GURL("http://www.foo.com/redirect")); | 406 redirect_chain.push_back(GURL("http://www.foo.com/redirect")); |
| 407 redirect_chain.push_back(GURL("http://www.foo.com/second_redirect")); | 407 redirect_chain.push_back(GURL("http://www.foo.com/second_redirect")); |
| 408 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); | 408 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); |
| 409 SetRedirectChain(redirect_chain, false); | 409 SetRedirectChain(redirect_chain, false); |
| 410 browse_info_->http_status_code = 404; | 410 browse_info_->http_status_code = 404; |
| 411 NavigateAndCommit(GURL("http://www.foo.com/page.html"), | 411 NavigateAndCommit(GURL("http://www.foo.com/page.html"), |
| 412 GURL("http://www.foo.com"), | 412 GURL("http://www.foo.com"), |
| 413 content::PageTransitionFromInt( | 413 ui::PageTransitionFromInt( |
| 414 content::PAGE_TRANSITION_TYPED | | 414 ui::PAGE_TRANSITION_TYPED | |
| 415 content::PAGE_TRANSITION_CHAIN_START | | 415 ui::PAGE_TRANSITION_CHAIN_START | |
| 416 content::PAGE_TRANSITION_CLIENT_REDIRECT)); | 416 ui::PAGE_TRANSITION_CLIENT_REDIRECT)); |
| 417 | 417 |
| 418 EXPECT_TRUE(ExtractFeatures(&request)); | 418 EXPECT_TRUE(ExtractFeatures(&request)); |
| 419 features.clear(); | 419 features.clear(); |
| 420 GetFeatureMap(request, &features); | 420 GetFeatureMap(request, &features); |
| 421 | 421 |
| 422 EXPECT_EQ(1, | 422 EXPECT_EQ(1, |
| 423 features[base::StringPrintf("%s=%s", | 423 features[base::StringPrintf("%s=%s", |
| 424 features::kReferrer, | 424 features::kReferrer, |
| 425 "http://www.foo.com/")]); | 425 "http://www.foo.com/")]); |
| 426 EXPECT_EQ(1.0, | 426 EXPECT_EQ(1.0, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 456 | 456 |
| 457 request.Clear(); | 457 request.Clear(); |
| 458 request.set_url("http://www.bar.com/"); | 458 request.set_url("http://www.bar.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("http://www.foo.com/page.html")); | 461 redirect_chain.push_back(GURL("http://www.foo.com/page.html")); |
| 462 redirect_chain.push_back(GURL("http://www.bar.com/")); | 462 redirect_chain.push_back(GURL("http://www.bar.com/")); |
| 463 SetRedirectChain(redirect_chain, true); | 463 SetRedirectChain(redirect_chain, true); |
| 464 NavigateAndCommit(GURL("http://www.bar.com/"), | 464 NavigateAndCommit(GURL("http://www.bar.com/"), |
| 465 GURL("http://www.foo.com/page.html"), | 465 GURL("http://www.foo.com/page.html"), |
| 466 content::PageTransitionFromInt( | 466 ui::PageTransitionFromInt( |
| 467 content::PAGE_TRANSITION_LINK | | 467 ui::PAGE_TRANSITION_LINK | |
| 468 content::PAGE_TRANSITION_CHAIN_END | | 468 ui::PAGE_TRANSITION_CHAIN_END | |
| 469 content::PAGE_TRANSITION_CLIENT_REDIRECT)); | 469 ui::PAGE_TRANSITION_CLIENT_REDIRECT)); |
| 470 | 470 |
| 471 EXPECT_TRUE(ExtractFeatures(&request)); | 471 EXPECT_TRUE(ExtractFeatures(&request)); |
| 472 features.clear(); | 472 features.clear(); |
| 473 GetFeatureMap(request, &features); | 473 GetFeatureMap(request, &features); |
| 474 | 474 |
| 475 EXPECT_EQ(1.0, | 475 EXPECT_EQ(1.0, |
| 476 features[base::StringPrintf("%s=%s", | 476 features[base::StringPrintf("%s=%s", |
| 477 features::kReferrer, | 477 features::kReferrer, |
| 478 "http://www.foo.com/page.html")]); | 478 "http://www.foo.com/page.html")]); |
| 479 EXPECT_EQ(1.0, | 479 EXPECT_EQ(1.0, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 495 features::kIsFirstNavigation))); | 495 features::kIsFirstNavigation))); |
| 496 | 496 |
| 497 request.Clear(); | 497 request.Clear(); |
| 498 request.set_url("http://www.bar.com/other_page.html"); | 498 request.set_url("http://www.bar.com/other_page.html"); |
| 499 request.set_client_score(0.5); | 499 request.set_client_score(0.5); |
| 500 redirect_chain.clear(); | 500 redirect_chain.clear(); |
| 501 redirect_chain.push_back(GURL("http://www.bar.com/other_page.html")); | 501 redirect_chain.push_back(GURL("http://www.bar.com/other_page.html")); |
| 502 SetRedirectChain(redirect_chain, false); | 502 SetRedirectChain(redirect_chain, false); |
| 503 NavigateAndCommit(GURL("http://www.bar.com/other_page.html"), | 503 NavigateAndCommit(GURL("http://www.bar.com/other_page.html"), |
| 504 GURL("http://www.bar.com/"), | 504 GURL("http://www.bar.com/"), |
| 505 content::PAGE_TRANSITION_LINK); | 505 ui::PAGE_TRANSITION_LINK); |
| 506 | 506 |
| 507 EXPECT_TRUE(ExtractFeatures(&request)); | 507 EXPECT_TRUE(ExtractFeatures(&request)); |
| 508 features.clear(); | 508 features.clear(); |
| 509 GetFeatureMap(request, &features); | 509 GetFeatureMap(request, &features); |
| 510 | 510 |
| 511 EXPECT_EQ(1.0, | 511 EXPECT_EQ(1.0, |
| 512 features[base::StringPrintf("%s=%s", | 512 features[base::StringPrintf("%s=%s", |
| 513 features::kReferrer, | 513 features::kReferrer, |
| 514 "http://www.bar.com/")]); | 514 "http://www.bar.com/")]); |
| 515 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); | 515 EXPECT_EQ(0.0, features[features::kHasSSLReferrer]); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 535 features::kIsFirstNavigation)]); | 535 features::kIsFirstNavigation)]); |
| 536 request.Clear(); | 536 request.Clear(); |
| 537 request.set_url("http://www.baz.com/"); | 537 request.set_url("http://www.baz.com/"); |
| 538 request.set_client_score(0.5); | 538 request.set_client_score(0.5); |
| 539 redirect_chain.clear(); | 539 redirect_chain.clear(); |
| 540 redirect_chain.push_back(GURL("https://bankofamerica.com")); | 540 redirect_chain.push_back(GURL("https://bankofamerica.com")); |
| 541 redirect_chain.push_back(GURL("http://www.baz.com/")); | 541 redirect_chain.push_back(GURL("http://www.baz.com/")); |
| 542 SetRedirectChain(redirect_chain, true); | 542 SetRedirectChain(redirect_chain, true); |
| 543 NavigateAndCommit(GURL("http://www.baz.com"), | 543 NavigateAndCommit(GURL("http://www.baz.com"), |
| 544 GURL("https://bankofamerica.com"), | 544 GURL("https://bankofamerica.com"), |
| 545 content::PAGE_TRANSITION_GENERATED); | 545 ui::PAGE_TRANSITION_GENERATED); |
| 546 | 546 |
| 547 EXPECT_TRUE(ExtractFeatures(&request)); | 547 EXPECT_TRUE(ExtractFeatures(&request)); |
| 548 features.clear(); | 548 features.clear(); |
| 549 GetFeatureMap(request, &features); | 549 GetFeatureMap(request, &features); |
| 550 | 550 |
| 551 EXPECT_EQ(1.0, | 551 EXPECT_EQ(1.0, |
| 552 features[base::StringPrintf("%s[0]=%s", | 552 features[base::StringPrintf("%s[0]=%s", |
| 553 features::kRedirect, | 553 features::kRedirect, |
| 554 features::kSecureRedirectValue)]); | 554 features::kSecureRedirectValue)]); |
| 555 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); | 555 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 // First ip is good but all the others are bad. | 650 // First ip is good but all the others are bad. |
| 651 EXPECT_CALL(*db_manager_, MatchMalwareIP(ip)).WillOnce(Return(i > 0)); | 651 EXPECT_CALL(*db_manager_, MatchMalwareIP(ip)).WillOnce(Return(i > 0)); |
| 652 } | 652 } |
| 653 | 653 |
| 654 ExtractMalwareFeatures(&request); | 654 ExtractMalwareFeatures(&request); |
| 655 // The number of IP matched url we store is capped at 5 IPs per request. | 655 // The number of IP matched url we store is capped at 5 IPs per request. |
| 656 EXPECT_EQ(5, request.bad_ip_url_info_size()); | 656 EXPECT_EQ(5, request.bad_ip_url_info_size()); |
| 657 } | 657 } |
| 658 | 658 |
| 659 } // namespace safe_browsing | 659 } // namespace safe_browsing |
| OLD | NEW |