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