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

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

Issue 42553002: Mostly integrate new malware IP blacklist with the csd client. When (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix leaks in the unit-tests Created 7 years, 1 month 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 "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_service.h" 20 #include "chrome/browser/safe_browsing/client_side_detection_host.h"
21 #include "chrome/browser/safe_browsing/database_manager.h"
22 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
21 #include "chrome/browser/safe_browsing/ui_manager.h" 23 #include "chrome/browser/safe_browsing/ui_manager.h"
22 #include "chrome/common/safe_browsing/csd.pb.h" 24 #include "chrome/common/safe_browsing/csd.pb.h"
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
24 #include "chrome/test/base/testing_profile.h" 26 #include "chrome/test/base/testing_profile.h"
25 #include "content/public/browser/navigation_controller.h" 27 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
27 #include "content/public/common/page_transition_types.h" 29 #include "content/public/common/page_transition_types.h"
28 #include "content/public/common/referrer.h" 30 #include "content/public/common/referrer.h"
29 #include "content/public/test/test_browser_thread.h" 31 #include "content/public/test/test_browser_thread.h"
30 #include "content/public/test/web_contents_tester.h" 32 #include "content/public/test/web_contents_tester.h"
31 #include "testing/gmock/include/gmock/gmock.h" 33 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h" 34 #include "testing/gtest/include/gtest/gtest.h"
33 #include "url/gurl.h" 35 #include "url/gurl.h"
34 36
37 using content::BrowserThread;
35 using content::WebContentsTester; 38 using content::WebContentsTester;
39
40 using testing::DoAll;
36 using testing::Return; 41 using testing::Return;
37 using testing::StrictMock; 42 using testing::StrictMock;
38 43
39 namespace safe_browsing { 44 namespace safe_browsing {
45
40 namespace { 46 namespace {
41 class MockClientSideDetectionService : public ClientSideDetectionService { 47
48 class MockSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
42 public: 49 public:
43 MockClientSideDetectionService() : ClientSideDetectionService(NULL) {} 50 explicit MockSafeBrowsingDatabaseManager(
44 virtual ~MockClientSideDetectionService() {}; 51 const scoped_refptr<SafeBrowsingService>& service)
52 : SafeBrowsingDatabaseManager(service) { }
45 53
46 MOCK_CONST_METHOD1(IsBadIpAddress, bool(const std::string&)); 54 MOCK_METHOD1(MatchMalwareIP, bool(const std::string& ip_address));
55
56 protected:
57 virtual ~MockSafeBrowsingDatabaseManager() {}
58
59 private:
60 DISALLOW_COPY_AND_ASSIGN(MockSafeBrowsingDatabaseManager);
61 };
62
63 class MockClientSideDetectionHost : public ClientSideDetectionHost {
64 public:
65 MockClientSideDetectionHost(
66 content::WebContents* tab,
67 SafeBrowsingDatabaseManager* database_manager)
68 : ClientSideDetectionHost(tab) {
69 set_safe_browsing_managers(NULL, database_manager);
70 }
71
72 virtual ~MockClientSideDetectionHost() {};
73
74 MOCK_METHOD1(IsBadIpAddress, bool(const std::string&));
47 }; 75 };
48 } // namespace 76 } // namespace
49 77
50 class BrowserFeatureExtractorTest : public ChromeRenderViewHostTestHarness { 78 class BrowserFeatureExtractorTest : public ChromeRenderViewHostTestHarness {
51 protected: 79 protected:
52 virtual void SetUp() { 80 virtual void SetUp() {
53 ChromeRenderViewHostTestHarness::SetUp(); 81 ChromeRenderViewHostTestHarness::SetUp();
54 ASSERT_TRUE(profile()->CreateHistoryService( 82 ASSERT_TRUE(profile()->CreateHistoryService(
55 true /* delete_file */, false /* no_db */)); 83 true /* delete_file */, false /* no_db */));
56 service_.reset(new StrictMock<MockClientSideDetectionService>()); 84
85 db_manager_ = new StrictMock<MockSafeBrowsingDatabaseManager>(
86 SafeBrowsingService::CreateSafeBrowsingService());
87 host_.reset(new StrictMock<MockClientSideDetectionHost>(
88 web_contents(), db_manager_.get()));
57 extractor_.reset( 89 extractor_.reset(
58 new BrowserFeatureExtractor(web_contents(), service_.get())); 90 new BrowserFeatureExtractor(web_contents(), host_.get()));
59 num_pending_ = 0; 91 num_pending_ = 0;
60 browse_info_.reset(new BrowseInfo); 92 browse_info_.reset(new BrowseInfo);
61 } 93 }
62 94
63 virtual void TearDown() { 95 virtual void TearDown() {
64 extractor_.reset(); 96 extractor_.reset();
97 host_.reset();
98 db_manager_ = NULL;
65 profile()->DestroyHistoryService(); 99 profile()->DestroyHistoryService();
66 ChromeRenderViewHostTestHarness::TearDown(); 100 ChromeRenderViewHostTestHarness::TearDown();
67 ASSERT_EQ(0, num_pending_); 101 ASSERT_EQ(0, num_pending_);
68 } 102 }
69 103
70 HistoryService* history_service() { 104 HistoryService* history_service() {
71 return HistoryServiceFactory::GetForProfile(profile(), 105 return HistoryServiceFactory::GetForProfile(profile(),
72 Profile::EXPLICIT_ACCESS); 106 Profile::EXPLICIT_ACCESS);
73 } 107 }
74 108
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 std::map<std::string, double>* features) { 165 std::map<std::string, double>* features) {
132 for (int i = 0; i < request.non_model_feature_map_size(); ++i) { 166 for (int i = 0; i < request.non_model_feature_map_size(); ++i) {
133 const ClientPhishingRequest::Feature& feature = 167 const ClientPhishingRequest::Feature& feature =
134 request.non_model_feature_map(i); 168 request.non_model_feature_map(i);
135 EXPECT_EQ(0U, features->count(feature.name())); 169 EXPECT_EQ(0U, features->count(feature.name()));
136 (*features)[feature.name()] = feature.value(); 170 (*features)[feature.name()] = feature.value();
137 } 171 }
138 } 172 }
139 173
140 void ExtractMalwareFeatures(ClientMalwareRequest* request) { 174 void ExtractMalwareFeatures(ClientMalwareRequest* request) {
175 // Feature extraction takes ownership of the request object
176 // and passes it along to the done callback in the end.
177 StartExtractMalwareFeatures(request);
178 base::MessageLoopForUI::current()->Run();
179 EXPECT_EQ(1U, success_.count(request));
180 EXPECT_TRUE(success_[request]);
181 }
182
183 void StartExtractMalwareFeatures(ClientMalwareRequest* request) {
184 success_.erase(request);
185 ++num_pending_;
186 // We temporarily give up ownership of request to ExtractMalwareFeatures
187 // but we'll regain ownership of it in ExtractMalwareFeaturesDone.
141 extractor_->ExtractMalwareFeatures( 188 extractor_->ExtractMalwareFeatures(
142 browse_info_.get(), request); 189 browse_info_.get(),
190 request,
191 base::Bind(&BrowserFeatureExtractorTest::ExtractMalwareFeaturesDone,
192 base::Unretained(this)));
143 } 193 }
144 194
145 void GetMalwareFeatureMap( 195 void GetMalwareFeatureMap(
146 const ClientMalwareRequest& request, 196 const ClientMalwareRequest& request,
147 std::map<std::string, std::set<std::string> >* features) { 197 std::map<std::string, std::set<std::string> >* features) {
148 for (int i = 0; i < request.feature_map_size(); ++i) { 198 for (int i = 0; i < request.feature_map_size(); ++i) {
149 const ClientMalwareRequest::Feature& feature = 199 const ClientMalwareRequest::Feature& feature =
150 request.feature_map(i); 200 request.feature_map(i);
151 EXPECT_EQ(0U, features->count(feature.name())); 201 EXPECT_EQ(0U, features->count(feature.name()));
152 std::set<std::string> meta_infos; 202 std::set<std::string> meta_infos;
153 for (int j = 0; j < feature.metainfo_size(); ++j) { 203 for (int j = 0; j < feature.metainfo_size(); ++j) {
154 meta_infos.insert(feature.metainfo(j)); 204 meta_infos.insert(feature.metainfo(j));
155 } 205 }
156 (*features)[feature.name()] = meta_infos; 206 (*features)[feature.name()] = meta_infos;
157 } 207 }
158 } 208 }
159 209
160 int num_pending_; 210 int num_pending_; // Number of pending feature extractions.
161 scoped_ptr<BrowserFeatureExtractor> extractor_; 211 scoped_ptr<BrowserFeatureExtractor> extractor_;
162 std::map<ClientPhishingRequest*, bool> success_; 212 std::map<void*, bool> success_;
163 scoped_ptr<BrowseInfo> browse_info_; 213 scoped_ptr<BrowseInfo> browse_info_;
164 scoped_ptr<MockClientSideDetectionService> service_; 214 scoped_ptr<StrictMock<MockClientSideDetectionHost> > host_;
215 scoped_refptr<StrictMock<MockSafeBrowsingDatabaseManager> > db_manager_;
165 216
166 private: 217 private:
167 void ExtractFeaturesDone(bool success, ClientPhishingRequest* request) { 218 void ExtractFeaturesDone(bool success, ClientPhishingRequest* request) {
168 ASSERT_EQ(0U, success_.count(request)); 219 ASSERT_EQ(0U, success_.count(request));
169 success_[request] = success; 220 success_[request] = success;
170 if (--num_pending_ == 0) { 221 if (--num_pending_ == 0) {
171 base::MessageLoop::current()->Quit(); 222 base::MessageLoop::current()->Quit();
172 } 223 }
173 } 224 }
225
226 void ExtractMalwareFeaturesDone(
227 bool success,
228 scoped_ptr<ClientMalwareRequest> request) {
229 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 ASSERT_EQ(0U, success_.count(request.get()));
231 // The pointer doesn't really belong to us. It belongs to
232 // the test case which passed it to ExtractMalwareFeatures above.
233 success_[request.release()] = success;
234 if (--num_pending_ == 0) {
235 base::MessageLoopForUI::current()->Quit();
236 }
237 }
174 }; 238 };
175 239
176 TEST_F(BrowserFeatureExtractorTest, UrlNotInHistory) { 240 TEST_F(BrowserFeatureExtractorTest, UrlNotInHistory) {
177 ClientPhishingRequest request; 241 ClientPhishingRequest request;
178 SimpleNavigateAndCommit(GURL("http://www.google.com")); 242 SimpleNavigateAndCommit(GURL("http://www.google.com"));
179 request.set_url("http://www.google.com/"); 243 request.set_url("http://www.google.com/");
180 request.set_client_score(0.5); 244 request.set_client_score(0.5);
181 EXPECT_FALSE(ExtractFeatures(&request)); 245 EXPECT_FALSE(ExtractFeatures(&request));
182 } 246 }
183 247
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 request.set_url("http://www.baz.com/"); 537 request.set_url("http://www.baz.com/");
474 request.set_client_score(0.5); 538 request.set_client_score(0.5);
475 redirect_chain.clear(); 539 redirect_chain.clear();
476 redirect_chain.push_back(GURL("https://bankofamerica.com")); 540 redirect_chain.push_back(GURL("https://bankofamerica.com"));
477 redirect_chain.push_back(GURL("http://www.baz.com/")); 541 redirect_chain.push_back(GURL("http://www.baz.com/"));
478 SetRedirectChain(redirect_chain, true); 542 SetRedirectChain(redirect_chain, true);
479 NavigateAndCommit(GURL("http://www.baz.com"), 543 NavigateAndCommit(GURL("http://www.baz.com"),
480 GURL("https://bankofamerica.com"), 544 GURL("https://bankofamerica.com"),
481 content::PAGE_TRANSITION_GENERATED); 545 content::PAGE_TRANSITION_GENERATED);
482 546
483 std::set<std::string> urls;
484 urls.insert("http://test.com");
485 browse_info_->ips.insert(std::make_pair("193.5.163.8", urls));
486 browse_info_->ips.insert(std::make_pair("23.94.78.1", urls));
487 EXPECT_CALL(*service_, IsBadIpAddress("193.5.163.8")).WillOnce(Return(true));
488 EXPECT_CALL(*service_, IsBadIpAddress("23.94.78.1")).WillOnce(Return(false));
489
490 EXPECT_TRUE(ExtractFeatures(&request)); 547 EXPECT_TRUE(ExtractFeatures(&request));
491 features.clear(); 548 features.clear();
492 GetFeatureMap(request, &features); 549 GetFeatureMap(request, &features);
493 550
494 EXPECT_EQ(1.0, 551 EXPECT_EQ(1.0,
495 features[base::StringPrintf("%s[0]=%s", 552 features[base::StringPrintf("%s[0]=%s",
496 features::kRedirect, 553 features::kRedirect,
497 features::kSecureRedirectValue)]); 554 features::kSecureRedirectValue)]);
498 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); 555 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]);
499 EXPECT_EQ(5.0, features[features::kPageTransitionType]); 556 EXPECT_EQ(5.0, features[features::kPageTransitionType]);
500 // Should not have redirect or host features. 557 // Should not have redirect or host features.
501 EXPECT_EQ(0U, 558 EXPECT_EQ(0U,
502 features.count(base::StringPrintf("%s%s", 559 features.count(base::StringPrintf("%s%s",
503 features::kHostPrefix, 560 features::kHostPrefix,
504 features::kPageTransitionType))); 561 features::kPageTransitionType)));
505 EXPECT_EQ(0U, 562 EXPECT_EQ(0U,
506 features.count(base::StringPrintf("%s%s", 563 features.count(base::StringPrintf("%s%s",
507 features::kHostPrefix, 564 features::kHostPrefix,
508 features::kIsFirstNavigation))); 565 features::kIsFirstNavigation)));
509 EXPECT_EQ(5.0, features[features::kPageTransitionType]); 566 EXPECT_EQ(5.0, features[features::kPageTransitionType]);
510 EXPECT_EQ(1.0, features[std::string(features::kBadIpFetch) + "193.5.163.8"]);
511 EXPECT_FALSE(features.count(std::string(features::kBadIpFetch) +
512 "23.94.78.1"));
513 } 567 }
514 568
515 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) { 569 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) {
516 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html")); 570 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html"));
517 ClientPhishingRequest request; 571 ClientPhishingRequest request;
518 request.set_url("http://www.foo.com/malware.html"); 572 request.set_url("http://www.foo.com/malware.html");
519 request.set_client_score(0.5); 573 request.set_client_score(0.5);
520 574
521 browse_info_->unsafe_resource.reset( 575 browse_info_->unsafe_resource.reset(
522 new SafeBrowsingUIManager::UnsafeResource); 576 new SafeBrowsingUIManager::UnsafeResource);
(...skipping 22 matching lines...) Expand all
545 request.set_url("http://www.foo.com/"); 599 request.set_url("http://www.foo.com/");
546 600
547 std::set<std::string> bad_urls; 601 std::set<std::string> bad_urls;
548 bad_urls.insert("http://bad.com"); 602 bad_urls.insert("http://bad.com");
549 bad_urls.insert("http://evil.com"); 603 bad_urls.insert("http://evil.com");
550 browse_info_->ips.insert(std::make_pair("193.5.163.8", bad_urls)); 604 browse_info_->ips.insert(std::make_pair("193.5.163.8", bad_urls));
551 browse_info_->ips.insert(std::make_pair("92.92.92.92", bad_urls)); 605 browse_info_->ips.insert(std::make_pair("92.92.92.92", bad_urls));
552 std::set<std::string> good_urls; 606 std::set<std::string> good_urls;
553 good_urls.insert("http://ok.com"); 607 good_urls.insert("http://ok.com");
554 browse_info_->ips.insert(std::make_pair("23.94.78.1", good_urls)); 608 browse_info_->ips.insert(std::make_pair("23.94.78.1", good_urls));
555 EXPECT_CALL(*service_, IsBadIpAddress("193.5.163.8")).WillOnce(Return(true)); 609 EXPECT_CALL(*db_manager_, MatchMalwareIP("193.5.163.8"))
556 EXPECT_CALL(*service_, IsBadIpAddress("92.92.92.92")).WillOnce(Return(true)); 610 .WillOnce(Return(true));
557 EXPECT_CALL(*service_, IsBadIpAddress("23.94.78.1")).WillOnce(Return(false)); 611 EXPECT_CALL(*db_manager_, MatchMalwareIP("92.92.92.92"))
612 .WillOnce(Return(true));
613 EXPECT_CALL(*db_manager_, MatchMalwareIP("23.94.78.1"))
614 .WillOnce(Return(false));
558 615
559 ExtractMalwareFeatures(&request); 616 ExtractMalwareFeatures(&request);
560 std::map<std::string, std::set<std::string> > features; 617 std::map<std::string, std::set<std::string> > features;
561 GetMalwareFeatureMap(request, &features); 618 GetMalwareFeatureMap(request, &features);
562 619
563 EXPECT_EQ(2U, features.size()); 620 EXPECT_EQ(2U, features.size());
564 std::string feature_name = base::StringPrintf("%s%s", features::kBadIpFetch, 621 std::string feature_name = base::StringPrintf("%s%s", features::kBadIpFetch,
565 "193.5.163.8"); 622 "193.5.163.8");
566 EXPECT_TRUE(features.count(feature_name)); 623 EXPECT_TRUE(features.count(feature_name));
567 std::set<std::string> urls = features[feature_name]; 624 std::set<std::string> urls = features[feature_name];
(...skipping 13 matching lines...) Expand all
581 ClientMalwareRequest request; 638 ClientMalwareRequest request;
582 request.set_url("http://www.foo.com/"); 639 request.set_url("http://www.foo.com/");
583 640
584 std::set<std::string> bad_urls; 641 std::set<std::string> bad_urls;
585 bad_urls.insert("http://bad.com"); 642 bad_urls.insert("http://bad.com");
586 std::vector<std::string> ips; 643 std::vector<std::string> ips;
587 for (int i = 0; i < 7; ++i) { // Add 7 ips 644 for (int i = 0; i < 7; ++i) { // Add 7 ips
588 std::string ip = base::StringPrintf("%d.%d.%d.%d", i, i, i, i); 645 std::string ip = base::StringPrintf("%d.%d.%d.%d", i, i, i, i);
589 ips.push_back(ip); 646 ips.push_back(ip);
590 browse_info_->ips.insert(std::make_pair(ip, bad_urls)); 647 browse_info_->ips.insert(std::make_pair(ip, bad_urls));
591 }
592 648
593 // First ip is good, then check the next 5 bad ips. 649 // First ip is good but all the others are bad.
594 // Not check the 7th as reached limit. 650 EXPECT_CALL(*db_manager_, MatchMalwareIP(ip)).WillOnce(Return(i > 0));
595 EXPECT_CALL(*service_, IsBadIpAddress(ips[0])).WillOnce(Return(false));
596 for (int i = 1; i < 6; ++i) {
597 EXPECT_CALL(*service_, IsBadIpAddress(ips[i])).WillOnce(Return(true));
598 } 651 }
599 652
600 ExtractMalwareFeatures(&request); 653 ExtractMalwareFeatures(&request);
601 std::map<std::string, std::set<std::string> > features; 654 std::map<std::string, std::set<std::string> > features;
602 GetMalwareFeatureMap(request, &features); 655 GetMalwareFeatureMap(request, &features);
603 656
604 // Only keep 5 ips. 657 // The number of IP match features we store is capped at 5 IPs per request.
605 EXPECT_EQ(5U, features.size()); 658 EXPECT_EQ(5U, features.size());
606 } 659 }
607 660
608 } // namespace safe_browsing 661 } // namespace safe_browsing
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/browser_feature_extractor.cc ('k') | chrome/browser/safe_browsing/client_side_detection_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698