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