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

Side by Side Diff: chrome/browser/safe_browsing/browser_feature_extractor.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 <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/format_macros.h" 12 #include "base/format_macros.h"
13 #include "base/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/time/time.h" 15 #include "base/time/time.h"
16 #include "chrome/browser/common/cancelable_request.h" 16 #include "chrome/browser/common/cancelable_request.h"
17 #include "chrome/browser/history/history_service.h" 17 #include "chrome/browser/history/history_service.h"
18 #include "chrome/browser/history/history_service_factory.h" 18 #include "chrome/browser/history/history_service_factory.h"
19 #include "chrome/browser/history/history_types.h" 19 #include "chrome/browser/history/history_types.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/safe_browsing/browser_features.h" 21 #include "chrome/browser/safe_browsing/browser_features.h"
22 #include "chrome/browser/safe_browsing/client_side_detection_service.h" 22 #include "chrome/browser/safe_browsing/client_side_detection_host.h"
23 #include "chrome/browser/safe_browsing/database_manager.h"
23 #include "chrome/common/safe_browsing/csd.pb.h" 24 #include "chrome/common/safe_browsing/csd.pb.h"
24 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/navigation_controller.h" 26 #include "content/public/browser/navigation_controller.h"
26 #include "content/public/browser/navigation_entry.h" 27 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/page_transition_types.h" 29 #include "content/public/common/page_transition_types.h"
29 #include "url/gurl.h" 30 #include "url/gurl.h"
30 31
31 using content::BrowserThread; 32 using content::BrowserThread;
32 using content::NavigationController; 33 using content::NavigationController;
33 using content::NavigationEntry; 34 using content::NavigationEntry;
34 using content::WebContents; 35 using content::WebContents;
35 36
36 namespace safe_browsing { 37 namespace safe_browsing {
37 38
38 const int BrowserFeatureExtractor::kMaxMalwareIPPerRequest = 5; 39 namespace {
40
41 const int kMaxMalwareIPPerRequest = 5;
42
43 void FilterBenignIpsOnIOThread(
44 scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
45 IPUrlMap* ips) {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
47 for (IPUrlMap::iterator it = ips->begin(); it != ips->end();) {
48 if (!database_manager.get() ||
49 !database_manager->MatchMalwareIP(it->first)) {
50 // it++ here returns a copy of the old iterator and passes it to erase.
51 ips->erase(it++);
52 } else {
53 ++it;
54 }
55 }
56 }
57 } // namespace
39 58
40 BrowseInfo::BrowseInfo() : http_status_code(0) {} 59 BrowseInfo::BrowseInfo() : http_status_code(0) {}
41 60
42 BrowseInfo::~BrowseInfo() {} 61 BrowseInfo::~BrowseInfo() {}
43 62
44 static void AddFeature(const std::string& feature_name, 63 static void AddFeature(const std::string& feature_name,
45 double feature_value, 64 double feature_value,
46 ClientPhishingRequest* request) { 65 ClientPhishingRequest* request) {
47 DCHECK(request); 66 DCHECK(request);
48 ClientPhishingRequest::Feature* feature = 67 ClientPhishingRequest::Feature* feature =
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 features::kRedirect, 144 features::kRedirect,
126 i, 145 i,
127 printable_redirect.c_str()), 146 printable_redirect.c_str()),
128 1.0, 147 1.0,
129 request); 148 request);
130 } 149 }
131 } 150 }
132 151
133 BrowserFeatureExtractor::BrowserFeatureExtractor( 152 BrowserFeatureExtractor::BrowserFeatureExtractor(
134 WebContents* tab, 153 WebContents* tab,
135 ClientSideDetectionService* service) 154 ClientSideDetectionHost* host)
136 : tab_(tab), 155 : tab_(tab),
137 service_(service), 156 host_(host),
138 weak_factory_(this) { 157 weak_factory_(this) {
139 DCHECK(tab); 158 DCHECK(tab);
140 } 159 }
141 160
142 BrowserFeatureExtractor::~BrowserFeatureExtractor() { 161 BrowserFeatureExtractor::~BrowserFeatureExtractor() {
143 weak_factory_.InvalidateWeakPtrs(); 162 weak_factory_.InvalidateWeakPtrs();
144 // Delete all the pending extractions (delete callback and request objects). 163 // Delete all the pending extractions (delete callback and request objects).
145 STLDeleteContainerPairFirstPointers(pending_extractions_.begin(), 164 STLDeleteContainerPairFirstPointers(pending_extractions_.begin(),
146 pending_extractions_.end()); 165 pending_extractions_.end());
147 166
(...skipping 14 matching lines...) Expand all
162 } 181 }
163 182
164 void BrowserFeatureExtractor::ExtractFeatures(const BrowseInfo* info, 183 void BrowserFeatureExtractor::ExtractFeatures(const BrowseInfo* info,
165 ClientPhishingRequest* request, 184 ClientPhishingRequest* request,
166 const DoneCallback& callback) { 185 const DoneCallback& callback) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 186 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 DCHECK(request); 187 DCHECK(request);
169 DCHECK(info); 188 DCHECK(info);
170 DCHECK_EQ(0U, request->url().find("http:")); 189 DCHECK_EQ(0U, request->url().find("http:"));
171 DCHECK(!callback.is_null()); 190 DCHECK(!callback.is_null());
172 if (callback.is_null()) {
173 DLOG(ERROR) << "ExtractFeatures called without a callback object";
174 return;
175 }
176
177 // Extract features pertaining to this navigation. 191 // Extract features pertaining to this navigation.
178 const NavigationController& controller = tab_->GetController(); 192 const NavigationController& controller = tab_->GetController();
179 int url_index = -1; 193 int url_index = -1;
180 int first_host_index = -1; 194 int first_host_index = -1;
181 195
182 GURL request_url(request->url()); 196 GURL request_url(request->url());
183 int index = controller.GetCurrentEntryIndex(); 197 int index = controller.GetCurrentEntryIndex();
184 // The url that we are extracting features for should already be commited. 198 // The url that we are extracting features for should already be commited.
185 DCHECK_NE(index, -1); 199 DCHECK_NE(index, -1);
186 for (; index >= 0; index--) { 200 for (; index >= 0; index--) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 237
224 ExtractBrowseInfoFeatures(*info, request); 238 ExtractBrowseInfoFeatures(*info, request);
225 pending_extractions_[request] = callback; 239 pending_extractions_[request] = callback;
226 base::MessageLoop::current()->PostTask( 240 base::MessageLoop::current()->PostTask(
227 FROM_HERE, 241 FROM_HERE,
228 base::Bind(&BrowserFeatureExtractor::StartExtractFeatures, 242 base::Bind(&BrowserFeatureExtractor::StartExtractFeatures,
229 weak_factory_.GetWeakPtr(), request, callback)); 243 weak_factory_.GetWeakPtr(), request, callback));
230 } 244 }
231 245
232 void BrowserFeatureExtractor::ExtractMalwareFeatures( 246 void BrowserFeatureExtractor::ExtractMalwareFeatures(
233 const BrowseInfo* info, 247 BrowseInfo* info,
234 ClientMalwareRequest* request) { 248 ClientMalwareRequest* request,
249 const MalwareDoneCallback& callback) {
235 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
236 DCHECK(request);
237 DCHECK(info);
238 DCHECK_EQ(0U, request->url().find("http:")); 251 DCHECK_EQ(0U, request->url().find("http:"));
239 // get the IPs and urls that match the malware blacklisted IP list. 252 DCHECK(!callback.is_null());
240 if (service_) { 253
241 int matched_bad_ips = 0; 254 // Grab the IPs because they might go away before we're done
242 for (IPUrlMap::const_iterator it = info->ips.begin(); 255 // checking them against the IP blacklist on the IO thread.
243 it != info->ips.end(); ++it) { 256 scoped_ptr<IPUrlMap> ips(new IPUrlMap);
244 if (service_->IsBadIpAddress(it->first)) { 257 ips->swap(info->ips);
245 AddMalwareFeature(features::kBadIpFetch + it->first, 258
246 it->second, 1.0, request); 259 IPUrlMap* ips_ptr = ips.get();
247 ++matched_bad_ips; 260
248 // Limit the number of matched bad IPs in one request to control 261 // The API doesn't take a scoped_ptr because the API gets mocked and we
249 // the request's size 262 // cannot mock an API that takes scoped_ptr as arguments.
250 if (matched_bad_ips >= kMaxMalwareIPPerRequest) { 263 scoped_ptr<ClientMalwareRequest> req(request);
251 return; 264
252 } 265 // IP blacklist lookups have to happen on the IO thread.
253 } 266 BrowserThread::PostTaskAndReply(
254 } 267 BrowserThread::IO,
255 } 268 FROM_HERE,
269 base::Bind(&FilterBenignIpsOnIOThread,
270 host_->database_manager(),
271 ips_ptr),
272 base::Bind(&BrowserFeatureExtractor::FinishExtractMalwareFeatures,
273 weak_factory_.GetWeakPtr(),
274 base::Passed(&ips), callback, base::Passed(&req)));
256 } 275 }
257 276
258 void BrowserFeatureExtractor::ExtractBrowseInfoFeatures( 277 void BrowserFeatureExtractor::ExtractBrowseInfoFeatures(
259 const BrowseInfo& info, 278 const BrowseInfo& info,
260 ClientPhishingRequest* request) { 279 ClientPhishingRequest* request) {
261 if (service_) {
262 for (IPUrlMap::const_iterator it = info.ips.begin();
263 it != info.ips.end(); ++it) {
264 if (service_->IsBadIpAddress(it->first)) {
265 AddFeature(features::kBadIpFetch + it->first, 1.0, request);
266 }
267 }
268 }
269 if (info.unsafe_resource.get()) { 280 if (info.unsafe_resource.get()) {
270 // A SafeBrowsing interstitial was shown for the current URL. 281 // A SafeBrowsing interstitial was shown for the current URL.
271 AddFeature(features::kSafeBrowsingMaliciousUrl + 282 AddFeature(features::kSafeBrowsingMaliciousUrl +
272 info.unsafe_resource->url.spec(), 283 info.unsafe_resource->url.spec(),
273 1.0, 284 1.0,
274 request); 285 request);
275 AddFeature(features::kSafeBrowsingOriginalUrl + 286 AddFeature(features::kSafeBrowsingOriginalUrl +
276 info.unsafe_resource->original_url.spec(), 287 info.unsafe_resource->original_url.spec(),
277 1.0, 288 1.0,
278 request); 289 request);
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 *history = HistoryServiceFactory::GetForProfile(profile, 499 *history = HistoryServiceFactory::GetForProfile(profile,
489 Profile::EXPLICIT_ACCESS); 500 Profile::EXPLICIT_ACCESS);
490 if (*history) { 501 if (*history) {
491 return true; 502 return true;
492 } 503 }
493 } 504 }
494 VLOG(2) << "Unable to query history. No history service available."; 505 VLOG(2) << "Unable to query history. No history service available.";
495 return false; 506 return false;
496 } 507 }
497 508
509 void BrowserFeatureExtractor::FinishExtractMalwareFeatures(
510 scoped_ptr<IPUrlMap> bad_ips,
511 MalwareDoneCallback callback,
512 scoped_ptr<ClientMalwareRequest> request) {
513 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
514 int matched_bad_ips = 0;
515 for (IPUrlMap::const_iterator it = bad_ips->begin();
516 it != bad_ips->end(); ++it) {
517 AddMalwareFeature(features::kBadIpFetch + it->first,
518 it->second, 1.0, request.get());
519 ++matched_bad_ips;
520 // Limit the number of matched bad IPs in one request to control
521 // the request's size
522 if (matched_bad_ips >= kMaxMalwareIPPerRequest) {
523 break;
524 }
525 }
526 callback.Run(true, request.Pass());
527 }
528
498 } // namespace safe_browsing 529 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698