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

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: Remove inline accessor 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 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 explicit MockClientSideDetectionHost(
66 SafeBrowsingDatabaseManager* database_manager)
67 : ClientSideDetectionHost(database_manager) {}
68 virtual ~MockClientSideDetectionHost() {};
69
70 MOCK_METHOD1(IsBadIpAddress, bool(const std::string&));
47 }; 71 };
48 } // namespace 72 } // namespace
49 73
50 class BrowserFeatureExtractorTest : public ChromeRenderViewHostTestHarness { 74 class BrowserFeatureExtractorTest : public ChromeRenderViewHostTestHarness {
51 protected: 75 protected:
52 virtual void SetUp() { 76 virtual void SetUp() {
53 ChromeRenderViewHostTestHarness::SetUp(); 77 ChromeRenderViewHostTestHarness::SetUp();
54 ASSERT_TRUE(profile()->CreateHistoryService( 78 ASSERT_TRUE(profile()->CreateHistoryService(
55 true /* delete_file */, false /* no_db */)); 79 true /* delete_file */, false /* no_db */));
56 service_.reset(new StrictMock<MockClientSideDetectionService>()); 80
81 sb_service_ = SafeBrowsingService::CreateSafeBrowsingService();
82 db_manager_ = new StrictMock<MockSafeBrowsingDatabaseManager>(
83 sb_service_);
84 host_.reset(new StrictMock<MockClientSideDetectionHost>(db_manager_.get()));
57 extractor_.reset( 85 extractor_.reset(
58 new BrowserFeatureExtractor(web_contents(), service_.get())); 86 new BrowserFeatureExtractor(web_contents(), host_.get()));
59 num_pending_ = 0; 87 num_pending_ = 0;
60 browse_info_.reset(new BrowseInfo); 88 browse_info_.reset(new BrowseInfo);
61 } 89 }
62 90
63 virtual void TearDown() { 91 virtual void TearDown() {
64 extractor_.reset(); 92 extractor_.reset();
65 profile()->DestroyHistoryService(); 93 profile()->DestroyHistoryService();
66 ChromeRenderViewHostTestHarness::TearDown(); 94 ChromeRenderViewHostTestHarness::TearDown();
67 ASSERT_EQ(0, num_pending_); 95 ASSERT_EQ(0, num_pending_);
68 } 96 }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 std::map<std::string, double>* features) { 159 std::map<std::string, double>* features) {
132 for (int i = 0; i < request.non_model_feature_map_size(); ++i) { 160 for (int i = 0; i < request.non_model_feature_map_size(); ++i) {
133 const ClientPhishingRequest::Feature& feature = 161 const ClientPhishingRequest::Feature& feature =
134 request.non_model_feature_map(i); 162 request.non_model_feature_map(i);
135 EXPECT_EQ(0U, features->count(feature.name())); 163 EXPECT_EQ(0U, features->count(feature.name()));
136 (*features)[feature.name()] = feature.value(); 164 (*features)[feature.name()] = feature.value();
137 } 165 }
138 } 166 }
139 167
140 void ExtractMalwareFeatures(ClientMalwareRequest* request) { 168 void ExtractMalwareFeatures(ClientMalwareRequest* request) {
169 // Feature extraction takes ownership of the request object
170 // and passes it along to the done callback in the end.
171 StartExtractMalwareFeatures(request);
172 base::MessageLoopForUI::current()->Run();
173 EXPECT_EQ(1U, success_.count(request));
174 EXPECT_TRUE(success_[request]);
175 }
176
177 void StartExtractMalwareFeatures(ClientMalwareRequest* request) {
178 success_.erase(request);
179 ++num_pending_;
180 scoped_ptr<ClientMalwareRequest> request_copy(new ClientMalwareRequest(
mattm 2013/10/29 01:11:47 hm, not sure I follow whats going on with the copy
noé 2013/10/31 02:41:12 Fixed and added a comment.
181 *request));
141 extractor_->ExtractMalwareFeatures( 182 extractor_->ExtractMalwareFeatures(
142 browse_info_.get(), request); 183 browse_info_.get(),
184 request_copy.release(),
185 base::Bind(&BrowserFeatureExtractorTest::ExtractMalwareFeaturesDone,
186 base::Unretained(this),
187 request));
143 } 188 }
144 189
145 void GetMalwareFeatureMap( 190 void GetMalwareFeatureMap(
146 const ClientMalwareRequest& request, 191 const ClientMalwareRequest& request,
147 std::map<std::string, std::set<std::string> >* features) { 192 std::map<std::string, std::set<std::string> >* features) {
148 for (int i = 0; i < request.feature_map_size(); ++i) { 193 for (int i = 0; i < request.feature_map_size(); ++i) {
149 const ClientMalwareRequest::Feature& feature = 194 const ClientMalwareRequest::Feature& feature =
150 request.feature_map(i); 195 request.feature_map(i);
151 EXPECT_EQ(0U, features->count(feature.name())); 196 EXPECT_EQ(0U, features->count(feature.name()));
152 std::set<std::string> meta_infos; 197 std::set<std::string> meta_infos;
153 for (int j = 0; j < feature.metainfo_size(); ++j) { 198 for (int j = 0; j < feature.metainfo_size(); ++j) {
154 meta_infos.insert(feature.metainfo(j)); 199 meta_infos.insert(feature.metainfo(j));
155 } 200 }
156 (*features)[feature.name()] = meta_infos; 201 (*features)[feature.name()] = meta_infos;
157 } 202 }
158 } 203 }
159 204
160 int num_pending_; 205 int num_pending_; // Number of pending feature extractions.
161 scoped_ptr<BrowserFeatureExtractor> extractor_; 206 scoped_ptr<BrowserFeatureExtractor> extractor_;
162 std::map<ClientPhishingRequest*, bool> success_; 207 std::map<void*, bool> success_;
163 scoped_ptr<BrowseInfo> browse_info_; 208 scoped_ptr<BrowseInfo> browse_info_;
164 scoped_ptr<MockClientSideDetectionService> service_; 209 scoped_ptr<StrictMock<MockClientSideDetectionHost> > host_;
210 scoped_refptr<StrictMock<MockSafeBrowsingDatabaseManager> > db_manager_;
211 scoped_refptr<SafeBrowsingService> sb_service_;
165 212
166 private: 213 private:
167 void ExtractFeaturesDone(bool success, ClientPhishingRequest* request) { 214 void ExtractFeaturesDone(bool success, ClientPhishingRequest* request) {
168 ASSERT_EQ(0U, success_.count(request)); 215 ASSERT_EQ(0U, success_.count(request));
169 success_[request] = success; 216 success_[request] = success;
170 if (--num_pending_ == 0) { 217 if (--num_pending_ == 0) {
171 base::MessageLoop::current()->Quit(); 218 base::MessageLoop::current()->Quit();
172 } 219 }
173 } 220 }
221
222 void ExtractMalwareFeaturesDone(
223 ClientMalwareRequest* client_request,
224 bool success,
225 scoped_ptr<ClientMalwareRequest> request_copy) {
226 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
227 ASSERT_EQ(0U, success_.count(client_request));
228 success_[client_request] = success;
229 *client_request = *request_copy;
230 if (--num_pending_ == 0) {
231 base::MessageLoopForUI::current()->Quit();
232 }
233 }
174 }; 234 };
175 235
176 TEST_F(BrowserFeatureExtractorTest, UrlNotInHistory) { 236 TEST_F(BrowserFeatureExtractorTest, UrlNotInHistory) {
177 ClientPhishingRequest request; 237 ClientPhishingRequest request;
178 SimpleNavigateAndCommit(GURL("http://www.google.com")); 238 SimpleNavigateAndCommit(GURL("http://www.google.com"));
179 request.set_url("http://www.google.com/"); 239 request.set_url("http://www.google.com/");
180 request.set_client_score(0.5); 240 request.set_client_score(0.5);
181 EXPECT_FALSE(ExtractFeatures(&request)); 241 EXPECT_FALSE(ExtractFeatures(&request));
182 } 242 }
183 243
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 request.set_url("http://www.baz.com/"); 533 request.set_url("http://www.baz.com/");
474 request.set_client_score(0.5); 534 request.set_client_score(0.5);
475 redirect_chain.clear(); 535 redirect_chain.clear();
476 redirect_chain.push_back(GURL("https://bankofamerica.com")); 536 redirect_chain.push_back(GURL("https://bankofamerica.com"));
477 redirect_chain.push_back(GURL("http://www.baz.com/")); 537 redirect_chain.push_back(GURL("http://www.baz.com/"));
478 SetRedirectChain(redirect_chain, true); 538 SetRedirectChain(redirect_chain, true);
479 NavigateAndCommit(GURL("http://www.baz.com"), 539 NavigateAndCommit(GURL("http://www.baz.com"),
480 GURL("https://bankofamerica.com"), 540 GURL("https://bankofamerica.com"),
481 content::PAGE_TRANSITION_GENERATED); 541 content::PAGE_TRANSITION_GENERATED);
482 542
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)); 543 EXPECT_TRUE(ExtractFeatures(&request));
491 features.clear(); 544 features.clear();
492 GetFeatureMap(request, &features); 545 GetFeatureMap(request, &features);
493 546
494 EXPECT_EQ(1.0, 547 EXPECT_EQ(1.0,
495 features[base::StringPrintf("%s[0]=%s", 548 features[base::StringPrintf("%s[0]=%s",
496 features::kRedirect, 549 features::kRedirect,
497 features::kSecureRedirectValue)]); 550 features::kSecureRedirectValue)]);
498 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]); 551 EXPECT_EQ(1.0, features[features::kHasSSLReferrer]);
499 EXPECT_EQ(5.0, features[features::kPageTransitionType]); 552 EXPECT_EQ(5.0, features[features::kPageTransitionType]);
500 // Should not have redirect or host features. 553 // Should not have redirect or host features.
501 EXPECT_EQ(0U, 554 EXPECT_EQ(0U,
502 features.count(base::StringPrintf("%s%s", 555 features.count(base::StringPrintf("%s%s",
503 features::kHostPrefix, 556 features::kHostPrefix,
504 features::kPageTransitionType))); 557 features::kPageTransitionType)));
505 EXPECT_EQ(0U, 558 EXPECT_EQ(0U,
506 features.count(base::StringPrintf("%s%s", 559 features.count(base::StringPrintf("%s%s",
507 features::kHostPrefix, 560 features::kHostPrefix,
508 features::kIsFirstNavigation))); 561 features::kIsFirstNavigation)));
509 EXPECT_EQ(5.0, features[features::kPageTransitionType]); 562 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 } 563 }
514 564
515 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) { 565 TEST_F(BrowserFeatureExtractorTest, SafeBrowsingFeatures) {
516 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html")); 566 SimpleNavigateAndCommit(GURL("http://www.foo.com/malware.html"));
517 ClientPhishingRequest request; 567 ClientPhishingRequest request;
518 request.set_url("http://www.foo.com/malware.html"); 568 request.set_url("http://www.foo.com/malware.html");
519 request.set_client_score(0.5); 569 request.set_client_score(0.5);
520 570
521 browse_info_->unsafe_resource.reset( 571 browse_info_->unsafe_resource.reset(
522 new SafeBrowsingUIManager::UnsafeResource); 572 new SafeBrowsingUIManager::UnsafeResource);
(...skipping 22 matching lines...) Expand all
545 request.set_url("http://www.foo.com/"); 595 request.set_url("http://www.foo.com/");
546 596
547 std::set<std::string> bad_urls; 597 std::set<std::string> bad_urls;
548 bad_urls.insert("http://bad.com"); 598 bad_urls.insert("http://bad.com");
549 bad_urls.insert("http://evil.com"); 599 bad_urls.insert("http://evil.com");
550 browse_info_->ips.insert(std::make_pair("193.5.163.8", bad_urls)); 600 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)); 601 browse_info_->ips.insert(std::make_pair("92.92.92.92", bad_urls));
552 std::set<std::string> good_urls; 602 std::set<std::string> good_urls;
553 good_urls.insert("http://ok.com"); 603 good_urls.insert("http://ok.com");
554 browse_info_->ips.insert(std::make_pair("23.94.78.1", good_urls)); 604 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)); 605 EXPECT_CALL(*db_manager_, MatchMalwareIP("193.5.163.8"))
556 EXPECT_CALL(*service_, IsBadIpAddress("92.92.92.92")).WillOnce(Return(true)); 606 .WillOnce(Return(true));
557 EXPECT_CALL(*service_, IsBadIpAddress("23.94.78.1")).WillOnce(Return(false)); 607 EXPECT_CALL(*db_manager_, MatchMalwareIP("92.92.92.92"))
608 .WillOnce(Return(true));
609 EXPECT_CALL(*db_manager_, MatchMalwareIP("23.94.78.1"))
610 .WillOnce(Return(false));
558 611
559 ExtractMalwareFeatures(&request); 612 ExtractMalwareFeatures(&request);
560 std::map<std::string, std::set<std::string> > features; 613 std::map<std::string, std::set<std::string> > features;
561 GetMalwareFeatureMap(request, &features); 614 GetMalwareFeatureMap(request, &features);
562 615
563 EXPECT_EQ(2U, features.size()); 616 EXPECT_EQ(2U, features.size());
564 std::string feature_name = base::StringPrintf("%s%s", features::kBadIpFetch, 617 std::string feature_name = base::StringPrintf("%s%s", features::kBadIpFetch,
565 "193.5.163.8"); 618 "193.5.163.8");
566 EXPECT_TRUE(features.count(feature_name)); 619 EXPECT_TRUE(features.count(feature_name));
567 std::set<std::string> urls = features[feature_name]; 620 std::set<std::string> urls = features[feature_name];
(...skipping 13 matching lines...) Expand all
581 ClientMalwareRequest request; 634 ClientMalwareRequest request;
582 request.set_url("http://www.foo.com/"); 635 request.set_url("http://www.foo.com/");
583 636
584 std::set<std::string> bad_urls; 637 std::set<std::string> bad_urls;
585 bad_urls.insert("http://bad.com"); 638 bad_urls.insert("http://bad.com");
586 std::vector<std::string> ips; 639 std::vector<std::string> ips;
587 for (int i = 0; i < 7; ++i) { // Add 7 ips 640 for (int i = 0; i < 7; ++i) { // Add 7 ips
588 std::string ip = base::StringPrintf("%d.%d.%d.%d", i, i, i, i); 641 std::string ip = base::StringPrintf("%d.%d.%d.%d", i, i, i, i);
589 ips.push_back(ip); 642 ips.push_back(ip);
590 browse_info_->ips.insert(std::make_pair(ip, bad_urls)); 643 browse_info_->ips.insert(std::make_pair(ip, bad_urls));
591 }
592 644
593 // First ip is good, then check the next 5 bad ips. 645 // First ip is good but all the others are bad.
594 // Not check the 7th as reached limit. 646 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 } 647 }
599 648
600 ExtractMalwareFeatures(&request); 649 ExtractMalwareFeatures(&request);
601 std::map<std::string, std::set<std::string> > features; 650 std::map<std::string, std::set<std::string> > features;
602 GetMalwareFeatureMap(request, &features); 651 GetMalwareFeatureMap(request, &features);
603 652
604 // Only keep 5 ips. 653 // The number of IP match features we store is capped at 5 IPs per request.
605 EXPECT_EQ(5U, features.size()); 654 EXPECT_EQ(5U, features.size());
606 } 655 }
607 656
608 } // namespace safe_browsing 657 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698