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

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

Issue 7465101: Check that all the hashes ids in the model are valid. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Address Matt's comments. Created 9 years, 4 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/client_side_detection_service.h" 5 #include "chrome/browser/safe_browsing/client_side_detection_service.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 NotificationService::AllSources()); 69 NotificationService::AllSources());
70 } 70 }
71 71
72 ClientSideDetectionService::~ClientSideDetectionService() { 72 ClientSideDetectionService::~ClientSideDetectionService() {
73 method_factory_.RevokeAll(); 73 method_factory_.RevokeAll();
74 STLDeleteContainerPairPointers(client_phishing_reports_.begin(), 74 STLDeleteContainerPairPointers(client_phishing_reports_.begin(),
75 client_phishing_reports_.end()); 75 client_phishing_reports_.end());
76 client_phishing_reports_.clear(); 76 client_phishing_reports_.clear();
77 } 77 }
78 78
79 /* static */ 79 // static
80 ClientSideDetectionService* ClientSideDetectionService::Create( 80 ClientSideDetectionService* ClientSideDetectionService::Create(
81 net::URLRequestContextGetter* request_context_getter) { 81 net::URLRequestContextGetter* request_context_getter) {
82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
83 scoped_ptr<ClientSideDetectionService> service( 83 scoped_ptr<ClientSideDetectionService> service(
84 new ClientSideDetectionService(request_context_getter)); 84 new ClientSideDetectionService(request_context_getter));
85 if (!service->InitializePrivateNetworks()) { 85 if (!service->InitializePrivateNetworks()) {
86 UMA_HISTOGRAM_COUNTS("SBClientPhishing.InitPrivateNetworksFailed", 1); 86 UMA_HISTOGRAM_COUNTS("SBClientPhishing.InitPrivateNetworksFailed", 1);
87 return NULL; 87 return NULL;
88 } 88 }
89 // We fetch the model at every browser restart. In a lot of cases the model 89 // We fetch the model at every browser restart. In a lot of cases the model
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 if (!status.is_success() || RC_REQUEST_OK != response_code) { 292 if (!status.is_success() || RC_REQUEST_OK != response_code) {
293 model_status = MODEL_FETCH_FAILED; 293 model_status = MODEL_FETCH_FAILED;
294 } else if (data.empty()) { 294 } else if (data.empty()) {
295 model_status = MODEL_EMPTY; 295 model_status = MODEL_EMPTY;
296 } else if (data.size() > kMaxModelSizeBytes) { 296 } else if (data.size() > kMaxModelSizeBytes) {
297 model_status = MODEL_TOO_LARGE; 297 model_status = MODEL_TOO_LARGE;
298 } else if (!model->ParseFromString(data)) { 298 } else if (!model->ParseFromString(data)) {
299 model_status = MODEL_PARSE_ERROR; 299 model_status = MODEL_PARSE_ERROR;
300 } else if (!model->IsInitialized() || !model->has_version()) { 300 } else if (!model->IsInitialized() || !model->has_version()) {
301 model_status = MODEL_MISSING_FIELDS; 301 model_status = MODEL_MISSING_FIELDS;
302 } else if (!ModelHasValidHashIds(*model)) {
303 model_status = MODEL_BAD_HASH_IDS;
302 } else if (model->version() < 0 || 304 } else if (model->version() < 0 ||
303 (model_.get() && model->version() < model_->version())) { 305 (model_.get() && model->version() < model_->version())) {
304 model_status = MODEL_INVALID_VERSION_NUMBER; 306 model_status = MODEL_INVALID_VERSION_NUMBER;
305 } else if (model_.get() && model->version() == model_->version()) { 307 } else if (model_.get() && model->version() == model_->version()) {
306 model_status = MODEL_NOT_CHANGED; 308 model_status = MODEL_NOT_CHANGED;
307 } else { 309 } else {
308 // The model is valid => replace the existing model with the new one. 310 // The model is valid => replace the existing model with the new one.
309 model_str_.assign(data); 311 model_str_.assign(data);
310 model_.swap(model); 312 model_.swap(model);
311 model_status = MODEL_SUCCESS; 313 model_status = MODEL_SUCCESS;
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 private_networks_.push_back(std::make_pair(ip_number, prefix_length)); 428 private_networks_.push_back(std::make_pair(ip_number, prefix_length));
427 } else { 429 } else {
428 DLOG(FATAL) << "Unable to parse IP address range: " 430 DLOG(FATAL) << "Unable to parse IP address range: "
429 << kPrivateNetworks[i]; 431 << kPrivateNetworks[i];
430 return false; 432 return false;
431 } 433 }
432 } 434 }
433 return true; 435 return true;
434 } 436 }
435 437
436 /* static */ 438 // static
437 void ClientSideDetectionService::SetBadSubnets(const ClientSideModel& model, 439 void ClientSideDetectionService::SetBadSubnets(const ClientSideModel& model,
438 BadSubnetMap* bad_subnets) { 440 BadSubnetMap* bad_subnets) {
439 bad_subnets->clear(); 441 bad_subnets->clear();
440 for (int i = 0; i < model.bad_subnet_size(); ++i) { 442 for (int i = 0; i < model.bad_subnet_size(); ++i) {
441 int size = model.bad_subnet(i).size(); 443 int size = model.bad_subnet(i).size();
442 if (size < 0 || size > static_cast<int>(net::kIPv6AddressSize) * 8) { 444 if (size < 0 || size > static_cast<int>(net::kIPv6AddressSize) * 8) {
443 DLOG(ERROR) << "Invalid bad subnet size: " << size; 445 DLOG(ERROR) << "Invalid bad subnet size: " << size;
444 continue; 446 continue;
445 } 447 }
446 if (model.bad_subnet(i).prefix().size() != crypto::SHA256_LENGTH) { 448 if (model.bad_subnet(i).prefix().size() != crypto::SHA256_LENGTH) {
447 DLOG(ERROR) << "Invalid bad subnet prefix length: " 449 DLOG(ERROR) << "Invalid bad subnet prefix length: "
448 << model.bad_subnet(i).prefix().size(); 450 << model.bad_subnet(i).prefix().size();
449 continue; 451 continue;
450 } 452 }
451 // We precompute the mask for the given subnet size to speed up lookups. 453 // We precompute the mask for the given subnet size to speed up lookups.
452 // Basically we need to create a 16B long string which has the highest 454 // Basically we need to create a 16B long string which has the highest
453 // |size| bits sets to one. 455 // |size| bits sets to one.
454 std::string mask(net::kIPv6AddressSize, '\x00'); 456 std::string mask(net::kIPv6AddressSize, '\x00');
455 mask.replace(0, size / 8, size / 8, '\xFF'); 457 mask.replace(0, size / 8, size / 8, '\xFF');
456 if (size % 8) { 458 if (size % 8) {
457 mask[size / 8] = 0xFF << (8 - (size % 8)); 459 mask[size / 8] = 0xFF << (8 - (size % 8));
458 } 460 }
459 (*bad_subnets)[mask].insert(model.bad_subnet(i).prefix()); 461 (*bad_subnets)[mask].insert(model.bad_subnet(i).prefix());
460 } 462 }
461 } 463 }
464
465 // static
466 bool ClientSideDetectionService::ModelHasValidHashIds(
467 const ClientSideModel& model) {
468 const int max_index = model.hashes_size() - 1;
469 for (int i = 0; i < model.rule_size(); ++i) {
470 for (int j = 0; j < model.rule(i).feature_size(); ++j) {
471 if (model.rule(i).feature(j) < 0 ||
472 model.rule(i).feature(j) > max_index) {
473 return false;
474 }
475 }
476 }
477 for (int i = 0; i < model.page_term_size(); ++i) {
478 if (model.page_term(i) < 0 || model.page_term(i) > max_index) {
479 return false;
480 }
481 }
482 for (int i = 0; i < model.page_word_size(); ++i) {
483 if (model.page_word(i) < 0 || model.page_word(i) > max_index) {
484 return false;
485 }
486 }
487 return true;
488 }
462 } // namespace safe_browsing 489 } // namespace safe_browsing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698