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 "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 FILE_PATH_LITERAL(".mshxml"), | 113 FILE_PATH_LITERAL(".mshxml"), |
114 FILE_PATH_LITERAL(".ps1"), | 114 FILE_PATH_LITERAL(".ps1"), |
115 FILE_PATH_LITERAL(".ps1xml"), | 115 FILE_PATH_LITERAL(".ps1xml"), |
116 FILE_PATH_LITERAL(".ps2"), | 116 FILE_PATH_LITERAL(".ps2"), |
117 FILE_PATH_LITERAL(".ps2xml"), | 117 FILE_PATH_LITERAL(".ps2xml"), |
118 FILE_PATH_LITERAL(".psc1"), | 118 FILE_PATH_LITERAL(".psc1"), |
119 FILE_PATH_LITERAL(".psc2"), | 119 FILE_PATH_LITERAL(".psc2"), |
120 FILE_PATH_LITERAL(".scf"), | 120 FILE_PATH_LITERAL(".scf"), |
121 FILE_PATH_LITERAL(".sct"), | 121 FILE_PATH_LITERAL(".sct"), |
122 FILE_PATH_LITERAL(".wsf"), | 122 FILE_PATH_LITERAL(".wsf"), |
| 123 FILE_PATH_LITERAL(".7z"), |
| 124 FILE_PATH_LITERAL(".xz"), |
| 125 FILE_PATH_LITERAL(".gz"), |
| 126 FILE_PATH_LITERAL(".tgz"), |
| 127 FILE_PATH_LITERAL(".bz2"), |
| 128 FILE_PATH_LITERAL(".tar"), |
| 129 FILE_PATH_LITERAL(".arj"), |
| 130 FILE_PATH_LITERAL(".lzh"), |
| 131 FILE_PATH_LITERAL(".lha"), |
| 132 FILE_PATH_LITERAL(".wim"), |
| 133 FILE_PATH_LITERAL(".z"), |
| 134 FILE_PATH_LITERAL(".lzma"), |
| 135 FILE_PATH_LITERAL(".cpio"), |
123 }; | 136 }; |
124 | 137 |
125 // UMA enumeration value for unrecognized file types. This is the array index of | 138 // UMA enumeration value for unrecognized file types. This is the array index of |
126 // the "Other" bucket in kDangerousFileTypes. | 139 // the "Other" bucket in kDangerousFileTypes. |
127 const int EXTENSION_OTHER = 18; | 140 const int EXTENSION_OTHER = 18; |
128 | 141 |
129 void RecordFileExtensionType(const base::FilePath& file) { | 142 // Maximum extension ID returned by GetExtensionTypeForUMA() + 1. |
| 143 const int EXTENSION_MAX = arraysize(kDangerousFileTypes); |
| 144 |
| 145 int GetExtensionTypeForUMA(const base::FilePath::StringType& extension) { |
130 DCHECK_EQ(static_cast<base::FilePath::CharType*>(nullptr), | 146 DCHECK_EQ(static_cast<base::FilePath::CharType*>(nullptr), |
131 kDangerousFileTypes[EXTENSION_OTHER]); | 147 kDangerousFileTypes[EXTENSION_OTHER]); |
| 148 DCHECK_EQ(0u, extension.find(base::FilePath::kExtensionSeparator)); |
| 149 DCHECK_EQ(extension, base::FilePath(extension).FinalExtension()); |
132 | 150 |
133 int extension_type = EXTENSION_OTHER; | 151 for (const auto& dangerous_extension : kDangerousFileTypes) { |
134 for (const auto& extension : kDangerousFileTypes) { | 152 if (dangerous_extension && |
135 if (extension && file.MatchesExtension(extension)) { | 153 base::FilePath::CompareEqualIgnoreCase(dangerous_extension, extension)) |
136 extension_type = &extension - kDangerousFileTypes; | 154 return &dangerous_extension - kDangerousFileTypes; |
137 break; | |
138 } | |
139 } | 155 } |
| 156 return EXTENSION_OTHER; |
| 157 } |
140 | 158 |
| 159 void RecordFileExtensionType(const base::FilePath& file) { |
141 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadExtensions", | 160 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.DownloadExtensions", |
142 extension_type, arraysize(kDangerousFileTypes)); | 161 GetExtensionTypeForUMA(file.FinalExtension()), |
| 162 EXTENSION_MAX); |
| 163 } |
| 164 |
| 165 void RecordArchivedArchiveFileExtensionType( |
| 166 const base::FilePath::StringType& extension) { |
| 167 UMA_HISTOGRAM_ENUMERATION("SBClientDownload.ArchivedArchiveExtensions", |
| 168 GetExtensionTypeForUMA(extension), EXTENSION_MAX); |
143 } | 169 } |
144 | 170 |
145 // Enumerate for histogramming purposes. | 171 // Enumerate for histogramming purposes. |
146 // DO NOT CHANGE THE ORDERING OF THESE VALUES (different histogram data will | 172 // DO NOT CHANGE THE ORDERING OF THESE VALUES (different histogram data will |
147 // be mixed together based on their values). | 173 // be mixed together based on their values). |
148 enum SBStatsType { | 174 enum SBStatsType { |
149 DOWNLOAD_URL_CHECKS_TOTAL, | 175 DOWNLOAD_URL_CHECKS_TOTAL, |
150 DOWNLOAD_URL_CHECKS_CANCELED, | 176 DOWNLOAD_URL_CHECKS_CANCELED, |
151 DOWNLOAD_URL_CHECKS_MALWARE, | 177 DOWNLOAD_URL_CHECKS_MALWARE, |
152 | 178 |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 ClientDownloadRequest::DownloadType* type) { | 521 ClientDownloadRequest::DownloadType* type) { |
496 if (item.GetUrlChain().empty()) { | 522 if (item.GetUrlChain().empty()) { |
497 *reason = REASON_EMPTY_URL_CHAIN; | 523 *reason = REASON_EMPTY_URL_CHAIN; |
498 return false; | 524 return false; |
499 } | 525 } |
500 const GURL& final_url = item.GetUrlChain().back(); | 526 const GURL& final_url = item.GetUrlChain().back(); |
501 if (!final_url.is_valid() || final_url.is_empty()) { | 527 if (!final_url.is_valid() || final_url.is_empty()) { |
502 *reason = REASON_INVALID_URL; | 528 *reason = REASON_INVALID_URL; |
503 return false; | 529 return false; |
504 } | 530 } |
505 if (!download_protection_util::IsBinaryFile(target_path)) { | 531 if (!download_protection_util::IsSupportedBinaryFile(target_path)) { |
506 *reason = REASON_NOT_BINARY_FILE; | 532 *reason = REASON_NOT_BINARY_FILE; |
507 return false; | 533 return false; |
508 } | 534 } |
509 if ((!final_url.IsStandard() && !final_url.SchemeIsBlob() && | 535 if ((!final_url.IsStandard() && !final_url.SchemeIsBlob() && |
510 !final_url.SchemeIs(url::kDataScheme)) || | 536 !final_url.SchemeIs(url::kDataScheme)) || |
511 final_url.SchemeIsFile()) { | 537 final_url.SchemeIsFile()) { |
512 *reason = REASON_UNSUPPORTED_URL_SCHEME; | 538 *reason = REASON_UNSUPPORTED_URL_SCHEME; |
513 return false; | 539 return false; |
514 } | 540 } |
515 *type = download_protection_util::GetDownloadType(target_path); | 541 *type = download_protection_util::GetDownloadType(target_path); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 // analyzer is refcounted, it might outlive the request. | 620 // analyzer is refcounted, it might outlive the request. |
595 analyzer_ = new SandboxedZipAnalyzer( | 621 analyzer_ = new SandboxedZipAnalyzer( |
596 item_->GetFullPath(), | 622 item_->GetFullPath(), |
597 base::Bind(&CheckClientDownloadRequest::OnZipAnalysisFinished, | 623 base::Bind(&CheckClientDownloadRequest::OnZipAnalysisFinished, |
598 weakptr_factory_.GetWeakPtr())); | 624 weakptr_factory_.GetWeakPtr())); |
599 analyzer_->Start(); | 625 analyzer_->Start(); |
600 } | 626 } |
601 | 627 |
602 void OnZipAnalysisFinished(const zip_analyzer::Results& results) { | 628 void OnZipAnalysisFinished(const zip_analyzer::Results& results) { |
603 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 629 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 630 DCHECK_EQ(ClientDownloadRequest::ZIPPED_EXECUTABLE, type_); |
604 if (!service_) | 631 if (!service_) |
605 return; | 632 return; |
606 if (results.success) { | 633 if (results.success) { |
607 zipped_executable_ = results.has_executable; | 634 zipped_executable_ = results.has_executable; |
608 archived_binary_.CopyFrom(results.archived_binary); | 635 archived_binary_.CopyFrom(results.archived_binary); |
609 DVLOG(1) << "Zip analysis finished for " << item_->GetFullPath().value() | 636 DVLOG(1) << "Zip analysis finished for " << item_->GetFullPath().value() |
610 << ", has_executable=" << results.has_executable | 637 << ", has_executable=" << results.has_executable |
611 << " has_archive=" << results.has_archive; | 638 << " has_archive=" << results.has_archive; |
612 } else { | 639 } else { |
613 DVLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); | 640 DVLOG(1) << "Zip analysis failed for " << item_->GetFullPath().value(); |
614 } | 641 } |
615 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasExecutable", | 642 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasExecutable", |
616 zipped_executable_); | 643 zipped_executable_); |
617 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasArchiveButNoExecutable", | 644 UMA_HISTOGRAM_BOOLEAN("SBClientDownload.ZipFileHasArchiveButNoExecutable", |
618 results.has_archive && !zipped_executable_); | 645 results.has_archive && !zipped_executable_); |
619 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractZipFeaturesTime", | 646 UMA_HISTOGRAM_TIMES("SBClientDownload.ExtractZipFeaturesTime", |
620 base::TimeTicks::Now() - zip_analysis_start_time_); | 647 base::TimeTicks::Now() - zip_analysis_start_time_); |
| 648 for (const auto& file_extension : results.archived_archive_filetypes) |
| 649 RecordArchivedArchiveFileExtensionType(file_extension); |
621 | 650 |
622 if (!zipped_executable_) { | 651 if (!zipped_executable_ && !results.has_archive) { |
623 PostFinishTask(UNKNOWN, REASON_ARCHIVE_WITHOUT_BINARIES); | 652 PostFinishTask(UNKNOWN, REASON_ARCHIVE_WITHOUT_BINARIES); |
624 return; | 653 return; |
625 } | 654 } |
| 655 |
| 656 if (!zipped_executable_ && results.has_archive) |
| 657 type_ = ClientDownloadRequest::ZIPPED_ARCHIVE; |
626 OnFileFeatureExtractionDone(); | 658 OnFileFeatureExtractionDone(); |
627 } | 659 } |
628 | 660 |
629 static void RecordCountOfSignedOrWhitelistedDownload() { | 661 static void RecordCountOfSignedOrWhitelistedDownload() { |
630 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); | 662 UMA_HISTOGRAM_COUNTS("SBClientDownload.SignedOrWhitelistedDownload", 1); |
631 } | 663 } |
632 | 664 |
633 void CheckWhitelists() { | 665 void CheckWhitelists() { |
634 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 666 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
635 | 667 |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 GURL DownloadProtectionService::GetDownloadRequestUrl() { | 1168 GURL DownloadProtectionService::GetDownloadRequestUrl() { |
1137 GURL url(kDownloadRequestUrl); | 1169 GURL url(kDownloadRequestUrl); |
1138 std::string api_key = google_apis::GetAPIKey(); | 1170 std::string api_key = google_apis::GetAPIKey(); |
1139 if (!api_key.empty()) | 1171 if (!api_key.empty()) |
1140 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); | 1172 url = url.Resolve("?key=" + net::EscapeQueryParamValue(api_key, true)); |
1141 | 1173 |
1142 return url; | 1174 return url; |
1143 } | 1175 } |
1144 | 1176 |
1145 } // namespace safe_browsing | 1177 } // namespace safe_browsing |
OLD | NEW |