Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: chrome/browser/safe_browsing/client_side_detection_host_unittest.cc

Issue 173133004: Separate pre-classification checks for client-side malware and phishing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address Matt's comments. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "base/files/file_path.h" 5 #include "base/files/file_path.h"
6 #include "base/memory/ref_counted.h" 6 #include "base/memory/ref_counted.h"
7 #include "base/memory/scoped_ptr.h" 7 #include "base/memory/scoped_ptr.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager); 152 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingUIManager);
153 }; 153 };
154 154
155 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager { 155 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
156 public: 156 public:
157 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service) 157 explicit MockSafeBrowsingDatabaseManager(SafeBrowsingService* service)
158 : SafeBrowsingDatabaseManager(service) { } 158 : SafeBrowsingDatabaseManager(service) { }
159 159
160 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&)); 160 MOCK_METHOD1(MatchCsdWhitelistUrl, bool(const GURL&));
161 MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address)); 161 MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address));
162 MOCK_METHOD0(IsMalwareKillSwitchOn, bool());
162 163
163 protected: 164 protected:
164 virtual ~MockSafeBrowsingDatabaseManager() {} 165 virtual ~MockSafeBrowsingDatabaseManager() {}
165 166
166 private: 167 private:
167 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager); 168 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
168 }; 169 };
169 170
170 class MockTestingProfile : public TestingProfile { 171 class MockTestingProfile : public TestingProfile {
171 public: 172 public:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 new StrictMock<MockSafeBrowsingDatabaseManager>(sb_service); 213 new StrictMock<MockSafeBrowsingDatabaseManager>(sb_service);
213 ui_manager_ = new StrictMock<MockSafeBrowsingUIManager>(sb_service); 214 ui_manager_ = new StrictMock<MockSafeBrowsingUIManager>(sb_service);
214 csd_host_.reset(safe_browsing::ClientSideDetectionHost::Create( 215 csd_host_.reset(safe_browsing::ClientSideDetectionHost::Create(
215 web_contents())); 216 web_contents()));
216 csd_host_->set_client_side_detection_service(csd_service_.get()); 217 csd_host_->set_client_side_detection_service(csd_service_.get());
217 csd_host_->set_safe_browsing_managers(ui_manager_.get(), 218 csd_host_->set_safe_browsing_managers(ui_manager_.get(),
218 database_manager_.get()); 219 database_manager_.get());
219 // We need to create this here since we don't call 220 // We need to create this here since we don't call
220 // DidNavigateMainFramePostCommit in this test. 221 // DidNavigateMainFramePostCommit in this test.
221 csd_host_->browse_info_.reset(new BrowseInfo); 222 csd_host_->browse_info_.reset(new BrowseInfo);
222
223 // By default this is set to false. Turn it on as if we are in canary or
224 // dev channel
225 csd_host_->malware_report_enabled_ = true;
226 } 223 }
227 224
228 virtual void TearDown() { 225 virtual void TearDown() {
229 // Delete the host object on the UI thread and release the 226 // Delete the host object on the UI thread and release the
230 // SafeBrowsingService. 227 // SafeBrowsingService.
231 BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, 228 BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE,
232 csd_host_.release()); 229 csd_host_.release());
233 database_manager_ = NULL; 230 database_manager_ = NULL;
234 ui_manager_ = NULL; 231 ui_manager_ = NULL;
235 base::RunLoop().RunUntilIdle(); 232 base::RunLoop().RunUntilIdle();
236 ChromeRenderViewHostTestHarness::TearDown(); 233 ChromeRenderViewHostTestHarness::TearDown();
237 } 234 }
238 235
239 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE { 236 virtual content::BrowserContext* CreateBrowserContext() OVERRIDE {
240 // Set custom profile object so that we can mock calls to IsOffTheRecord. 237 // Set custom profile object so that we can mock calls to IsOffTheRecord.
241 // This needs to happen before we call the parent SetUp() function. We use 238 // This needs to happen before we call the parent SetUp() function. We use
242 // a nice mock because other parts of the code are calling IsOffTheRecord. 239 // a nice mock because other parts of the code are calling IsOffTheRecord.
243 mock_profile_ = new NiceMock<MockTestingProfile>(); 240 mock_profile_ = new NiceMock<MockTestingProfile>();
244 return mock_profile_; 241 return mock_profile_;
245 } 242 }
246 243
247 void OnPhishingDetectionDone(const std::string& verdict_str) { 244 void OnPhishingDetectionDone(const std::string& verdict_str) {
248 csd_host_->OnPhishingDetectionDone(verdict_str); 245 csd_host_->OnPhishingDetectionDone(verdict_str);
249 } 246 }
250 247
248 void DocumentOnLoadCompletedInMainFrame(int32 page_id) {
249 csd_host_->DocumentOnLoadCompletedInMainFrame(page_id);
250 }
251
251 void UpdateIPUrlMap(const std::string& ip, const std::string& host) { 252 void UpdateIPUrlMap(const std::string& ip, const std::string& host) {
252 csd_host_->UpdateIPUrlMap(ip, host, "", "", ResourceType::OBJECT); 253 csd_host_->UpdateIPUrlMap(ip, host, "", "", ResourceType::OBJECT);
253 } 254 }
254 255
255 BrowseInfo* GetBrowseInfo() { 256 BrowseInfo* GetBrowseInfo() {
256 return csd_host_->browse_info_.get(); 257 return csd_host_->browse_info_.get();
257 } 258 }
258 259
259 void ExpectPreClassificationChecks(const GURL& url, 260 void ExpectPreClassificationChecks(const GURL& url,
260 const bool* is_private, 261 const bool* is_private,
261 const bool* is_incognito, 262 const bool* is_incognito,
262 const bool* match_csd_whitelist, 263 const bool* match_csd_whitelist,
264 const bool* malware_killswitch,
263 const bool* get_valid_cached_result, 265 const bool* get_valid_cached_result,
264 const bool* is_in_cache, 266 const bool* is_in_cache,
265 const bool* over_report_limit) { 267 const bool* over_report_limit) {
266 if (is_private) { 268 if (is_private) {
267 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_)) 269 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_))
268 .WillOnce(Return(*is_private)); 270 .WillOnce(Return(*is_private));
269 } 271 }
270 if (is_incognito) { 272 if (is_incognito) {
271 EXPECT_CALL(*mock_profile_, IsOffTheRecord()) 273 EXPECT_CALL(*mock_profile_, IsOffTheRecord())
272 .WillRepeatedly(Return(*is_incognito)); 274 .WillRepeatedly(Return(*is_incognito));
273 } 275 }
274 if (match_csd_whitelist) { 276 if (match_csd_whitelist) {
275 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(url)) 277 EXPECT_CALL(*database_manager_.get(), MatchCsdWhitelistUrl(url))
276 .WillOnce(Return(*match_csd_whitelist)); 278 .WillOnce(Return(*match_csd_whitelist));
277 } 279 }
280 if (malware_killswitch) {
281 EXPECT_CALL(*database_manager_.get(), IsMalwareKillSwitchOn())
282 .WillRepeatedly(Return(*malware_killswitch));
283 }
278 if (get_valid_cached_result) { 284 if (get_valid_cached_result) {
279 EXPECT_CALL(*csd_service_, GetValidCachedResult(url, NotNull())) 285 EXPECT_CALL(*csd_service_, GetValidCachedResult(url, NotNull()))
280 .WillOnce(DoAll(SetArgumentPointee<1>(true), 286 .WillOnce(DoAll(SetArgumentPointee<1>(true),
281 Return(*get_valid_cached_result))); 287 Return(*get_valid_cached_result)));
282 } 288 }
283 if (is_in_cache) { 289 if (is_in_cache) {
284 EXPECT_CALL(*csd_service_, IsInCache(url)).WillOnce(Return(*is_in_cache)); 290 EXPECT_CALL(*csd_service_, IsInCache(url)).WillOnce(Return(*is_in_cache));
285 } 291 }
286 if (over_report_limit) { 292 if (over_report_limit) {
287 EXPECT_CALL(*csd_service_, OverPhishingReportLimit()) 293 EXPECT_CALL(*csd_service_, OverPhishingReportLimit())
(...skipping 15 matching lines...) Expand all
303 } 309 }
304 310
305 void SetRedirectChain(const std::vector<GURL>& redirect_chain) { 311 void SetRedirectChain(const std::vector<GURL>& redirect_chain) {
306 csd_host_->browse_info_->url_redirects = redirect_chain; 312 csd_host_->browse_info_->url_redirects = redirect_chain;
307 } 313 }
308 314
309 void SetReferrer(const GURL& referrer) { 315 void SetReferrer(const GURL& referrer) {
310 csd_host_->browse_info_->referrer = referrer; 316 csd_host_->browse_info_->referrer = referrer;
311 } 317 }
312 318
319 void ExpectShouldClassifyForMalwareResult(bool should_classify) {
320 EXPECT_EQ(should_classify, csd_host_->should_classify_for_malware_);
321 }
322
323 void ExpectStartPhishingDetection(const GURL* url) {
324 const IPC::Message* msg = process()->sink().GetFirstMessageMatching(
325 SafeBrowsingMsg_StartPhishingDetection::ID);
326 if (url) {
327 ASSERT_TRUE(msg);
328 Tuple1<GURL> actual_url;
329 SafeBrowsingMsg_StartPhishingDetection::Read(msg, &actual_url);
330 EXPECT_EQ(*url, actual_url.a);
331 EXPECT_EQ(rvh()->GetRoutingID(), msg->routing_id());
332 process()->sink().ClearMessages();
333 } else {
334 ASSERT_FALSE(msg);
335 }
336 }
337
313 void TestUnsafeResourceCopied(const UnsafeResource& resource) { 338 void TestUnsafeResourceCopied(const UnsafeResource& resource) {
314 ASSERT_TRUE(csd_host_->unsafe_resource_.get()); 339 ASSERT_TRUE(csd_host_->unsafe_resource_.get());
315 // Test that the resource from OnSafeBrowsingHit notification was copied 340 // Test that the resource from OnSafeBrowsingHit notification was copied
316 // into the CSDH. 341 // into the CSDH.
317 EXPECT_EQ(resource.url, csd_host_->unsafe_resource_->url); 342 EXPECT_EQ(resource.url, csd_host_->unsafe_resource_->url);
318 EXPECT_EQ(resource.original_url, csd_host_->unsafe_resource_->original_url); 343 EXPECT_EQ(resource.original_url, csd_host_->unsafe_resource_->original_url);
319 EXPECT_EQ(resource.is_subresource, 344 EXPECT_EQ(resource.is_subresource,
320 csd_host_->unsafe_resource_->is_subresource); 345 csd_host_->unsafe_resource_->is_subresource);
321 EXPECT_EQ(resource.threat_type, csd_host_->unsafe_resource_->threat_type); 346 EXPECT_EQ(resource.threat_type, csd_host_->unsafe_resource_->threat_type);
322 EXPECT_TRUE(csd_host_->unsafe_resource_->callback.is_null()); 347 EXPECT_TRUE(csd_host_->unsafe_resource_->callback.is_null());
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 web_contents(), 468 web_contents(),
444 csd_host_.get()); 469 csd_host_.get());
445 SetFeatureExtractor(mock_extractor); // The host class takes ownership. 470 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
446 471
447 ClientSideDetectionService::ClientReportPhishingRequestCallback cb; 472 ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
448 ClientPhishingRequest verdict; 473 ClientPhishingRequest verdict;
449 verdict.set_url("http://phishingurl.com/"); 474 verdict.set_url("http://phishingurl.com/");
450 verdict.set_client_score(1.0f); 475 verdict.set_client_score(1.0f);
451 verdict.set_is_phishing(true); 476 verdict.set_is_phishing(true);
452 477
453 ClientMalwareRequest malware_verdict;
454 malware_verdict.set_url(verdict.url());
455 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) 478 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _))
456 .WillOnce(DoAll(DeleteArg<1>(), 479 .WillOnce(DoAll(DeleteArg<1>(),
457 InvokeCallbackArgument<2>(true, &verdict))); 480 InvokeCallbackArgument<2>(true, &verdict)));
458 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
459 .WillOnce(InvokeMalwareCallback(&malware_verdict));
460 EXPECT_CALL(*csd_service_, 481 EXPECT_CALL(*csd_service_,
461 SendClientReportPhishingRequest( 482 SendClientReportPhishingRequest(
462 Pointee(PartiallyEqualVerdict(verdict)), _)) 483 Pointee(PartiallyEqualVerdict(verdict)), _))
463 .WillOnce(SaveArg<1>(&cb)); 484 .WillOnce(SaveArg<1>(&cb));
464 OnPhishingDetectionDone(verdict.SerializeAsString()); 485 OnPhishingDetectionDone(verdict.SerializeAsString());
465 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 486 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
466 ASSERT_FALSE(cb.is_null()); 487 ASSERT_FALSE(cb.is_null());
467 488
468 // Make sure DisplayBlockingPage is not going to be called. 489 // Make sure DisplayBlockingPage is not going to be called.
469 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_)).Times(0); 490 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_)).Times(0);
(...skipping 17 matching lines...) Expand all
487 verdict.set_client_score(1.0f); 508 verdict.set_client_score(1.0f);
488 verdict.set_is_phishing(true); 509 verdict.set_is_phishing(true);
489 510
490 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) 511 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _))
491 .WillOnce(DoAll(DeleteArg<1>(), 512 .WillOnce(DoAll(DeleteArg<1>(),
492 InvokeCallbackArgument<2>(true, &verdict))); 513 InvokeCallbackArgument<2>(true, &verdict)));
493 EXPECT_CALL(*csd_service_, 514 EXPECT_CALL(*csd_service_,
494 SendClientReportPhishingRequest( 515 SendClientReportPhishingRequest(
495 Pointee(PartiallyEqualVerdict(verdict)), _)) 516 Pointee(PartiallyEqualVerdict(verdict)), _))
496 .WillOnce(SaveArg<1>(&cb)); 517 .WillOnce(SaveArg<1>(&cb));
497
498 ClientMalwareRequest malware_verdict;
499 malware_verdict.set_url(verdict.url());
500 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
501 .WillOnce(InvokeMalwareCallback(&malware_verdict));
502 EXPECT_CALL(*csd_service_,
503 SendClientReportMalwareRequest(_, _)).Times(0);
504
505 OnPhishingDetectionDone(verdict.SerializeAsString()); 518 OnPhishingDetectionDone(verdict.SerializeAsString());
506 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 519 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
507 ASSERT_FALSE(cb.is_null()); 520 ASSERT_FALSE(cb.is_null());
508 521
509 // Make sure DisplayBlockingPage is not going to be called. 522 // Make sure DisplayBlockingPage is not going to be called.
510 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_)).Times(0); 523 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_)).Times(0);
511 cb.Run(GURL(verdict.url()), false); 524 cb.Run(GURL(verdict.url()), false);
512 base::RunLoop().RunUntilIdle(); 525 base::RunLoop().RunUntilIdle();
513 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get())); 526 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get()));
514 } 527 }
515 528
516 TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneShowInterstitial) { 529 TEST_F(ClientSideDetectionHostTest, OnPhishingDetectionDoneShowInterstitial) {
517 // Case 3: client thinks the page is phishing and so does the server. 530 // Case 3: client thinks the page is phishing and so does the server.
518 // We show an interstitial. 531 // We show an interstitial.
519 MockBrowserFeatureExtractor* mock_extractor = 532 MockBrowserFeatureExtractor* mock_extractor =
520 new StrictMock<MockBrowserFeatureExtractor>( 533 new StrictMock<MockBrowserFeatureExtractor>(
521 web_contents(), 534 web_contents(),
522 csd_host_.get()); 535 csd_host_.get());
523 SetFeatureExtractor(mock_extractor); // The host class takes ownership. 536 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
524 537
525 ClientSideDetectionService::ClientReportPhishingRequestCallback cb; 538 ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
526 GURL phishing_url("http://phishingurl.com/"); 539 GURL phishing_url("http://phishingurl.com/");
527 ClientPhishingRequest verdict; 540 ClientPhishingRequest verdict;
528 verdict.set_url(phishing_url.spec()); 541 verdict.set_url(phishing_url.spec());
529 verdict.set_client_score(1.0f); 542 verdict.set_client_score(1.0f);
530 verdict.set_is_phishing(true); 543 verdict.set_is_phishing(true);
531 544
532 ClientMalwareRequest malware_verdict;
533 malware_verdict.set_url(verdict.url());
534
535 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) 545 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _))
536 .WillOnce(DoAll(DeleteArg<1>(), 546 .WillOnce(DoAll(DeleteArg<1>(),
537 InvokeCallbackArgument<2>(true, &verdict))); 547 InvokeCallbackArgument<2>(true, &verdict)));
538 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
539 .WillOnce(InvokeMalwareCallback(&malware_verdict));
540 EXPECT_CALL(*csd_service_, 548 EXPECT_CALL(*csd_service_,
541 SendClientReportPhishingRequest( 549 SendClientReportPhishingRequest(
542 Pointee(PartiallyEqualVerdict(verdict)), _)) 550 Pointee(PartiallyEqualVerdict(verdict)), _))
543 .WillOnce(SaveArg<1>(&cb)); 551 .WillOnce(SaveArg<1>(&cb));
544 OnPhishingDetectionDone(verdict.SerializeAsString()); 552 OnPhishingDetectionDone(verdict.SerializeAsString());
545 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 553 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
546 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); 554 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
547 ASSERT_FALSE(cb.is_null()); 555 ASSERT_FALSE(cb.is_null());
548 556
549 UnsafeResource resource; 557 UnsafeResource resource;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 csd_host_.get()); 590 csd_host_.get());
583 SetFeatureExtractor(mock_extractor); // The host class takes ownership. 591 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
584 592
585 ClientSideDetectionService::ClientReportPhishingRequestCallback cb; 593 ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
586 GURL phishing_url("http://phishingurl.com/"); 594 GURL phishing_url("http://phishingurl.com/");
587 ClientPhishingRequest verdict; 595 ClientPhishingRequest verdict;
588 verdict.set_url(phishing_url.spec()); 596 verdict.set_url(phishing_url.spec());
589 verdict.set_client_score(1.0f); 597 verdict.set_client_score(1.0f);
590 verdict.set_is_phishing(true); 598 verdict.set_is_phishing(true);
591 599
592 ClientMalwareRequest malware_verdict;
593 malware_verdict.set_url(verdict.url());
594
595 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)) 600 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _))
596 .WillOnce(DoAll(DeleteArg<1>(), 601 .WillOnce(DoAll(DeleteArg<1>(),
597 InvokeCallbackArgument<2>(true, &verdict))); 602 InvokeCallbackArgument<2>(true, &verdict)));
598 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
599 .WillOnce(InvokeMalwareCallback(&malware_verdict));
600 EXPECT_CALL(*csd_service_, 603 EXPECT_CALL(*csd_service_,
601 SendClientReportPhishingRequest( 604 SendClientReportPhishingRequest(
602 Pointee(PartiallyEqualVerdict(verdict)), _)) 605 Pointee(PartiallyEqualVerdict(verdict)), _))
603 .WillOnce(SaveArg<1>(&cb)); 606 .WillOnce(SaveArg<1>(&cb));
604 OnPhishingDetectionDone(verdict.SerializeAsString()); 607 OnPhishingDetectionDone(verdict.SerializeAsString());
605 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 608 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
606 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get())); 609 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
607 ASSERT_FALSE(cb.is_null()); 610 ASSERT_FALSE(cb.is_null());
608 611
609 // Set this back to a normal browser feature extractor since we're using 612 // Set this back to a normal browser feature extractor since we're using
610 // NavigateAndCommit() and it's easier to use the real thing than setting up 613 // NavigateAndCommit() and it's easier to use the real thing than setting up
611 // mock expectations. 614 // mock expectations.
612 SetFeatureExtractor(new BrowserFeatureExtractor(web_contents(), 615 SetFeatureExtractor(new BrowserFeatureExtractor(web_contents(),
613 csd_host_.get())); 616 csd_host_.get()));
614 GURL other_phishing_url("http://other_phishing_url.com/bla"); 617 GURL other_phishing_url("http://other_phishing_url.com/bla");
615 ExpectPreClassificationChecks(other_phishing_url, &kFalse, &kFalse, &kFalse, 618 ExpectPreClassificationChecks(other_phishing_url, &kFalse, &kFalse, &kFalse,
616 &kFalse, &kFalse, &kFalse); 619 &kFalse, &kFalse, &kFalse, &kFalse);
617 // We navigate away. The callback cb should be revoked. 620 // We navigate away. The callback cb should be revoked.
618 NavigateAndCommit(other_phishing_url); 621 NavigateAndCommit(other_phishing_url);
619 // Wait for the pre-classification checks to finish for other_phishing_url. 622 // Wait for the pre-classification checks to finish for other_phishing_url.
620 WaitAndCheckPreClassificationChecks(); 623 WaitAndCheckPreClassificationChecks();
621 624
622 ClientSideDetectionService::ClientReportPhishingRequestCallback cb_other; 625 ClientSideDetectionService::ClientReportPhishingRequestCallback cb_other;
623 verdict.set_url(other_phishing_url.spec()); 626 verdict.set_url(other_phishing_url.spec());
624 verdict.set_client_score(0.8f); 627 verdict.set_client_score(0.8f);
625 EXPECT_CALL(*csd_service_, 628 EXPECT_CALL(*csd_service_,
626 SendClientReportPhishingRequest( 629 SendClientReportPhishingRequest(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 new StrictMock<MockBrowserFeatureExtractor>( 675 new StrictMock<MockBrowserFeatureExtractor>(
673 web_contents(), 676 web_contents(),
674 csd_host_.get()); 677 csd_host_.get());
675 SetFeatureExtractor(mock_extractor); // The host class takes ownership. 678 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
676 679
677 ClientPhishingRequest verdict; 680 ClientPhishingRequest verdict;
678 verdict.set_url("http://not-phishing.com/"); 681 verdict.set_url("http://not-phishing.com/");
679 verdict.set_client_score(0.1f); 682 verdict.set_client_score(0.1f);
680 verdict.set_is_phishing(false); 683 verdict.set_is_phishing(false);
681 684
682 ClientMalwareRequest malware_verdict;
683 malware_verdict.set_url(verdict.url());
684
685 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0); 685 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0);
686 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
687 .WillOnce(InvokeMalwareCallback(&malware_verdict));
688 OnPhishingDetectionDone(verdict.SerializeAsString()); 686 OnPhishingDetectionDone(verdict.SerializeAsString());
689 EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor)); 687 EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor));
690 } 688 }
691 689
692 TEST_F(ClientSideDetectionHostTest, 690 TEST_F(ClientSideDetectionHostTest,
693 OnPhishingDetectionDoneVerdictNotPhishingButSBMatchSubResource) { 691 OnPhishingDetectionDoneVerdictNotPhishingButSBMatchSubResource) {
694 // Case 7: renderer sends a verdict string that isn't phishing but the URL 692 // Case 7: renderer sends a verdict string that isn't phishing but the URL
695 // of a subresource was on the regular phishing or malware lists. 693 // of a subresource was on the regular phishing or malware lists.
696 GURL url("http://not-phishing.com/"); 694 GURL url("http://not-phishing.com/");
697 ClientPhishingRequest verdict; 695 ClientPhishingRequest verdict;
698 verdict.set_url(url.spec()); 696 verdict.set_url(url.spec());
699 verdict.set_client_score(0.1f); 697 verdict.set_client_score(0.1f);
700 verdict.set_is_phishing(false); 698 verdict.set_is_phishing(false);
701 699
702 // First we have to navigate to the URL to set the unique page ID. 700 // First we have to navigate to the URL to set the unique page ID.
703 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, 701 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
704 &kFalse, &kFalse); 702 &kFalse, &kFalse, &kFalse);
705 NavigateAndCommit(url); 703 NavigateAndCommit(url);
706 WaitAndCheckPreClassificationChecks(); 704 WaitAndCheckPreClassificationChecks();
707 SetUnsafeSubResourceForCurrent(); 705 SetUnsafeSubResourceForCurrent();
708 706
709 EXPECT_CALL(*csd_service_, 707 EXPECT_CALL(*csd_service_,
710 SendClientReportPhishingRequest( 708 SendClientReportPhishingRequest(
711 Pointee(PartiallyEqualVerdict(verdict)), CallbackIsNull())) 709 Pointee(PartiallyEqualVerdict(verdict)), CallbackIsNull()))
712 .WillOnce(DoAll(DeleteArg<0>(), QuitUIMessageLoop())); 710 .WillOnce(DoAll(DeleteArg<0>(), QuitUIMessageLoop()));
713 std::vector<GURL> redirect_chain; 711 std::vector<GURL> redirect_chain;
714 redirect_chain.push_back(url); 712 redirect_chain.push_back(url);
715 SetRedirectChain(redirect_chain); 713 SetRedirectChain(redirect_chain);
716 OnPhishingDetectionDone(verdict.SerializeAsString()); 714 OnPhishingDetectionDone(verdict.SerializeAsString());
717 base::MessageLoop::current()->Run(); 715 base::MessageLoop::current()->Run();
718 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 716 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
719 } 717 }
720 718
721 TEST_F(ClientSideDetectionHostTest, 719 TEST_F(ClientSideDetectionHostTest,
722 OnPhishingDetectionDoneVerdictNotPhishingButSBMatchOnNewRVH) { 720 OnPhishingDetectionDoneVerdictNotPhishingButSBMatchOnNewRVH) {
723 // When navigating to a different host (thus creating a pending RVH) which 721 // When navigating to a different host (thus creating a pending RVH) which
724 // matches regular malware list, and after navigation the renderer sends a 722 // matches regular malware list, and after navigation the renderer sends a
725 // verdict string that isn't phishing, we should still send the report. 723 // verdict string that isn't phishing, we should still send the report.
726 724
727 // Do an initial navigation to a safe host. 725 // Do an initial navigation to a safe host.
728 GURL start_url("http://safe.example.com/"); 726 GURL start_url("http://safe.example.com/");
729 ExpectPreClassificationChecks( 727 ExpectPreClassificationChecks(
730 start_url, &kFalse, &kFalse, &kFalse, &kFalse, &kFalse, &kFalse); 728 start_url, &kFalse, &kFalse, &kFalse, &kFalse, &kFalse, &kFalse, &kFalse);
731 NavigateAndCommit(start_url); 729 NavigateAndCommit(start_url);
732 WaitAndCheckPreClassificationChecks(); 730 WaitAndCheckPreClassificationChecks();
733 731
734 // Now navigate to a different host which will have a malware hit before the 732 // Now navigate to a different host which will have a malware hit before the
735 // navigation commits. 733 // navigation commits.
736 GURL url("http://malware-but-not-phishing.com/"); 734 GURL url("http://malware-but-not-phishing.com/");
737 ClientPhishingRequest verdict; 735 ClientPhishingRequest verdict;
738 verdict.set_url(url.spec()); 736 verdict.set_url(url.spec());
739 verdict.set_client_score(0.1f); 737 verdict.set_client_score(0.1f);
740 verdict.set_is_phishing(false); 738 verdict.set_is_phishing(false);
741 739
742 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, 740 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
743 &kFalse, &kFalse); 741 &kFalse, &kFalse, &kFalse);
744 NavigateWithSBHitAndCommit(url); 742 NavigateWithSBHitAndCommit(url);
745 WaitAndCheckPreClassificationChecks(); 743 WaitAndCheckPreClassificationChecks();
746 744
747 EXPECT_CALL(*csd_service_, 745 EXPECT_CALL(*csd_service_,
748 SendClientReportPhishingRequest( 746 SendClientReportPhishingRequest(
749 Pointee(PartiallyEqualVerdict(verdict)), CallbackIsNull())) 747 Pointee(PartiallyEqualVerdict(verdict)), CallbackIsNull()))
750 .WillOnce(DoAll(DeleteArg<0>(), QuitUIMessageLoop())); 748 .WillOnce(DoAll(DeleteArg<0>(), QuitUIMessageLoop()));
751 std::vector<GURL> redirect_chain; 749 std::vector<GURL> redirect_chain;
752 redirect_chain.push_back(url); 750 redirect_chain.push_back(url);
753 SetRedirectChain(redirect_chain); 751 SetRedirectChain(redirect_chain);
754 OnPhishingDetectionDone(verdict.SerializeAsString()); 752 OnPhishingDetectionDone(verdict.SerializeAsString());
755 base::MessageLoop::current()->Run(); 753 base::MessageLoop::current()->Run();
756 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 754 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
757 755
758 ExpectPreClassificationChecks(start_url, &kFalse, &kFalse, &kFalse, &kFalse, 756 ExpectPreClassificationChecks(start_url, &kFalse, &kFalse, &kFalse, &kFalse,
759 &kFalse, &kFalse); 757 &kFalse, &kFalse, &kFalse);
760 NavigateWithoutSBHitAndCommit(start_url); 758 NavigateWithoutSBHitAndCommit(start_url);
761 WaitAndCheckPreClassificationChecks(); 759 WaitAndCheckPreClassificationChecks();
762 } 760 }
763 761
762 TEST_F(ClientSideDetectionHostTest,
763 DocumentOnLoadCompletedInMainFrameShowMalwareInterstitial) {
764 // Case 9: client thinks the page match malware IP and so does the server.
765 // We show an sub-resource malware interstitial.
766 MockBrowserFeatureExtractor* mock_extractor =
767 new StrictMock<MockBrowserFeatureExtractor>(
768 web_contents(),
769 csd_host_.get());
770 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
771
772 GURL malware_landing_url("http://malware.com/");
773 GURL malware_ip_url("http://badip.com");
774 ClientMalwareRequest malware_verdict;
775 malware_verdict.set_url("http://malware.com/");
776 ClientMalwareRequest::UrlInfo* badipurl =
777 malware_verdict.add_bad_ip_url_info();
778 badipurl->set_ip("1.2.3.4");
779 badipurl->set_url("http://badip.com");
780
781 ExpectPreClassificationChecks(GURL(malware_verdict.url()), &kFalse, &kFalse,
782 &kFalse, &kFalse, &kFalse, &kFalse, &kFalse);
783 NavigateAndCommit(GURL(malware_verdict.url()));
784 WaitAndCheckPreClassificationChecks();
785
786 ClientSideDetectionService::ClientReportMalwareRequestCallback cb;
787 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
788 .WillOnce(InvokeMalwareCallback(&malware_verdict));
789 EXPECT_CALL(*csd_service_,
790 SendClientReportMalwareRequest(
791 Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _))
792 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb)));
793 DocumentOnLoadCompletedInMainFrame(GetBrowseInfo()->page_id);
794 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
795 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
796 ASSERT_FALSE(cb.is_null());
797
798 UnsafeResource resource;
799 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_))
800 .WillOnce(SaveArg<0>(&resource));
801 cb.Run(malware_landing_url, malware_ip_url, true);
802
803 base::RunLoop().RunUntilIdle();
804 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get()));
805 EXPECT_EQ(malware_ip_url, resource.url);
806 EXPECT_EQ(malware_landing_url, resource.original_url);
807 EXPECT_TRUE(resource.is_subresource);
808 EXPECT_EQ(SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL, resource.threat_type);
809 EXPECT_EQ(web_contents()->GetRenderProcessHost()->GetID(),
810 resource.render_process_host_id);
811 EXPECT_EQ(web_contents()->GetRenderViewHost()->GetRoutingID(),
812 resource.render_view_id);
813
814 // Make sure the client object will be deleted.
815 BrowserThread::PostTask(
816 BrowserThread::IO,
817 FROM_HERE,
818 base::Bind(&MockSafeBrowsingUIManager::InvokeOnBlockingPageComplete,
819 ui_manager_, resource.callback));
820 }
821
764 TEST_F(ClientSideDetectionHostTest, UpdateIPUrlMap) { 822 TEST_F(ClientSideDetectionHostTest, UpdateIPUrlMap) {
765 BrowseInfo* browse_info = GetBrowseInfo(); 823 BrowseInfo* browse_info = GetBrowseInfo();
766 824
767 // Empty IP or host are skipped 825 // Empty IP or host are skipped
768 UpdateIPUrlMap("250.10.10.10", std::string()); 826 UpdateIPUrlMap("250.10.10.10", std::string());
769 ASSERT_EQ(0U, browse_info->ips.size()); 827 ASSERT_EQ(0U, browse_info->ips.size());
770 UpdateIPUrlMap(std::string(), "http://google.com/a"); 828 UpdateIPUrlMap(std::string(), "http://google.com/a");
771 ASSERT_EQ(0U, browse_info->ips.size()); 829 ASSERT_EQ(0U, browse_info->ips.size());
772 UpdateIPUrlMap(std::string(), std::string()); 830 UpdateIPUrlMap(std::string(), std::string());
773 ASSERT_EQ(0U, browse_info->ips.size()); 831 ASSERT_EQ(0U, browse_info->ips.size());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 // Add url to existing IPs succeed 870 // Add url to existing IPs succeed
813 UpdateIPUrlMap("100.100.100.256", "more.com/"); 871 UpdateIPUrlMap("100.100.100.256", "more.com/");
814 ASSERT_EQ(2U, browse_info->ips["100.100.100.256"].size()); 872 ASSERT_EQ(2U, browse_info->ips["100.100.100.256"].size());
815 expected_urls.clear(); 873 expected_urls.clear();
816 expected_urls.push_back(IPUrlInfo("test.com/", "", "", ResourceType::OBJECT)); 874 expected_urls.push_back(IPUrlInfo("test.com/", "", "", ResourceType::OBJECT));
817 expected_urls.push_back(IPUrlInfo("more.com/", "", "", ResourceType::OBJECT)); 875 expected_urls.push_back(IPUrlInfo("more.com/", "", "", ResourceType::OBJECT));
818 CheckIPUrlEqual(expected_urls, 876 CheckIPUrlEqual(expected_urls,
819 browse_info->ips["100.100.100.256"]); 877 browse_info->ips["100.100.100.256"]);
820 } 878 }
821 879
822 TEST_F(ClientSideDetectionHostTest,
823 OnPhishingDetectionDoneVerdictNotPhishingNotMalwareIP) {
824 // Case 7: renderer sends a verdict string that isn't phishing and not matches
825 // malware bad IP list
826 MockBrowserFeatureExtractor* mock_extractor =
827 new StrictMock<MockBrowserFeatureExtractor>(
828 web_contents(),
829 csd_host_.get());
830 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
831
832 ClientPhishingRequest verdict;
833 verdict.set_url("http://not-phishing.com/");
834 verdict.set_client_score(0.1f);
835 verdict.set_is_phishing(false);
836
837 ClientMalwareRequest malware_verdict;
838 malware_verdict.set_url(verdict.url());
839
840 // That is a special case. If there were no IP matches or if feature
841 // extraction failed the callback will delete the malware_verdict.
842 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
843 .WillOnce(InvokeMalwareCallback(&malware_verdict));
844 EXPECT_CALL(*csd_service_,
845 SendClientReportMalwareRequest(_, _)).Times(0);
846 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0);
847
848 OnPhishingDetectionDone(verdict.SerializeAsString());
849 EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor));
850 }
851
852 TEST_F(ClientSideDetectionHostTest,
853 OnPhishingDetectionDoneVerdictNotPhishingButMalwareIP) {
854 // Case 8: renderer sends a verdict string that isn't phishing but matches
855 // malware bad IP list
856 MockBrowserFeatureExtractor* mock_extractor =
857 new StrictMock<MockBrowserFeatureExtractor>(
858 web_contents(),
859 csd_host_.get());
860 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
861
862 ClientPhishingRequest verdict;
863 verdict.set_url("http://not-phishing.com/");
864 verdict.set_client_score(0.1f);
865 verdict.set_is_phishing(false);
866
867 ClientMalwareRequest malware_verdict;
868 malware_verdict.set_url(verdict.url());
869 malware_verdict.set_referrer_url("http://referrer.com/");
870 ClientMalwareRequest::UrlInfo* badipurl =
871 malware_verdict.add_bad_ip_url_info();
872 badipurl->set_ip("1.2.3.4");
873 badipurl->set_url("badip.com");
874
875 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
876 .WillOnce(InvokeMalwareCallback(&malware_verdict));
877 EXPECT_CALL(*csd_service_,
878 SendClientReportMalwareRequest(
879 Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _))
880 .WillOnce(DeleteArg<0>());
881 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _)).Times(0);
882
883 SetReferrer(GURL("http://referrer.com/"));
884 OnPhishingDetectionDone(verdict.SerializeAsString());
885 EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor));
886 }
887
888 TEST_F(ClientSideDetectionHostTest,
889 OnPhishingDetectionDoneVerdictPhishingAndMalwareIP) {
890 // Case 9: renderer sends a verdict string that is phishing and matches
891 // malware bad IP list
892 MockBrowserFeatureExtractor* mock_extractor =
893 new StrictMock<MockBrowserFeatureExtractor>(
894 web_contents(),
895 csd_host_.get());
896 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
897
898 ClientSideDetectionService::ClientReportPhishingRequestCallback cb;
899 ClientPhishingRequest verdict;
900 verdict.set_url("http://not-phishing.com/");
901 verdict.set_client_score(0.1f);
902 verdict.set_is_phishing(true);
903
904 ClientMalwareRequest malware_verdict;
905 malware_verdict.set_url(verdict.url());
906 ClientMalwareRequest::UrlInfo* badipurl =
907 malware_verdict.add_bad_ip_url_info();
908 badipurl->set_ip("1.2.3.4");
909 badipurl->set_url("badip.com");
910
911 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
912 .WillOnce(InvokeMalwareCallback(&malware_verdict));
913 EXPECT_CALL(*csd_service_,
914 SendClientReportMalwareRequest(
915 Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _))
916 .WillOnce(DeleteArg<0>());
917
918 EXPECT_CALL(*mock_extractor, ExtractFeatures(_, _, _))
919 .WillOnce(DoAll(DeleteArg<1>(),
920 InvokeCallbackArgument<2>(true, &verdict)));
921
922 EXPECT_CALL(*csd_service_,
923 SendClientReportPhishingRequest(
924 Pointee(PartiallyEqualVerdict(verdict)), _))
925 .WillOnce(SaveArg<1>(&cb));
926
927 // Referrer url using https won't be set and sent out.
928 SetReferrer(GURL("https://referrer.com/"));
929 OnPhishingDetectionDone(verdict.SerializeAsString());
930 EXPECT_TRUE(Mock::VerifyAndClear(mock_extractor));
931 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
932 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
933 ASSERT_FALSE(cb.is_null());
934 }
935
936 TEST_F(ClientSideDetectionHostTest,
937 OnPhishingDetectionDoneShowMalwareInterstitial) {
938 // Case 10: client thinks the page match malware IP and so does the server.
939 // We show an sub-resource malware interstitial.
940 MockBrowserFeatureExtractor* mock_extractor =
941 new StrictMock<MockBrowserFeatureExtractor>(
942 web_contents(),
943 csd_host_.get());
944 SetFeatureExtractor(mock_extractor); // The host class takes ownership.
945
946 ClientPhishingRequest verdict;
947 verdict.set_url("http://not-phishing.com/");
948 verdict.set_client_score(0.1f);
949 verdict.set_is_phishing(false);
950
951 ClientSideDetectionService::ClientReportMalwareRequestCallback cb;
952 GURL malware_landing_url("http://malware.com/");
953 GURL malware_ip_url("http://badip.com");
954 ClientMalwareRequest malware_verdict;
955 malware_verdict.set_url("http://malware.com/");
956 ClientMalwareRequest::UrlInfo* badipurl =
957 malware_verdict.add_bad_ip_url_info();
958 badipurl->set_ip("1.2.3.4");
959 badipurl->set_url("http://badip.com");
960
961 EXPECT_CALL(*mock_extractor, ExtractMalwareFeatures(_, _, _))
962 .WillOnce(InvokeMalwareCallback(&malware_verdict));
963 EXPECT_CALL(*csd_service_,
964 SendClientReportMalwareRequest(
965 Pointee(PartiallyEqualMalwareVerdict(malware_verdict)), _))
966 .WillOnce(DoAll(DeleteArg<0>(), SaveArg<1>(&cb)));
967 OnPhishingDetectionDone(verdict.SerializeAsString());
968 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
969 EXPECT_TRUE(Mock::VerifyAndClear(csd_service_.get()));
970 ASSERT_FALSE(cb.is_null());
971
972 UnsafeResource resource;
973 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_))
974 .WillOnce(SaveArg<0>(&resource));
975 cb.Run(malware_landing_url, malware_ip_url, true);
976
977 base::RunLoop().RunUntilIdle();
978 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get()));
979 EXPECT_EQ(malware_ip_url, resource.url);
980 EXPECT_EQ(malware_landing_url, resource.original_url);
981 EXPECT_TRUE(resource.is_subresource);
982 EXPECT_EQ(SB_THREAT_TYPE_CLIENT_SIDE_MALWARE_URL, resource.threat_type);
983 EXPECT_EQ(web_contents()->GetRenderProcessHost()->GetID(),
984 resource.render_process_host_id);
985 EXPECT_EQ(web_contents()->GetRenderViewHost()->GetRoutingID(),
986 resource.render_view_id);
987
988 // Make sure the client object will be deleted.
989 BrowserThread::PostTask(
990 BrowserThread::IO,
991 FROM_HERE,
992 base::Bind(&MockSafeBrowsingUIManager::InvokeOnBlockingPageComplete,
993 ui_manager_, resource.callback));
994 }
995
996 TEST_F(ClientSideDetectionHostTest, NavigationCancelsShouldClassifyUrl) { 880 TEST_F(ClientSideDetectionHostTest, NavigationCancelsShouldClassifyUrl) {
997 // Test that canceling pending should classify requests works as expected. 881 // Test that canceling pending should classify requests works as expected.
998 882
999 GURL first_url("http://first.phishy.url.com"); 883 GURL first_url("http://first.phishy.url.com");
1000 GURL second_url("http://second.url.com/"); 884 GURL second_url("http://second.url.com/");
1001 // The first few checks are done synchronously so check that they have been 885 // The first few checks are done synchronously so check that they have been
1002 // done for the first URL, while the second URL has all the checks done. We 886 // done for the first URL, while the second URL has all the checks done. We
1003 // need to manually set up the IsPrivateIPAddress mock since if the same mock 887 // need to manually set up the IsPrivateIPAddress mock since if the same mock
1004 // expectation is specified twice, gmock will only use the last instance of 888 // expectation is specified twice, gmock will only use the last instance of
1005 // it, meaning the first will never be matched. 889 // it, meaning the first will never be matched.
1006 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_)) 890 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_))
1007 .WillOnce(Return(false)) 891 .WillOnce(Return(false))
1008 .WillOnce(Return(false)); 892 .WillOnce(Return(false));
1009 ExpectPreClassificationChecks(first_url, NULL, &kFalse, &kFalse, NULL, 893 ExpectPreClassificationChecks(first_url, NULL, &kFalse, &kFalse, &kFalse,
1010 NULL, NULL); 894 NULL, NULL, NULL);
1011 ExpectPreClassificationChecks(second_url, NULL, &kFalse, &kFalse, &kFalse, 895 ExpectPreClassificationChecks(second_url, NULL, &kFalse, &kFalse, &kFalse,
1012 &kFalse, &kFalse); 896 &kFalse, &kFalse, &kFalse);
1013 897
1014 NavigateAndCommit(first_url); 898 NavigateAndCommit(first_url);
1015 // Don't flush the message loop, as we want to navigate to a different 899 // Don't flush the message loop, as we want to navigate to a different
1016 // url before the final pre-classification checks are run. 900 // url before the final pre-classification checks are run.
1017 NavigateAndCommit(second_url); 901 NavigateAndCommit(second_url);
1018 WaitAndCheckPreClassificationChecks(); 902 WaitAndCheckPreClassificationChecks();
1019 } 903 }
1020 904
1021 TEST_F(ClientSideDetectionHostTest, ShouldClassifyUrl) { 905 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckPass) {
1022 // Navigate the tab to a page. We should see a StartPhishingDetection IPC. 906 // Navigate the tab to a page. We should see a StartPhishingDetection IPC.
1023 GURL url("http://host.com/"); 907 GURL url("http://host.com/");
1024 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, 908 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
909 &kFalse, &kFalse, &kFalse);
910 NavigateAndCommit(url);
911 WaitAndCheckPreClassificationChecks();
912
913 ExpectStartPhishingDetection(&url);
914 ExpectShouldClassifyForMalwareResult(true);
915 }
916
917 TEST_F(ClientSideDetectionHostTest,
918 TestPreClassificationCheckInPageNavigation) {
919 GURL url("http://host.com/");
920 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
921 &kFalse, &kFalse, &kFalse);
922 NavigateAndCommit(url);
923 WaitAndCheckPreClassificationChecks();
924
925 ExpectStartPhishingDetection(&url);
926 ExpectShouldClassifyForMalwareResult(true);
927
928 // Now try an in-page navigation. This should not trigger an IPC.
929 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_)).Times(0);
930 GURL inpage("http://host.com/#foo");
931 ExpectPreClassificationChecks(inpage, NULL, NULL, NULL, NULL, NULL, NULL,
932 NULL);
933 NavigateAndCommit(inpage);
934 WaitAndCheckPreClassificationChecks();
935
936 ExpectStartPhishingDetection(NULL);
937 ExpectShouldClassifyForMalwareResult(true);
938 }
939
940 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckXHTML) {
941 // Check that XHTML is supported, in addition to the default HTML type.
942 // Note: for this test to work correctly, the new URL must be on the
943 // same domain as the previous URL, otherwise it will create a new
944 // RenderViewHost that won't have the mime type set.
mattm 2014/03/20 22:51:41 Given the comment, is this test still correct?
noé 2014/03/21 00:08:38 Done.
945 GURL url("http://host.com/xhtml");
946 rvh_tester()->SetContentsMimeType("application/xhtml+xml");
947 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
948 &kFalse, &kFalse, &kFalse);
949 NavigateAndCommit(url);
950 WaitAndCheckPreClassificationChecks();
951
952 ExpectStartPhishingDetection(&url);
953 ExpectShouldClassifyForMalwareResult(true);
954 }
955
956 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckTwoNavigations) {
957 // Navigate to two hosts, which should cause two IPCs.
958 GURL url1("http://host1.com/");
959 ExpectPreClassificationChecks(url1, &kFalse, &kFalse, &kFalse, &kFalse,
960 &kFalse, &kFalse, &kFalse);
961 NavigateAndCommit(url1);
962 WaitAndCheckPreClassificationChecks();
963
964 ExpectStartPhishingDetection(&url1);
965 ExpectShouldClassifyForMalwareResult(true);
966
967 GURL url2("http://host2.com/");
968 ExpectPreClassificationChecks(url2, &kFalse, &kFalse, &kFalse, &kFalse,
969 &kFalse, &kFalse, &kFalse);
970 NavigateAndCommit(url2);
971 WaitAndCheckPreClassificationChecks();
972
973 ExpectStartPhishingDetection(&url2);
974 ExpectShouldClassifyForMalwareResult(true);
975 }
976
977 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckMimeType) {
978 // If the mime type is not one that we support, no IPC should be triggered
979 // but all pre-classification checks should run because we might classify
980 // other mime types for malware.
981 // Note: for this test to work correctly, the new URL must be on the
982 // same domain as the previous URL, otherwise it will create a new
983 // RenderViewHost that won't have the mime type set.
984 GURL url("http://host2.com/image.jpg");
985 rvh_tester()->SetContentsMimeType("image/jpeg");
986 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
987 &kFalse, &kFalse,&kFalse);
988 NavigateAndCommit(url);
989 WaitAndCheckPreClassificationChecks();
990
991 ExpectStartPhishingDetection(NULL);
992 ExpectShouldClassifyForMalwareResult(true);
993 }
994
995 TEST_F(ClientSideDetectionHostTest,
996 TestPreClassificationCheckPrivateIpAddress) {
997 // If IsPrivateIPAddress returns true, no IPC should be triggered.
998 GURL url("http://host3.com/");
999 ExpectPreClassificationChecks(url, &kTrue, &kFalse, NULL, NULL, NULL, NULL,
1000 NULL);
1001 NavigateAndCommit(url);
1002 WaitAndCheckPreClassificationChecks();
1003 const IPC::Message* msg = process()->sink().GetFirstMessageMatching(
1004 SafeBrowsingMsg_StartPhishingDetection::ID);
1005 ASSERT_FALSE(msg);
1006 ExpectShouldClassifyForMalwareResult(false);
1007 }
1008
1009 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckIncognito) {
1010 // If the tab is incognito there should be no IPC. Also, we shouldn't
1011 // even check the csd-whitelist.
1012 GURL url("http://host4.com/");
1013 ExpectPreClassificationChecks(url, &kFalse, &kTrue, NULL, NULL, NULL, NULL,
1014 NULL);
1015 NavigateAndCommit(url);
1016 WaitAndCheckPreClassificationChecks();
1017
1018 ExpectStartPhishingDetection(NULL);
1019 ExpectShouldClassifyForMalwareResult(false);
1020 }
1021
1022 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckCsdWhitelist) {
1023 // If the URL is on the csd whitelist no phishing IPC should be sent
1024 // but we should classify the URL for malware.
1025 GURL url("http://host5.com/");
1026 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kTrue, &kFalse, &kFalse,
1025 &kFalse, &kFalse); 1027 &kFalse, &kFalse);
1026 NavigateAndCommit(url); 1028 NavigateAndCommit(url);
1027 WaitAndCheckPreClassificationChecks(); 1029 WaitAndCheckPreClassificationChecks();
1028 1030
1029 const IPC::Message* msg = process()->sink().GetFirstMessageMatching( 1031 ExpectStartPhishingDetection(NULL);
1030 SafeBrowsingMsg_StartPhishingDetection::ID); 1032 ExpectShouldClassifyForMalwareResult(true);
1031 ASSERT_TRUE(msg); 1033 }
1032 Tuple1<GURL> actual_url;
1033 SafeBrowsingMsg_StartPhishingDetection::Read(msg, &actual_url);
1034 EXPECT_EQ(url, actual_url.a);
1035 EXPECT_EQ(rvh()->GetRoutingID(), msg->routing_id());
1036 process()->sink().ClearMessages();
1037 1034
1038 // Now try an in-page navigation. This should not trigger an IPC. 1035 TEST_F(ClientSideDetectionHostTest,
1039 EXPECT_CALL(*csd_service_, IsPrivateIPAddress(_)).Times(0); 1036 TestPreClassificationCheckMalwareKillSwitch) {
1040 url = GURL("http://host.com/#foo"); 1037 // If the malware killswitch is on we shouldn't classify the page for malware.
1041 ExpectPreClassificationChecks(url, NULL, NULL, NULL, NULL, NULL, NULL); 1038 GURL url("http://host5.com/kill-switch");
1039 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, &kFalse,
1040 &kFalse, &kFalse);
1042 NavigateAndCommit(url); 1041 NavigateAndCommit(url);
1043 WaitAndCheckPreClassificationChecks(); 1042 WaitAndCheckPreClassificationChecks();
1044 1043
1045 msg = process()->sink().GetFirstMessageMatching( 1044 ExpectStartPhishingDetection(&url);
1046 SafeBrowsingMsg_StartPhishingDetection::ID); 1045 ExpectShouldClassifyForMalwareResult(false);
1047 ASSERT_FALSE(msg); 1046 }
1048 1047
1049 // Check that XHTML is supported, in addition to the default HTML type. 1048 TEST_F(ClientSideDetectionHostTest,
1050 // Note: for this test to work correctly, the new URL must be on the 1049 TestPreClassificationCheckKillswitchAndCsdWhitelist) {
1051 // same domain as the previous URL, otherwise it will create a new 1050 // If both the malware kill-swtich is on and the URL is on the csd whitelist,
1052 // RenderViewHost that won't have the mime type set. 1051 // we will leave pre-classification checks early.
1053 url = GURL("http://host.com/xhtml"); 1052 GURL url("http://host5.com/kill-switch-and-whitelisted");
1054 rvh_tester()->SetContentsMimeType("application/xhtml+xml"); 1053 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kTrue, &kTrue, NULL,
1055 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, 1054 NULL, NULL);
1056 &kFalse, &kFalse);
1057 NavigateAndCommit(url); 1055 NavigateAndCommit(url);
1058 WaitAndCheckPreClassificationChecks(); 1056 WaitAndCheckPreClassificationChecks();
1059 msg = process()->sink().GetFirstMessageMatching(
1060 SafeBrowsingMsg_StartPhishingDetection::ID);
1061 ASSERT_TRUE(msg);
1062 SafeBrowsingMsg_StartPhishingDetection::Read(msg, &actual_url);
1063 EXPECT_EQ(url, actual_url.a);
1064 EXPECT_EQ(rvh()->GetRoutingID(), msg->routing_id());
1065 process()->sink().ClearMessages();
1066 1057
1067 // Navigate to a new host, which should cause another IPC. 1058 ExpectStartPhishingDetection(NULL);
1068 url = GURL("http://host2.com/"); 1059 ExpectShouldClassifyForMalwareResult(false);
1060 }
1061
1062 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckInvalidCache) {
1063 // If item is in the cache but it isn't valid, we will classify regardless
1064 // of whether we are over the reporting limit.
1065 GURL url("http://host6.com/");
1069 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, 1066 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
1070 &kFalse, &kFalse); 1067 &kFalse, &kFalse, &kFalse);
mattm 2014/03/20 22:51:41 The flags seem to be wrong on the new version of t
noé 2014/03/21 00:08:38 Done.
1068
1071 NavigateAndCommit(url); 1069 NavigateAndCommit(url);
1072 WaitAndCheckPreClassificationChecks(); 1070 WaitAndCheckPreClassificationChecks();
1073 msg = process()->sink().GetFirstMessageMatching(
1074 SafeBrowsingMsg_StartPhishingDetection::ID);
1075 ASSERT_TRUE(msg);
1076 SafeBrowsingMsg_StartPhishingDetection::Read(msg, &actual_url);
1077 EXPECT_EQ(url, actual_url.a);
1078 EXPECT_EQ(rvh()->GetRoutingID(), msg->routing_id());
1079 process()->sink().ClearMessages();
1080 1071
1081 // If the mime type is not one that we support, no IPC should be triggered. 1072 ExpectStartPhishingDetection(&url);
1082 // Note: for this test to work correctly, the new URL must be on the 1073 ExpectShouldClassifyForMalwareResult(true);
1083 // same domain as the previous URL, otherwise it will create a new 1074 }
1084 // RenderViewHost that won't have the mime type set. 1075
1085 url = GURL("http://host2.com/image.jpg"); 1076 TEST_F(ClientSideDetectionHostTest,
1086 rvh_tester()->SetContentsMimeType("image/jpeg"); 1077 TestPreClassificationCheckOverReportingLimit) {
1087 ExpectPreClassificationChecks(url, NULL, NULL, NULL, NULL, NULL, NULL); 1078 // If the url isn't in the cache and we are over the reporting limit, we
1079 // don't do classification.
1080 GURL url("http://host7.com/");
1081 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
1082 &kFalse, &kFalse, &kTrue);
1088 NavigateAndCommit(url); 1083 NavigateAndCommit(url);
1089 WaitAndCheckPreClassificationChecks(); 1084 WaitAndCheckPreClassificationChecks();
1090 msg = process()->sink().GetFirstMessageMatching(
1091 SafeBrowsingMsg_StartPhishingDetection::ID);
1092 ASSERT_FALSE(msg);
1093 1085
1094 // If IsPrivateIPAddress returns true, no IPC should be triggered. 1086 ExpectStartPhishingDetection(NULL);
1095 url = GURL("http://host3.com/"); 1087 ExpectShouldClassifyForMalwareResult(true);
1096 ExpectPreClassificationChecks(url, &kTrue, NULL, NULL, NULL, NULL, NULL); 1088 }
1097 NavigateAndCommit(url);
1098 WaitAndCheckPreClassificationChecks();
1099 msg = process()->sink().GetFirstMessageMatching(
1100 SafeBrowsingMsg_StartPhishingDetection::ID);
1101 ASSERT_FALSE(msg);
1102 1089
1103 // If the tab is incognito there should be no IPC. Also, we shouldn't 1090 TEST_F(ClientSideDetectionHostTest, TestPreClassificationCheckValidCached) {
1104 // even check the csd-whitelist.
1105 url = GURL("http://host4.com/");
1106 ExpectPreClassificationChecks(url, &kFalse, &kTrue, NULL, NULL, NULL, NULL);
1107 NavigateAndCommit(url);
1108 WaitAndCheckPreClassificationChecks();
1109 msg = process()->sink().GetFirstMessageMatching(
1110 SafeBrowsingMsg_StartPhishingDetection::ID);
1111 ASSERT_FALSE(msg);
1112
1113 // If the URL is on the csd whitelist, no IPC should be triggered.
1114 url = GURL("http://host5.com/");
1115 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kTrue, NULL, NULL,
1116 NULL);
1117 NavigateAndCommit(url);
1118 WaitAndCheckPreClassificationChecks();
1119 msg = process()->sink().GetFirstMessageMatching(
1120 SafeBrowsingMsg_StartPhishingDetection::ID);
1121 ASSERT_FALSE(msg);
1122
1123 // If item is in the cache but it isn't valid, we will classify regardless
1124 // of whether we are over the reporting limit.
1125 url = GURL("http://host6.com/");
1126 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse, &kTrue,
1127 NULL);
1128 NavigateAndCommit(url);
1129 WaitAndCheckPreClassificationChecks();
1130 msg = process()->sink().GetFirstMessageMatching(
1131 SafeBrowsingMsg_StartPhishingDetection::ID);
1132 ASSERT_TRUE(msg);
1133 SafeBrowsingMsg_StartPhishingDetection::Read(msg, &actual_url);
1134 EXPECT_EQ(url, actual_url.a);
1135 EXPECT_EQ(rvh()->GetRoutingID(), msg->routing_id());
1136 process()->sink().ClearMessages();
1137
1138 // If the url isn't in the cache and we are over the reporting limit, we
1139 // don't do classification.
1140 url = GURL("http://host7.com/");
1141 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kFalse,
1142 &kFalse, &kTrue);
1143 NavigateAndCommit(url);
1144 WaitAndCheckPreClassificationChecks();
1145 msg = process()->sink().GetFirstMessageMatching(
1146 SafeBrowsingMsg_StartPhishingDetection::ID);
1147 ASSERT_FALSE(msg);
1148
1149 // If result is cached, we will try and display the blocking page directly 1091 // If result is cached, we will try and display the blocking page directly
1150 // with no start classification message. 1092 // with no start classification message.
1151 url = GURL("http://host8.com/"); 1093 GURL url("http://host8.com/");
1152 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, NULL, 1094 ExpectPreClassificationChecks(url, &kFalse, &kFalse, &kFalse, &kTrue, &kTrue,
mattm 2014/03/20 22:51:41 Is the malware_killswitch here on purpose?
noé 2014/03/21 00:08:38 Nop. Copy&Paste error. Good catch!
1153 NULL); 1095 &kFalse, &kFalse);
1154 1096
1155 UnsafeResource resource; 1097 UnsafeResource resource;
1156 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_)) 1098 EXPECT_CALL(*ui_manager_.get(), DisplayBlockingPage(_))
1157 .WillOnce(SaveArg<0>(&resource)); 1099 .WillOnce(SaveArg<0>(&resource));
1158 1100
1159 NavigateAndCommit(url); 1101 NavigateAndCommit(url);
1160 // Wait for CheckCsdWhitelist and CheckCache() to be called. 1102 // Wait for CheckCsdWhitelist and CheckCache() to be called.
1161 base::RunLoop().RunUntilIdle(); 1103 base::RunLoop().RunUntilIdle();
1162 // Now we check that all expected functions were indeed called on the two 1104 // Now we check that all expected functions were indeed called on the two
1163 // service objects. 1105 // service objects.
1164 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get())); 1106 EXPECT_TRUE(Mock::VerifyAndClear(csd_host_.get()));
1165 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get())); 1107 EXPECT_TRUE(Mock::VerifyAndClear(ui_manager_.get()));
1166 EXPECT_EQ(url, resource.url); 1108 EXPECT_EQ(url, resource.url);
1167 EXPECT_EQ(url, resource.original_url); 1109 EXPECT_EQ(url, resource.original_url);
1168 resource.callback.Reset(); 1110
1169 msg = process()->sink().GetFirstMessageMatching( 1111 ExpectStartPhishingDetection(NULL);
1170 SafeBrowsingMsg_StartPhishingDetection::ID); 1112 ExpectShouldClassifyForMalwareResult(false);
1171 ASSERT_FALSE(msg);
1172 } 1113 }
1173 } // namespace safe_browsing 1114 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698