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

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

Issue 14999008: Add a killswitch for CSD malware IP match and report feature. Use a new killswitch whitelist URL wh… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comment and add unittest Created 7 years, 7 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 "chrome/browser/safe_browsing/safe_browsing_database.h" 5 #include "chrome/browser/safe_browsing/safe_browsing_database.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // Maximum number of entries we allow in any of the whitelists. 60 // Maximum number of entries we allow in any of the whitelists.
61 // If a whitelist on disk contains more entries then all lookups to 61 // If a whitelist on disk contains more entries then all lookups to
62 // the whitelist will be considered a match. 62 // the whitelist will be considered a match.
63 const size_t kMaxWhitelistSize = 5000; 63 const size_t kMaxWhitelistSize = 5000;
64 64
65 // If the hash of this exact expression is on a whitelist then all 65 // If the hash of this exact expression is on a whitelist then all
66 // lookups to this whitelist will be considered a match. 66 // lookups to this whitelist will be considered a match.
67 const char kWhitelistKillSwitchUrl[] = 67 const char kWhitelistKillSwitchUrl[] =
68 "sb-ssl.google.com/safebrowsing/csd/killswitch"; // Don't change this! 68 "sb-ssl.google.com/safebrowsing/csd/killswitch"; // Don't change this!
69 69
70 // If the hash of this exact expression is on a whitelist then the
71 // malware IP blacklisting feature will be disabled in csd.
72 // Don't change this!
73 const char kMalwareIPKillSwitchUrl[] =
74 "sb-ssl.google.com/safebrowsing/csd/killswitch_malware";
75
70 // To save space, the incoming |chunk_id| and |list_id| are combined 76 // To save space, the incoming |chunk_id| and |list_id| are combined
71 // into an |encoded_chunk_id| for storage by shifting the |list_id| 77 // into an |encoded_chunk_id| for storage by shifting the |list_id|
72 // into the low-order bits. These functions decode that information. 78 // into the low-order bits. These functions decode that information.
73 // TODO(lzheng): It was reasonable when database is saved in sqlite, but 79 // TODO(lzheng): It was reasonable when database is saved in sqlite, but
74 // there should be better ways to save chunk_id and list_id after we use 80 // there should be better ways to save chunk_id and list_id after we use
75 // SafeBrowsingStoreFile. 81 // SafeBrowsingStoreFile.
76 int GetListIdBit(const int encoded_chunk_id) { 82 int GetListIdBit(const int encoded_chunk_id) {
77 return encoded_chunk_id & 1; 83 return encoded_chunk_id & 1;
78 } 84 }
79 int DecodeChunkId(int encoded_chunk_id) { 85 int DecodeChunkId(int encoded_chunk_id) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type, 426 UMA_HISTOGRAM_ENUMERATION("SB2.DatabaseFailure", failure_type,
421 FAILURE_DATABASE_MAX); 427 FAILURE_DATABASE_MAX);
422 } 428 }
423 429
424 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew() 430 SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew()
425 : creation_loop_(MessageLoop::current()), 431 : creation_loop_(MessageLoop::current()),
426 browse_store_(new SafeBrowsingStoreFile), 432 browse_store_(new SafeBrowsingStoreFile),
427 download_store_(NULL), 433 download_store_(NULL),
428 csd_whitelist_store_(NULL), 434 csd_whitelist_store_(NULL),
429 download_whitelist_store_(NULL), 435 download_whitelist_store_(NULL),
436 csd_malware_ipmatch_killswitch_on_(false),
430 reset_factory_(this), 437 reset_factory_(this),
431 corruption_detected_(false), 438 corruption_detected_(false),
432 change_detected_(false) { 439 change_detected_(false) {
433 DCHECK(browse_store_.get()); 440 DCHECK(browse_store_.get());
434 DCHECK(!download_store_.get()); 441 DCHECK(!download_store_.get());
435 DCHECK(!csd_whitelist_store_.get()); 442 DCHECK(!csd_whitelist_store_.get());
436 DCHECK(!download_whitelist_store_.get()); 443 DCHECK(!download_whitelist_store_.get());
437 DCHECK(!extension_blacklist_store_.get()); 444 DCHECK(!extension_blacklist_store_.get());
438 } 445 }
439 446
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 505
499 if (csd_whitelist_store_.get()) { 506 if (csd_whitelist_store_.get()) {
500 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base); 507 csd_whitelist_filename_ = CsdWhitelistDBFilename(filename_base);
501 csd_whitelist_store_->Init( 508 csd_whitelist_store_->Init(
502 csd_whitelist_filename_, 509 csd_whitelist_filename_,
503 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 510 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
504 base::Unretained(this))); 511 base::Unretained(this)));
505 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value(); 512 DVLOG(1) << "Init csd whitelist store: " << csd_whitelist_filename_.value();
506 std::vector<SBAddFullHash> full_hashes; 513 std::vector<SBAddFullHash> full_hashes;
507 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) { 514 if (csd_whitelist_store_->GetAddFullHashes(&full_hashes)) {
508 LoadWhitelist(full_hashes, &csd_whitelist_); 515 LoadWhitelist(full_hashes, &csd_whitelist_, true);
509 } else { 516 } else {
510 WhitelistEverything(&csd_whitelist_); 517 WhitelistEverything(&csd_whitelist_);
511 } 518 }
512 } else { 519 } else {
513 WhitelistEverything(&csd_whitelist_); // Just to be safe. 520 WhitelistEverything(&csd_whitelist_); // Just to be safe.
514 } 521 }
515 522
516 if (download_whitelist_store_.get()) { 523 if (download_whitelist_store_.get()) {
517 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base); 524 download_whitelist_filename_ = DownloadWhitelistDBFilename(filename_base);
518 download_whitelist_store_->Init( 525 download_whitelist_store_->Init(
519 download_whitelist_filename_, 526 download_whitelist_filename_,
520 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase, 527 base::Bind(&SafeBrowsingDatabaseNew::HandleCorruptDatabase,
521 base::Unretained(this))); 528 base::Unretained(this)));
522 DVLOG(1) << "Init download whitelist store: " 529 DVLOG(1) << "Init download whitelist store: "
523 << download_whitelist_filename_.value(); 530 << download_whitelist_filename_.value();
524 std::vector<SBAddFullHash> full_hashes; 531 std::vector<SBAddFullHash> full_hashes;
525 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) { 532 if (download_whitelist_store_->GetAddFullHashes(&full_hashes)) {
526 LoadWhitelist(full_hashes, &download_whitelist_); 533 LoadWhitelist(full_hashes, &download_whitelist_, false);
527 } else { 534 } else {
528 WhitelistEverything(&download_whitelist_); 535 WhitelistEverything(&download_whitelist_);
529 } 536 }
530 } else { 537 } else {
531 WhitelistEverything(&download_whitelist_); // Just to be safe. 538 WhitelistEverything(&download_whitelist_); // Just to be safe.
532 } 539 }
533 540
534 if (extension_blacklist_store_.get()) { 541 if (extension_blacklist_store_.get()) {
535 extension_blacklist_filename_ = ExtensionBlacklistDBFilename(filename_base); 542 extension_blacklist_filename_ = ExtensionBlacklistDBFilename(filename_base);
536 extension_blacklist_store_->Init( 543 extension_blacklist_store_->Init(
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 download_filename_, 1101 download_filename_,
1095 download_store_.get(), 1102 download_store_.get(),
1096 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH); 1103 FAILURE_DOWNLOAD_DATABASE_UPDATE_FINISH);
1097 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes", 1104 UMA_HISTOGRAM_COUNTS("SB2.DownloadDatabaseKilobytes",
1098 static_cast<int>(size_bytes / 1024)); 1105 static_cast<int>(size_bytes / 1024));
1099 } 1106 }
1100 1107
1101 UpdateBrowseStore(); 1108 UpdateBrowseStore();
1102 UpdateWhitelistStore(csd_whitelist_filename_, 1109 UpdateWhitelistStore(csd_whitelist_filename_,
1103 csd_whitelist_store_.get(), 1110 csd_whitelist_store_.get(),
1104 &csd_whitelist_); 1111 &csd_whitelist_, true);
1105 UpdateWhitelistStore(download_whitelist_filename_, 1112 UpdateWhitelistStore(download_whitelist_filename_,
1106 download_whitelist_store_.get(), 1113 download_whitelist_store_.get(),
1107 &download_whitelist_); 1114 &download_whitelist_, false);
1108 1115
1109 if (extension_blacklist_store_) { 1116 if (extension_blacklist_store_) {
1110 int64 size_bytes = UpdateHashPrefixStore( 1117 int64 size_bytes = UpdateHashPrefixStore(
1111 extension_blacklist_filename_, 1118 extension_blacklist_filename_,
1112 extension_blacklist_store_.get(), 1119 extension_blacklist_store_.get(),
1113 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH); 1120 FAILURE_EXTENSION_BLACKLIST_UPDATE_FINISH);
1114 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes", 1121 UMA_HISTOGRAM_COUNTS("SB2.ExtensionBlacklistKilobytes",
1115 static_cast<int>(size_bytes / 1024)); 1122 static_cast<int>(size_bytes / 1024));
1116 } 1123 }
1117 } 1124 }
1118 1125
1119 void SafeBrowsingDatabaseNew::UpdateWhitelistStore( 1126 void SafeBrowsingDatabaseNew::UpdateWhitelistStore(
1120 const base::FilePath& store_filename, 1127 const base::FilePath& store_filename,
1121 SafeBrowsingStore* store, 1128 SafeBrowsingStore* store,
1122 SBWhitelist* whitelist) { 1129 SBWhitelist* whitelist,
1130 bool check_malware_killswitch) {
1123 if (!store) 1131 if (!store)
1124 return; 1132 return;
1125 1133
1126 // For the whitelists, we don't cache and save full hashes since all 1134 // For the whitelists, we don't cache and save full hashes since all
1127 // hashes are already full. 1135 // hashes are already full.
1128 std::vector<SBAddFullHash> empty_add_hashes; 1136 std::vector<SBAddFullHash> empty_add_hashes;
1129 1137
1130 // Not needed for the whitelists. 1138 // Not needed for the whitelists.
1131 std::set<SBPrefix> empty_miss_cache; 1139 std::set<SBPrefix> empty_miss_cache;
1132 1140
1133 // Note: prefixes will not be empty. The current data store implementation 1141 // Note: prefixes will not be empty. The current data store implementation
1134 // stores all full-length hashes as both full and prefix hashes. 1142 // stores all full-length hashes as both full and prefix hashes.
1135 SBAddPrefixes prefixes; 1143 SBAddPrefixes prefixes;
1136 std::vector<SBAddFullHash> full_hashes; 1144 std::vector<SBAddFullHash> full_hashes;
1137 if (!store->FinishUpdate(empty_add_hashes, empty_miss_cache, &prefixes, 1145 if (!store->FinishUpdate(empty_add_hashes, empty_miss_cache, &prefixes,
1138 &full_hashes)) { 1146 &full_hashes)) {
1139 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH); 1147 RecordFailure(FAILURE_WHITELIST_DATABASE_UPDATE_FINISH);
1140 WhitelistEverything(whitelist); 1148 WhitelistEverything(whitelist);
1141 return; 1149 return;
1142 } 1150 }
1143 1151
1144 #if defined(OS_MACOSX) 1152 #if defined(OS_MACOSX)
1145 base::mac::SetFileBackupExclusion(store_filename); 1153 base::mac::SetFileBackupExclusion(store_filename);
1146 #endif 1154 #endif
1147 1155
1148 LoadWhitelist(full_hashes, whitelist); 1156 LoadWhitelist(full_hashes, whitelist, check_malware_killswitch);
1149 } 1157 }
1150 1158
1151 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( 1159 int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore(
1152 const base::FilePath& store_filename, 1160 const base::FilePath& store_filename,
1153 SafeBrowsingStore* store, 1161 SafeBrowsingStore* store,
1154 FailureType failure_type) { 1162 FailureType failure_type) {
1155 // We don't cache and save full hashes. 1163 // We don't cache and save full hashes.
1156 std::vector<SBAddFullHash> empty_add_hashes; 1164 std::vector<SBAddFullHash> empty_add_hashes;
1157 1165
1158 // Backend lookup happens only if a prefix is in add list. 1166 // Backend lookup happens only if a prefix is in add list.
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 } 1398 }
1391 1399
1392 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { 1400 void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) {
1393 base::AutoLock locked(lookup_lock_); 1401 base::AutoLock locked(lookup_lock_);
1394 whitelist->second = true; 1402 whitelist->second = true;
1395 whitelist->first.clear(); 1403 whitelist->first.clear();
1396 } 1404 }
1397 1405
1398 void SafeBrowsingDatabaseNew::LoadWhitelist( 1406 void SafeBrowsingDatabaseNew::LoadWhitelist(
1399 const std::vector<SBAddFullHash>& full_hashes, 1407 const std::vector<SBAddFullHash>& full_hashes,
1400 SBWhitelist* whitelist) { 1408 SBWhitelist* whitelist,
1409 bool check_malware_killswitch) {
1401 DCHECK_EQ(creation_loop_, MessageLoop::current()); 1410 DCHECK_EQ(creation_loop_, MessageLoop::current());
1402 if (full_hashes.size() > kMaxWhitelistSize) { 1411 if (full_hashes.size() > kMaxWhitelistSize) {
1403 WhitelistEverything(whitelist); 1412 WhitelistEverything(whitelist);
1404 return; 1413 return;
1405 } 1414 }
1406 1415
1407 std::vector<SBFullHash> new_whitelist; 1416 std::vector<SBFullHash> new_whitelist;
1408 new_whitelist.reserve(full_hashes.size()); 1417 new_whitelist.reserve(full_hashes.size());
1409 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); 1418 for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin();
1410 it != full_hashes.end(); ++it) { 1419 it != full_hashes.end(); ++it) {
1411 new_whitelist.push_back(it->full_hash); 1420 new_whitelist.push_back(it->full_hash);
1412 } 1421 }
1413 std::sort(new_whitelist.begin(), new_whitelist.end()); 1422 std::sort(new_whitelist.begin(), new_whitelist.end());
1414 1423
1415 SBFullHash kill_switch; 1424 SBFullHash kill_switch;
1416 crypto::SHA256HashString(kWhitelistKillSwitchUrl, &kill_switch, 1425 crypto::SHA256HashString(kWhitelistKillSwitchUrl, &kill_switch,
1417 sizeof(kill_switch)); 1426 sizeof(kill_switch));
1418 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(), 1427 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
1419 kill_switch)) { 1428 kill_switch)) {
1420 // The kill switch is whitelisted hence we whitelist all URLs. 1429 // The kill switch is whitelisted hence we whitelist all URLs.
1421 WhitelistEverything(whitelist); 1430 WhitelistEverything(whitelist);
1422 } else { 1431 } else {
1423 base::AutoLock locked(lookup_lock_); 1432 base::AutoLock locked(lookup_lock_);
1424 whitelist->second = false; 1433 whitelist->second = false;
1425 whitelist->first.swap(new_whitelist); 1434 whitelist->first.swap(new_whitelist);
1426 } 1435 }
1436
1437 // The killswitch is only in csd_whitelist, not download_whitelist
1438 if (!check_malware_killswitch) {
mattm 2013/05/21 02:14:09 I tihnk it would be clearer to move the check into
kewang 2013/05/22 10:14:00 I think this is a good idea. changed to call Conta
1439 return;
1440 }
1441
1442 SBFullHash malware_kill_switch;
1443 crypto::SHA256HashString(kMalwareIPKillSwitchUrl, &malware_kill_switch,
1444 sizeof(malware_kill_switch));
1445 if (std::binary_search(new_whitelist.begin(), new_whitelist.end(),
mattm 2013/05/21 02:14:09 I think this is a bug, new_whitelist here will act
kewang 2013/05/22 10:14:00 removed this part totally.
1446 malware_kill_switch)) {
1447 // Turn on the malware IP matching kill switch
1448 base::AutoLock locked(lookup_lock_);
1449 csd_malware_ipmatch_killswitch_on_ = true;
1450 } else {
1451 // Turn off the malware IP matching kill switch
1452 base::AutoLock locked(lookup_lock_);
1453 csd_malware_ipmatch_killswitch_on_ = false;
1454 }
1427 } 1455 }
1456
1457
1458 bool SafeBrowsingDatabaseNew::MalwareIPMatchKillSwitchOn() {
1459 base::AutoLock locked(lookup_lock_);
1460 return csd_malware_ipmatch_killswitch_on_;
1461 };
OLDNEW
« no previous file with comments | « chrome/browser/safe_browsing/safe_browsing_database.h ('k') | chrome/browser/safe_browsing/safe_browsing_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698