Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/download_protection_service.h" | 5 #include "chrome/browser/safe_browsing/download_protection_service.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 #if defined(OS_MACOSX) | 69 #if defined(OS_MACOSX) |
| 70 #include "chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h" | 70 #include "chrome/browser/safe_browsing/sandboxed_dmg_analyzer_mac.h" |
| 71 #endif | 71 #endif |
| 72 | 72 |
| 73 using content::BrowserThread; | 73 using content::BrowserThread; |
| 74 | 74 |
| 75 namespace { | 75 namespace { |
| 76 static const int64_t kDownloadRequestTimeoutMs = 7000; | 76 static const int64_t kDownloadRequestTimeoutMs = 7000; |
| 77 // We sample 1% of whitelisted downloads to still send out download pings. | 77 // We sample 1% of whitelisted downloads to still send out download pings. |
| 78 static const double kWhitelistDownloadSampleRate = 0.01; | 78 static const double kWhitelistDownloadSampleRate = 0.01; |
| 79 | |
| 80 enum WhitelistType { | |
| 81 NO_WHITELIST_MATCH, | |
| 82 URL_WHITELIST, | |
| 83 SIGNATURE_WHITELIST, | |
| 84 WHITELIST_TYPE_MAX | |
| 85 }; | |
| 86 | |
| 87 static void RecordCountOfWhitelistedDownload(WhitelistType type) { | |
| 88 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckWhitelistResult", type, | |
| 89 WHITELIST_TYPE_MAX); | |
| 90 } | |
| 79 } // namespace | 91 } // namespace |
| 80 | 92 |
| 81 namespace safe_browsing { | 93 namespace safe_browsing { |
| 82 | 94 |
| 83 const char DownloadProtectionService::kDownloadRequestUrl[] = | 95 const char DownloadProtectionService::kDownloadRequestUrl[] = |
| 84 "https://sb-ssl.google.com/safebrowsing/clientreport/download"; | 96 "https://sb-ssl.google.com/safebrowsing/clientreport/download"; |
| 85 | 97 |
| 86 const void* const DownloadProtectionService::kDownloadPingTokenKey | 98 const void* const DownloadProtectionService::kDownloadPingTokenKey |
| 87 = &kDownloadPingTokenKey; | 99 = &kDownloadPingTokenKey; |
| 88 | 100 |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 746 } else { | 758 } else { |
| 747 PostFinishTask(UNKNOWN, REASON_ARCHIVE_WITHOUT_BINARIES); | 759 PostFinishTask(UNKNOWN, REASON_ARCHIVE_WITHOUT_BINARIES); |
| 748 return; | 760 return; |
| 749 } | 761 } |
| 750 } | 762 } |
| 751 | 763 |
| 752 OnFileFeatureExtractionDone(); | 764 OnFileFeatureExtractionDone(); |
| 753 } | 765 } |
| 754 #endif // defined(OS_MACOSX) | 766 #endif // defined(OS_MACOSX) |
| 755 | 767 |
| 756 enum WhitelistType { | 768 bool ShouldSampleWhitelistedDownload() { |
| 757 NO_WHITELIST_MATCH, | |
| 758 URL_WHITELIST, | |
| 759 SIGNATURE_WHITELIST, | |
| 760 WHITELIST_TYPE_MAX | |
| 761 }; | |
| 762 | |
| 763 static void RecordCountOfWhitelistedDownload(WhitelistType type) { | |
| 764 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.CheckWhitelistResult", | |
| 765 type, | |
| 766 WHITELIST_TYPE_MAX); | |
| 767 } | |
| 768 | |
| 769 virtual bool ShouldSampleWhitelistedDownload() { | |
| 770 // We currently sample 1% whitelisted downloads from users who opted | 769 // We currently sample 1% whitelisted downloads from users who opted |
| 771 // in extended reporting and are not in incognito mode. | 770 // in extended reporting and are not in incognito mode. |
| 772 return service_ && is_extended_reporting_ && !is_incognito_ && | 771 return service_ && is_extended_reporting_ && !is_incognito_ && |
| 773 base::RandDouble() < service_->whitelist_sample_rate(); | 772 base::RandDouble() < service_->whitelist_sample_rate(); |
| 774 } | 773 } |
| 775 | 774 |
| 776 void CheckWhitelists() { | 775 void CheckWhitelists() { |
| 777 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 776 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 778 | 777 |
| 779 if (!database_manager_.get()) { | 778 if (!database_manager_.get()) { |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1186 REQUEST_MALFORMED, | 1185 REQUEST_MALFORMED, |
| 1187 FETCH_FAILED, | 1186 FETCH_FAILED, |
| 1188 RESPONSE_MALFORMED, | 1187 RESPONSE_MALFORMED, |
| 1189 SUCCEEDED | 1188 SUCCEEDED |
| 1190 }; | 1189 }; |
| 1191 | 1190 |
| 1192 PPAPIDownloadRequest( | 1191 PPAPIDownloadRequest( |
| 1193 const GURL& requestor_url, | 1192 const GURL& requestor_url, |
| 1194 const base::FilePath& default_file_path, | 1193 const base::FilePath& default_file_path, |
| 1195 const std::vector<base::FilePath::StringType>& alternate_extensions, | 1194 const std::vector<base::FilePath::StringType>& alternate_extensions, |
| 1195 Profile* profile, | |
| 1196 const CheckDownloadCallback& callback, | 1196 const CheckDownloadCallback& callback, |
| 1197 DownloadProtectionService* service, | 1197 DownloadProtectionService* service, |
| 1198 scoped_refptr<SafeBrowsingDatabaseManager> database_manager) | 1198 scoped_refptr<SafeBrowsingDatabaseManager> database_manager) |
| 1199 : requestor_url_(requestor_url), | 1199 : requestor_url_(requestor_url), |
| 1200 default_file_path_(default_file_path), | 1200 default_file_path_(default_file_path), |
| 1201 alternate_extensions_(alternate_extensions), | 1201 alternate_extensions_(alternate_extensions), |
| 1202 profile_(profile), | |
|
asanka
2016/07/14 20:44:32
Note that DownloadProtectionService has not lifeti
Jialiu Lin
2016/07/14 21:35:40
Make sense. Thanks!
| |
| 1202 callback_(callback), | 1203 callback_(callback), |
| 1203 service_(service), | 1204 service_(service), |
| 1204 database_manager_(database_manager), | 1205 database_manager_(database_manager), |
| 1205 start_time_(base::TimeTicks::Now()), | 1206 start_time_(base::TimeTicks::Now()), |
| 1206 supported_path_( | 1207 supported_path_( |
| 1207 GetSupportedFilePath(default_file_path, alternate_extensions)), | 1208 GetSupportedFilePath(default_file_path, alternate_extensions)), |
| 1209 sample_url_whitelist_(false), | |
| 1208 weakptr_factory_(this) {} | 1210 weakptr_factory_(this) {} |
| 1209 | 1211 |
| 1210 ~PPAPIDownloadRequest() override { | 1212 ~PPAPIDownloadRequest() override { |
| 1211 if (fetcher_ && !callback_.is_null()) | 1213 if (fetcher_ && !callback_.is_null()) |
| 1212 Finish(RequestOutcome::REQUEST_DESTROYED, UNKNOWN); | 1214 Finish(RequestOutcome::REQUEST_DESTROYED, UNKNOWN); |
| 1213 } | 1215 } |
| 1214 | 1216 |
| 1215 // Start the process of checking the download request. The callback passed as | 1217 // Start the process of checking the download request. The callback passed as |
| 1216 // the |callback| parameter to the constructor will be invoked with the result | 1218 // the |callback| parameter to the constructor will be invoked with the result |
| 1217 // of the check at some point in the future. | 1219 // of the check at some point in the future. |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1248 service_->download_request_timeout_ms())); | 1250 service_->download_request_timeout_ms())); |
| 1249 | 1251 |
| 1250 BrowserThread::PostTask( | 1252 BrowserThread::PostTask( |
| 1251 BrowserThread::IO, FROM_HERE, | 1253 BrowserThread::IO, FROM_HERE, |
| 1252 base::Bind(&PPAPIDownloadRequest::CheckWhitelistsOnIOThread, | 1254 base::Bind(&PPAPIDownloadRequest::CheckWhitelistsOnIOThread, |
| 1253 requestor_url_, database_manager_, | 1255 requestor_url_, database_manager_, |
| 1254 weakptr_factory_.GetWeakPtr())); | 1256 weakptr_factory_.GetWeakPtr())); |
| 1255 } | 1257 } |
| 1256 | 1258 |
| 1257 private: | 1259 private: |
| 1260 bool ShouldSampleWhitelistedDownload() { | |
| 1261 // We currently sample 1% whitelisted downloads from users who opted | |
| 1262 // in extended reporting and are not in incognito mode. | |
| 1263 bool is_extended_reporting = | |
| 1264 profile_ && | |
| 1265 profile_->GetPrefs()->GetBoolean( | |
| 1266 prefs::kSafeBrowsingExtendedReportingEnabled); | |
| 1267 bool is_incognito = profile_ && profile_->IsOffTheRecord(); | |
| 1268 return service_ && !is_incognito && is_extended_reporting && | |
| 1269 base::RandDouble() < service_->whitelist_sample_rate(); | |
| 1270 } | |
| 1271 | |
| 1258 // Whitelist checking needs to the done on the IO thread. | 1272 // Whitelist checking needs to the done on the IO thread. |
| 1259 static void CheckWhitelistsOnIOThread( | 1273 static void CheckWhitelistsOnIOThread( |
| 1260 const GURL& requestor_url, | 1274 const GURL& requestor_url, |
| 1261 scoped_refptr<SafeBrowsingDatabaseManager> database_manager, | 1275 scoped_refptr<SafeBrowsingDatabaseManager> database_manager, |
| 1262 base::WeakPtr<PPAPIDownloadRequest> download_request) { | 1276 base::WeakPtr<PPAPIDownloadRequest> download_request) { |
| 1263 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 1277 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 1264 DVLOG(2) << " checking whitelists for requestor URL:" << requestor_url; | 1278 DVLOG(2) << " checking whitelists for requestor URL:" << requestor_url; |
| 1265 | 1279 |
| 1266 bool url_was_whitelisted = | 1280 bool url_was_whitelisted = |
| 1267 requestor_url.is_valid() && database_manager && | 1281 requestor_url.is_valid() && database_manager && |
| 1268 database_manager->MatchDownloadWhitelistUrl(requestor_url); | 1282 database_manager->MatchDownloadWhitelistUrl(requestor_url); |
| 1269 BrowserThread::PostTask( | 1283 BrowserThread::PostTask( |
| 1270 BrowserThread::UI, FROM_HERE, | 1284 BrowserThread::UI, FROM_HERE, |
| 1271 base::Bind(&PPAPIDownloadRequest::WhitelistCheckComplete, | 1285 base::Bind(&PPAPIDownloadRequest::WhitelistCheckComplete, |
| 1272 download_request, url_was_whitelisted)); | 1286 download_request, url_was_whitelisted)); |
| 1273 } | 1287 } |
| 1274 | 1288 |
| 1275 void WhitelistCheckComplete(bool was_on_whitelist) { | 1289 void WhitelistCheckComplete(bool was_on_whitelist) { |
| 1276 DVLOG(2) << __FUNCTION__ << " was_on_whitelist:" << was_on_whitelist; | 1290 DVLOG(2) << __FUNCTION__ << " was_on_whitelist:" << was_on_whitelist; |
| 1277 if (was_on_whitelist) { | 1291 if (was_on_whitelist) { |
| 1278 // TODO(asanka): Should sample whitelisted downloads based on | 1292 if (ShouldSampleWhitelistedDownload()) { |
| 1279 // service_->whitelist_sample_rate(). http://crbug.com/610924 | 1293 RecordCountOfWhitelistedDownload(URL_WHITELIST); |
| 1280 Finish(RequestOutcome::WHITELIST_HIT, SAFE); | 1294 sample_url_whitelist_ = true; |
| 1281 return; | 1295 } else { |
| 1296 Finish(RequestOutcome::WHITELIST_HIT, SAFE); | |
| 1297 return; | |
| 1298 } | |
| 1282 } | 1299 } |
| 1283 | 1300 |
| 1284 // Not on whitelist, so we are going to check with the SafeBrowsing | 1301 // Not on whitelist, so we are going to check with the SafeBrowsing |
| 1285 // backend. | 1302 // backend. |
| 1286 SendRequest(); | 1303 SendRequest(); |
| 1287 } | 1304 } |
| 1288 | 1305 |
| 1289 void SendRequest() { | 1306 void SendRequest() { |
| 1290 DVLOG(2) << __FUNCTION__; | 1307 DVLOG(2) << __FUNCTION__; |
| 1291 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 1308 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1292 | 1309 |
| 1293 ClientDownloadRequest request; | 1310 ClientDownloadRequest request; |
| 1294 request.set_download_type(ClientDownloadRequest::PPAPI_SAVE_REQUEST); | 1311 request.set_download_type(ClientDownloadRequest::PPAPI_SAVE_REQUEST); |
| 1295 ClientDownloadRequest::Resource* resource = request.add_resources(); | 1312 ClientDownloadRequest::Resource* resource = request.add_resources(); |
| 1296 resource->set_type(ClientDownloadRequest::PPAPI_DOCUMENT); | 1313 resource->set_type(ClientDownloadRequest::PPAPI_DOCUMENT); |
| 1297 resource->set_url(requestor_url_.spec()); | 1314 resource->set_url(requestor_url_.spec()); |
| 1298 request.set_url(requestor_url_.spec()); | 1315 request.set_url(requestor_url_.spec()); |
| 1299 request.set_file_basename(supported_path_.BaseName().AsUTF8Unsafe()); | 1316 request.set_file_basename(supported_path_.BaseName().AsUTF8Unsafe()); |
| 1300 request.set_length(0); | 1317 request.set_length(0); |
| 1301 request.mutable_digests()->set_md5(std::string()); | 1318 request.mutable_digests()->set_md5(std::string()); |
| 1319 request.set_skipped_url_whitelist(sample_url_whitelist_); | |
| 1320 // Download protection does not check certificate whitelist for PPAPI | |
| 1321 // downloads. | |
| 1322 request.set_skipped_certificate_whitelist(false); | |
| 1302 for (const auto& alternate_extension : alternate_extensions_) { | 1323 for (const auto& alternate_extension : alternate_extensions_) { |
| 1303 if (alternate_extension.empty()) | 1324 if (alternate_extension.empty()) |
| 1304 continue; | 1325 continue; |
| 1305 DCHECK_EQ(base::FilePath::kExtensionSeparator, alternate_extension[0]); | 1326 DCHECK_EQ(base::FilePath::kExtensionSeparator, alternate_extension[0]); |
| 1306 *(request.add_alternate_extensions()) = | 1327 *(request.add_alternate_extensions()) = |
| 1307 base::FilePath(alternate_extension).AsUTF8Unsafe(); | 1328 base::FilePath(alternate_extension).AsUTF8Unsafe(); |
| 1308 } | 1329 } |
| 1309 if (supported_path_ != default_file_path_) { | 1330 if (supported_path_ != default_file_path_) { |
| 1310 *(request.add_alternate_extensions()) = | 1331 *(request.add_alternate_extensions()) = |
| 1311 base::FilePath(default_file_path_.FinalExtension()).AsUTF8Unsafe(); | 1332 base::FilePath(default_file_path_.FinalExtension()).AsUTF8Unsafe(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1426 // URL of document that requested the PPAPI download. | 1447 // URL of document that requested the PPAPI download. |
| 1427 const GURL requestor_url_; | 1448 const GURL requestor_url_; |
| 1428 | 1449 |
| 1429 // Default download path requested by the PPAPI plugin. | 1450 // Default download path requested by the PPAPI plugin. |
| 1430 const base::FilePath default_file_path_; | 1451 const base::FilePath default_file_path_; |
| 1431 | 1452 |
| 1432 // List of alternate extensions provided by the PPAPI plugin. Each extension | 1453 // List of alternate extensions provided by the PPAPI plugin. Each extension |
| 1433 // must begin with a leading extension separator. | 1454 // must begin with a leading extension separator. |
| 1434 const std::vector<base::FilePath::StringType> alternate_extensions_; | 1455 const std::vector<base::FilePath::StringType> alternate_extensions_; |
| 1435 | 1456 |
| 1457 Profile* profile_; | |
| 1458 | |
| 1436 // Callback to invoke with the result of the PPAPI download request check. | 1459 // Callback to invoke with the result of the PPAPI download request check. |
| 1437 CheckDownloadCallback callback_; | 1460 CheckDownloadCallback callback_; |
| 1438 | 1461 |
| 1439 DownloadProtectionService* service_; | 1462 DownloadProtectionService* service_; |
| 1440 const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; | 1463 const scoped_refptr<SafeBrowsingDatabaseManager> database_manager_; |
| 1441 | 1464 |
| 1442 // Time request was started. | 1465 // Time request was started. |
| 1443 const base::TimeTicks start_time_; | 1466 const base::TimeTicks start_time_; |
| 1444 | 1467 |
| 1445 // A download path that is supported by SafeBrowsing. This is determined by | 1468 // A download path that is supported by SafeBrowsing. This is determined by |
| 1446 // invoking GetSupportedFilePath(). If non-empty, | 1469 // invoking GetSupportedFilePath(). If non-empty, |
| 1447 // IsCheckedBinaryFile(supported_path_) is always true. This | 1470 // IsCheckedBinaryFile(supported_path_) is always true. This |
| 1448 // path is therefore used as the download target when sending the SafeBrowsing | 1471 // path is therefore used as the download target when sending the SafeBrowsing |
| 1449 // ping. | 1472 // ping. |
| 1450 const base::FilePath supported_path_; | 1473 const base::FilePath supported_path_; |
| 1451 | 1474 |
| 1475 bool sample_url_whitelist_; | |
| 1476 | |
| 1452 base::WeakPtrFactory<PPAPIDownloadRequest> weakptr_factory_; | 1477 base::WeakPtrFactory<PPAPIDownloadRequest> weakptr_factory_; |
| 1453 | 1478 |
| 1454 DISALLOW_COPY_AND_ASSIGN(PPAPIDownloadRequest); | 1479 DISALLOW_COPY_AND_ASSIGN(PPAPIDownloadRequest); |
| 1455 }; | 1480 }; |
| 1456 | 1481 |
| 1457 DownloadProtectionService::DownloadProtectionService( | 1482 DownloadProtectionService::DownloadProtectionService( |
| 1458 SafeBrowsingService* sb_service) | 1483 SafeBrowsingService* sb_service) |
| 1459 : request_context_getter_(sb_service ? sb_service->url_request_context() | 1484 : request_context_getter_(sb_service ? sb_service->url_request_context() |
| 1460 : nullptr), | 1485 : nullptr), |
| 1461 enabled_(false), | 1486 enabled_(false), |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1547 // UNKNOWN types properly. http://crbug.com/581044 | 1572 // UNKNOWN types properly. http://crbug.com/581044 |
| 1548 return (CheckClientDownloadRequest::IsSupportedDownload( | 1573 return (CheckClientDownloadRequest::IsSupportedDownload( |
| 1549 item, target_path, &reason, &type) && | 1574 item, target_path, &reason, &type) && |
| 1550 (ClientDownloadRequest::CHROME_EXTENSION != type)); | 1575 (ClientDownloadRequest::CHROME_EXTENSION != type)); |
| 1551 } | 1576 } |
| 1552 | 1577 |
| 1553 void DownloadProtectionService::CheckPPAPIDownloadRequest( | 1578 void DownloadProtectionService::CheckPPAPIDownloadRequest( |
| 1554 const GURL& requestor_url, | 1579 const GURL& requestor_url, |
| 1555 const base::FilePath& default_file_path, | 1580 const base::FilePath& default_file_path, |
| 1556 const std::vector<base::FilePath::StringType>& alternate_extensions, | 1581 const std::vector<base::FilePath::StringType>& alternate_extensions, |
| 1582 Profile* profile, | |
| 1557 const CheckDownloadCallback& callback) { | 1583 const CheckDownloadCallback& callback) { |
| 1558 DVLOG(1) << __FUNCTION__ << " url:" << requestor_url | 1584 DVLOG(1) << __FUNCTION__ << " url:" << requestor_url |
| 1559 << " default_file_path:" << default_file_path.value(); | 1585 << " default_file_path:" << default_file_path.value(); |
| 1560 std::unique_ptr<PPAPIDownloadRequest> request(new PPAPIDownloadRequest( | 1586 std::unique_ptr<PPAPIDownloadRequest> request(new PPAPIDownloadRequest( |
| 1561 requestor_url, default_file_path, alternate_extensions, callback, this, | 1587 requestor_url, default_file_path, alternate_extensions, profile, callback, |
| 1562 database_manager_)); | 1588 this, database_manager_)); |
| 1563 PPAPIDownloadRequest* request_copy = request.get(); | 1589 PPAPIDownloadRequest* request_copy = request.get(); |
| 1564 auto insertion_result = ppapi_download_requests_.insert( | 1590 auto insertion_result = ppapi_download_requests_.insert( |
| 1565 std::make_pair(request_copy, std::move(request))); | 1591 std::make_pair(request_copy, std::move(request))); |
| 1566 DCHECK(insertion_result.second); | 1592 DCHECK(insertion_result.second); |
| 1567 insertion_result.first->second->Start(); | 1593 insertion_result.first->second->Start(); |
| 1568 } | 1594 } |
| 1569 | 1595 |
| 1570 DownloadProtectionService::ClientDownloadRequestSubscription | 1596 DownloadProtectionService::ClientDownloadRequestSubscription |
| 1571 DownloadProtectionService::RegisterClientDownloadRequestCallback( | 1597 DownloadProtectionService::RegisterClientDownloadRequestCallback( |
| 1572 const ClientDownloadRequestCallback& callback) { | 1598 const ClientDownloadRequestCallback& callback) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1718 GURL DownloadProtectionService::GetDownloadRequestUrl() { | 1744 GURL DownloadProtectionService::GetDownloadRequestUrl() { |
| 1719 GURL url(kDownloadRequestUrl); | 1745 GURL url(kDownloadRequestUrl); |
| 1720 std::string api_key = google_apis::GetAPIKey(); | 1746 std::string api_key = google_apis::GetAPIKey(); |
| 1721 if (!api_key.empty()) | 1747 if (!api_key.empty()) |
| 1722 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 1748 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
| 1723 | 1749 |
| 1724 return url; | 1750 return url; |
| 1725 } | 1751 } |
| 1726 | 1752 |
| 1727 } // namespace safe_browsing | 1753 } // namespace safe_browsing |
| OLD | NEW |