Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // This file should not be build on Android but is currently getting built. | 5 // This file should not be build on Android but is currently getting built. |
| 6 // TODO(vakh): Fix that: http://crbug.com/621647 | 6 // TODO(vakh): Fix that: http://crbug.com/621647 |
| 7 | 7 |
| 8 #include "components/safe_browsing_db/v4_local_database_manager.h" | 8 #include "components/safe_browsing_db/v4_local_database_manager.h" |
| 9 | 9 |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 return ListInfos({ | 52 return ListInfos({ |
| 53 ListInfo(kSyncOnlyOnChromeBuilds, "CertCsdDownloadWhitelist.store", | 53 ListInfo(kSyncOnlyOnChromeBuilds, "CertCsdDownloadWhitelist.store", |
| 54 GetCertCsdDownloadWhitelistId(), SB_THREAT_TYPE_UNUSED), | 54 GetCertCsdDownloadWhitelistId(), SB_THREAT_TYPE_UNUSED), |
| 55 ListInfo(kSyncOnlyOnChromeBuilds, "ChromeFilenameClientIncident.store", | 55 ListInfo(kSyncOnlyOnChromeBuilds, "ChromeFilenameClientIncident.store", |
| 56 GetChromeFilenameClientIncidentId(), SB_THREAT_TYPE_UNUSED), | 56 GetChromeFilenameClientIncidentId(), SB_THREAT_TYPE_UNUSED), |
| 57 ListInfo(kSyncAlways, "IpMalware.store", GetIpMalwareId(), | 57 ListInfo(kSyncAlways, "IpMalware.store", GetIpMalwareId(), |
| 58 SB_THREAT_TYPE_UNUSED), | 58 SB_THREAT_TYPE_UNUSED), |
| 59 ListInfo(kSyncOnlyOnChromeBuilds, "UrlCsdDownloadWhitelist.store", | 59 ListInfo(kSyncOnlyOnChromeBuilds, "UrlCsdDownloadWhitelist.store", |
| 60 GetUrlCsdDownloadWhitelistId(), SB_THREAT_TYPE_UNUSED), | 60 GetUrlCsdDownloadWhitelistId(), SB_THREAT_TYPE_UNUSED), |
| 61 ListInfo(kSyncOnlyOnChromeBuilds, "UrlCsdWhitelist.store", | 61 ListInfo(kSyncOnlyOnChromeBuilds, "UrlCsdWhitelist.store", |
| 62 GetUrlCsdWhitelistId(), SB_THREAT_TYPE_UNUSED), | 62 GetUrlCsdWhitelistId(), SB_THREAT_TYPE_CSD_WHITELIST), |
| 63 ListInfo(kSyncAlways, "UrlSoceng.store", GetUrlSocEngId(), | 63 ListInfo(kSyncAlways, "UrlSoceng.store", GetUrlSocEngId(), |
| 64 SB_THREAT_TYPE_URL_PHISHING), | 64 SB_THREAT_TYPE_URL_PHISHING), |
| 65 ListInfo(kSyncAlways, "UrlMalware.store", GetUrlMalwareId(), | 65 ListInfo(kSyncAlways, "UrlMalware.store", GetUrlMalwareId(), |
| 66 SB_THREAT_TYPE_URL_MALWARE), | 66 SB_THREAT_TYPE_URL_MALWARE), |
| 67 ListInfo(kSyncAlways, "UrlUws.store", GetUrlUwsId(), | 67 ListInfo(kSyncAlways, "UrlUws.store", GetUrlUwsId(), |
| 68 SB_THREAT_TYPE_URL_UNWANTED), | 68 SB_THREAT_TYPE_URL_UNWANTED), |
| 69 ListInfo(kSyncAlways, "UrlMalBin.store", GetUrlMalBinId(), | 69 ListInfo(kSyncAlways, "UrlMalBin.store", GetUrlMalBinId(), |
| 70 SB_THREAT_TYPE_BINARY_MALWARE_URL), | 70 SB_THREAT_TYPE_BINARY_MALWARE_URL), |
| 71 ListInfo(kSyncAlways, "ChromeExtMalware.store", GetChromeExtMalwareId(), | 71 ListInfo(kSyncAlways, "ChromeExtMalware.store", GetChromeExtMalwareId(), |
| 72 SB_THREAT_TYPE_EXTENSION), | 72 SB_THREAT_TYPE_EXTENSION), |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 89 case MALWARE_THREAT: | 89 case MALWARE_THREAT: |
| 90 case SOCIAL_ENGINEERING_PUBLIC: | 90 case SOCIAL_ENGINEERING_PUBLIC: |
| 91 case MALICIOUS_BINARY: | 91 case MALICIOUS_BINARY: |
| 92 return 0; | 92 return 0; |
| 93 case UNWANTED_SOFTWARE: | 93 case UNWANTED_SOFTWARE: |
| 94 return 1; | 94 return 1; |
| 95 case API_ABUSE: | 95 case API_ABUSE: |
| 96 case CLIENT_INCIDENT: | 96 case CLIENT_INCIDENT: |
| 97 case SUBRESOURCE_FILTER: | 97 case SUBRESOURCE_FILTER: |
| 98 return 2; | 98 return 2; |
| 99 case CSD_WHITELIST: | |
| 100 return 3; | |
| 99 default: | 101 default: |
| 100 NOTREACHED() << "Unexpected ThreatType encountered: " | 102 NOTREACHED() << "Unexpected ThreatType encountered: " |
| 101 << list_id.threat_type(); | 103 << list_id.threat_type(); |
| 102 return kLeastSeverity; | 104 return kLeastSeverity; |
| 103 } | 105 } |
| 104 } | 106 } |
| 105 | 107 |
| 106 } // namespace | 108 } // namespace |
| 107 | 109 |
| 108 V4LocalDatabaseManager::PendingCheck::PendingCheck( | 110 V4LocalDatabaseManager::PendingCheck::PendingCheck( |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 return true; | 284 return true; |
| 283 } | 285 } |
| 284 | 286 |
| 285 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( | 287 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( |
| 286 client, ClientCallbackType::CHECK_URL_FOR_SUBRESOURCE_FILTER, | 288 client, ClientCallbackType::CHECK_URL_FOR_SUBRESOURCE_FILTER, |
| 287 stores_to_check, std::vector<GURL>(1, url)); | 289 stores_to_check, std::vector<GURL>(1, url)); |
| 288 | 290 |
| 289 return HandleCheck(std::move(check)); | 291 return HandleCheck(std::move(check)); |
| 290 } | 292 } |
| 291 | 293 |
| 294 AsyncMatch V4LocalDatabaseManager::CheckCsdWhitelistUrl(const GURL& url, | |
| 295 Client* client) { | |
| 296 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 297 | |
| 298 StoresToCheck stores_to_check({GetUrlCsdWhitelistId()}); | |
| 299 if (!AreAllStoresAvailableNow(stores_to_check) || !CanCheckUrl(url)) { | |
| 300 // Fail open: Whitelist everything. Otherwise we may run the | |
| 301 // CSD phishing/malware detector on popular domains and generate | |
| 302 // undue load on the client and server, or send Password Reputation | |
| 303 // requests on popular sites. This has the effect of disabling | |
| 304 // CSD phishing/malware detection and password reputation service | |
| 305 // until the store is first synced and/or loaded from disk. | |
| 306 return AsyncMatch::MATCH; | |
| 307 } | |
| 308 | |
| 309 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( | |
| 310 client, ClientCallbackType::CHECK_CSD_WHITELIST, stores_to_check, | |
| 311 std::vector<GURL>(1, url)); | |
| 312 | |
| 313 return HandleWhitelistCheck(std::move(check)); | |
| 314 } | |
| 315 | |
| 292 bool V4LocalDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) { | 316 bool V4LocalDatabaseManager::MatchCsdWhitelistUrl(const GURL& url) { |
| 293 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 317 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 294 | 318 |
| 295 StoresToCheck stores_to_check({GetUrlCsdWhitelistId()}); | 319 StoresToCheck stores_to_check({GetUrlCsdWhitelistId()}); |
| 296 if (!AreAllStoresAvailableNow(stores_to_check)) { | 320 if (!AreAllStoresAvailableNow(stores_to_check)) { |
| 297 // Fail open: Whitelist everything. Otherwise we may run the | 321 // Fail open: Whitelist everything. See CheckCsdWhitelistUrl. |
| 298 // CSD phishing/malware detector on popular domains and generate | |
| 299 // undue load on the client and server. This has the effect of disabling | |
| 300 // CSD phishing/malware detection until the store is first synced. | |
| 301 return true; | 322 return true; |
| 302 } | 323 } |
| 303 | 324 |
| 304 return HandleUrlSynchronously(url, stores_to_check); | 325 return HandleUrlSynchronously(url, stores_to_check); |
| 305 } | 326 } |
| 306 | 327 |
| 307 bool V4LocalDatabaseManager::MatchDownloadWhitelistString( | 328 bool V4LocalDatabaseManager::MatchDownloadWhitelistString( |
| 308 const std::string& str) { | 329 const std::string& str) { |
| 309 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 330 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 310 | 331 |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 547 const ListIdentifier& list_id) { | 568 const ListIdentifier& list_id) { |
| 548 auto it = std::find_if( | 569 auto it = std::find_if( |
| 549 std::begin(list_infos_), std::end(list_infos_), | 570 std::begin(list_infos_), std::end(list_infos_), |
| 550 [&list_id](ListInfo const& li) { return li.list_id() == list_id; }); | 571 [&list_id](ListInfo const& li) { return li.list_id() == list_id; }); |
| 551 DCHECK(list_infos_.end() != it); | 572 DCHECK(list_infos_.end() != it); |
| 552 DCHECK_NE(SB_THREAT_TYPE_SAFE, it->sb_threat_type()); | 573 DCHECK_NE(SB_THREAT_TYPE_SAFE, it->sb_threat_type()); |
| 553 DCHECK_NE(SB_THREAT_TYPE_UNUSED, it->sb_threat_type()); | 574 DCHECK_NE(SB_THREAT_TYPE_UNUSED, it->sb_threat_type()); |
| 554 return it->sb_threat_type(); | 575 return it->sb_threat_type(); |
| 555 } | 576 } |
| 556 | 577 |
| 578 AsyncMatch V4LocalDatabaseManager::HandleWhitelistCheck( | |
| 579 std::unique_ptr<PendingCheck> check) { | |
| 580 // We don't bother queuing whitelist checks since the DB will | |
| 581 // normally be available already -- whitelists are used after page load, | |
| 582 // and navigations are blocked until the DB is ready and dequeues checks. | |
| 583 // The caller should have already checked that the DB is ready. | |
| 584 DCHECK(v4_database_); | |
| 585 | |
| 586 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | |
| 587 if (!GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes)) { | |
| 588 return AsyncMatch::NO_MATCH; | |
| 589 } | |
| 590 | |
| 591 // Look for any full-length hash in the matches. If there is one, | |
| 592 // there's no need for a full-hash check. This saves bandwidth for | |
| 593 // very popular sites since they'll have full-length hashes locally. | |
| 594 // These loops will have exactly 1 entry most of the time. | |
| 595 for (const auto& entry : full_hash_to_store_and_hash_prefixes) { | |
| 596 for (const auto& store_and_prefix : entry.second) { | |
| 597 if (store_and_prefix.hash_prefix.size() == kMaxHashPrefixLength) | |
| 598 return AsyncMatch::MATCH; | |
| 599 } | |
| 600 } | |
| 601 | |
| 602 ScheduleFullHashCheck(std::move(check), full_hash_to_store_and_hash_prefixes); | |
| 603 return AsyncMatch::ASYNC; | |
| 604 } | |
| 605 | |
| 557 bool V4LocalDatabaseManager::HandleCheck(std::unique_ptr<PendingCheck> check) { | 606 bool V4LocalDatabaseManager::HandleCheck(std::unique_ptr<PendingCheck> check) { |
| 558 if (!v4_database_) { | 607 if (!v4_database_) { |
| 559 queued_checks_.push_back(std::move(check)); | 608 queued_checks_.push_back(std::move(check)); |
| 560 return false; | 609 return false; |
| 561 } | 610 } |
| 562 | 611 |
| 563 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; | 612 FullHashToStoreAndHashPrefixesMap full_hash_to_store_and_hash_prefixes; |
| 564 if (!GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes)) { | 613 if (!GetPrefixMatches(check, &full_hash_to_store_and_hash_prefixes)) { |
| 565 return true; | 614 return true; |
| 566 } | 615 } |
| 567 | 616 |
| 617 ScheduleFullHashCheck(std::move(check), full_hash_to_store_and_hash_prefixes); | |
| 618 return false; | |
| 619 } | |
| 620 | |
| 621 void V4LocalDatabaseManager::ScheduleFullHashCheck( | |
| 622 std::unique_ptr<PendingCheck> check, | |
| 623 const FullHashToStoreAndHashPrefixesMap& | |
| 624 full_hash_to_store_and_hash_prefixes) { | |
| 568 // Add check to pending_checks_ before scheduling PerformFullHashCheck so that | 625 // Add check to pending_checks_ before scheduling PerformFullHashCheck so that |
| 569 // even if the client calls CancelCheck before PerformFullHashCheck gets | 626 // even if the client calls CancelCheck before PerformFullHashCheck gets |
| 570 // called, the check can be found in pending_checks_. | 627 // called, the check can be found in pending_checks_. |
| 571 pending_checks_.insert(check.get()); | 628 pending_checks_.insert(check.get()); |
| 572 | 629 |
| 573 // Post on the IO thread to enforce async behavior. | 630 // Post on the IO thread to enforce async behavior. |
| 574 BrowserThread::PostTask( | 631 BrowserThread::PostTask( |
| 575 BrowserThread::IO, FROM_HERE, | 632 BrowserThread::IO, FROM_HERE, |
| 576 base::Bind(&V4LocalDatabaseManager::PerformFullHashCheck, | 633 base::Bind(&V4LocalDatabaseManager::PerformFullHashCheck, |
| 577 weak_factory_.GetWeakPtr(), base::Passed(std::move(check)), | 634 weak_factory_.GetWeakPtr(), base::Passed(std::move(check)), |
| 578 full_hash_to_store_and_hash_prefixes)); | 635 full_hash_to_store_and_hash_prefixes)); |
| 579 | |
| 580 return false; | |
| 581 } | 636 } |
| 582 | 637 |
| 583 bool V4LocalDatabaseManager::HandleHashSynchronously( | 638 bool V4LocalDatabaseManager::HandleHashSynchronously( |
| 584 const FullHash& hash, | 639 const FullHash& hash, |
| 585 const StoresToCheck& stores_to_check) { | 640 const StoresToCheck& stores_to_check) { |
| 586 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 641 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 587 | 642 |
| 588 std::set<FullHash> hashes{hash}; | 643 std::set<FullHash> hashes{hash}; |
| 589 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( | 644 std::unique_ptr<PendingCheck> check = base::MakeUnique<PendingCheck>( |
| 590 nullptr, ClientCallbackType::CHECK_OTHER, stores_to_check, hashes); | 645 nullptr, ClientCallbackType::CHECK_OTHER, stores_to_check, hashes); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 693 check->most_severe_threat_type); | 748 check->most_severe_threat_type); |
| 694 break; | 749 break; |
| 695 | 750 |
| 696 case ClientCallbackType::CHECK_RESOURCE_URL: | 751 case ClientCallbackType::CHECK_RESOURCE_URL: |
| 697 DCHECK_EQ(1u, check->urls.size()); | 752 DCHECK_EQ(1u, check->urls.size()); |
| 698 check->client->OnCheckResourceUrlResult(check->urls[0], | 753 check->client->OnCheckResourceUrlResult(check->urls[0], |
| 699 check->most_severe_threat_type, | 754 check->most_severe_threat_type, |
| 700 check->matching_full_hash); | 755 check->matching_full_hash); |
| 701 break; | 756 break; |
| 702 | 757 |
| 758 case ClientCallbackType::CHECK_CSD_WHITELIST: { | |
| 759 DCHECK_EQ(1u, check->urls.size()); | |
| 760 DCHECK(check->most_severe_threat_type == SB_THREAT_TYPE_SAFE || | |
| 761 check->most_severe_threat_type == SB_THREAT_TYPE_CSD_WHITELIST); | |
| 762 bool did_match_whitelist = | |
|
vakh (use Gerrit instead)
2017/05/24 16:01:17
would it be clearer to have it the other way:
boo
Nathan Parker
2017/05/31 23:40:11
yea, I think it is clearer, but I had it the other
| |
| 763 check->most_severe_threat_type != SB_THREAT_TYPE_SAFE; | |
| 764 check->client->OnCheckWhitelistUrlResult(did_match_whitelist); | |
| 765 break; | |
| 766 } | |
| 767 | |
| 703 case ClientCallbackType::CHECK_EXTENSION_IDS: { | 768 case ClientCallbackType::CHECK_EXTENSION_IDS: { |
| 704 DCHECK_EQ(check->full_hash_threat_types.size(), | 769 DCHECK_EQ(check->full_hash_threat_types.size(), |
| 705 check->full_hashes.size()); | 770 check->full_hashes.size()); |
| 706 std::set<FullHash> unsafe_extension_ids; | 771 std::set<FullHash> unsafe_extension_ids; |
| 707 for (size_t i = 0; i < check->full_hash_threat_types.size(); i++) { | 772 for (size_t i = 0; i < check->full_hash_threat_types.size(); i++) { |
| 708 if (check->full_hash_threat_types[i] == SB_THREAT_TYPE_EXTENSION) { | 773 if (check->full_hash_threat_types[i] == SB_THREAT_TYPE_EXTENSION) { |
| 709 unsafe_extension_ids.insert(check->full_hashes[i]); | 774 unsafe_extension_ids.insert(check->full_hashes[i]); |
| 710 } | 775 } |
| 711 } | 776 } |
| 712 check->client->OnCheckExtensionsResult(unsafe_extension_ids); | 777 check->client->OnCheckExtensionsResult(unsafe_extension_ids); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 v4_database_->AreAllStoresAvailable(stores_to_check); | 829 v4_database_->AreAllStoresAvailable(stores_to_check); |
| 765 } | 830 } |
| 766 | 831 |
| 767 bool V4LocalDatabaseManager::AreAnyStoresAvailableNow( | 832 bool V4LocalDatabaseManager::AreAnyStoresAvailableNow( |
| 768 const StoresToCheck& stores_to_check) const { | 833 const StoresToCheck& stores_to_check) const { |
| 769 return enabled_ && v4_database_ && | 834 return enabled_ && v4_database_ && |
| 770 v4_database_->AreAnyStoresAvailable(stores_to_check); | 835 v4_database_->AreAnyStoresAvailable(stores_to_check); |
| 771 } | 836 } |
| 772 | 837 |
| 773 } // namespace safe_browsing | 838 } // namespace safe_browsing |
| OLD | NEW |