Index: chrome/common/safe_browsing/download_protection_util.cc |
diff --git a/chrome/common/safe_browsing/download_protection_util.cc b/chrome/common/safe_browsing/download_protection_util.cc |
index 7fccf6fbed9eba05ea8a5719955e303df1250ae2..fd56472a0db63695637c0e11b00f023f52fb84cf 100644 |
--- a/chrome/common/safe_browsing/download_protection_util.cc |
+++ b/chrome/common/safe_browsing/download_protection_util.cc |
@@ -4,102 +4,203 @@ |
#include "chrome/common/safe_browsing/download_protection_util.h" |
+#include <algorithm> |
+ |
#include "base/files/file_path.h" |
#include "base/logging.h" |
namespace safe_browsing { |
namespace download_protection_util { |
-bool IsArchiveFile(const base::FilePath& file) { |
- // List of interesting archive file formats. These are by no means exhaustive, |
- // but are currently file types that Safe Browsing would like to see pings for |
- // due to the possibility of them being used as wrapper formats for malicious |
- // payloads. |
- const base::FilePath::CharType* kArchiveFileTypes[] = { |
- FILE_PATH_LITERAL(".zip"), |
- FILE_PATH_LITERAL(".rar"), |
- FILE_PATH_LITERAL(".7z"), |
- FILE_PATH_LITERAL(".cab"), |
- FILE_PATH_LITERAL(".xz"), |
- FILE_PATH_LITERAL(".gz"), |
- FILE_PATH_LITERAL(".tgz"), |
- FILE_PATH_LITERAL(".bz2"), |
- FILE_PATH_LITERAL(".tar"), |
- FILE_PATH_LITERAL(".arj"), |
- FILE_PATH_LITERAL(".lzh"), |
- FILE_PATH_LITERAL(".lha"), |
- FILE_PATH_LITERAL(".wim"), |
- FILE_PATH_LITERAL(".z"), |
- FILE_PATH_LITERAL(".lzma"), |
- FILE_PATH_LITERAL(".cpio"), |
+namespace { |
+ |
+// This enum matches the SBClientDownloadExtensions enum in histograms.xml. If |
+// you are adding a value here, you should also add to the enum definition in |
+// histograms.xml. Additions only at the end just in front of EXTENSION_MAX, |
+// natch. |
+enum SBClientDownloadExtensions { |
+ EXTENSION_EXE, |
+ EXTENSION_MSI, |
+ EXTENSION_CAB, |
+ EXTENSION_SYS, |
+ EXTENSION_SCR, |
+ EXTENSION_DRV, |
+ EXTENSION_BAT, |
+ EXTENSION_ZIP, |
+ EXTENSION_RAR, |
+ EXTENSION_DLL, |
+ EXTENSION_PIF, |
+ EXTENSION_COM, |
+ EXTENSION_JAR, |
+ EXTENSION_CLASS, |
+ EXTENSION_PDF, |
+ EXTENSION_VB, |
+ EXTENSION_REG, |
+ EXTENSION_GRP, |
+ EXTENSION_OTHER, // The "other" bucket. This is in the middle of the enum |
+ // due to historical reasons. |
+ EXTENSION_CRX, |
+ EXTENSION_APK, |
+ EXTENSION_DMG, |
+ EXTENSION_PKG, |
+ EXTENSION_TORRENT, |
+ EXTENSION_WEBSITE, |
+ EXTENSION_URL, |
+ EXTENSION_VBE, |
+ EXTENSION_VBS, |
+ EXTENSION_JS, |
+ EXTENSION_JSE, |
+ EXTENSION_MHT, |
+ EXTENSION_MHTML, |
+ EXTENSION_MSC, |
+ EXTENSION_MSP, |
+ EXTENSION_MST, |
+ EXTENSION_BAS, |
+ EXTENSION_HTA, |
+ EXTENSION_MSH, |
+ EXTENSION_MSH1, |
+ EXTENSION_MSH1XML, |
+ EXTENSION_MSH2, |
+ EXTENSION_MSH2XML, |
+ EXTENSION_MSHXML, |
+ EXTENSION_PS1, |
+ EXTENSION_PS1XML, |
+ EXTENSION_PS2, |
+ EXTENSION_PS2XML, |
+ EXTENSION_PSC1, |
+ EXTENSION_PSC2, |
+ EXTENSION_SCF, |
+ EXTENSION_SCT, |
+ EXTENSION_WSF, |
+ EXTENSION_7Z, |
+ EXTENSION_XZ, |
+ EXTENSION_GZ, |
+ EXTENSION_TGZ, |
+ EXTENSION_BZ2, |
+ EXTENSION_TAR, |
+ EXTENSION_ARJ, |
+ EXTENSION_LZH, |
+ EXTENSION_LHA, |
+ EXTENSION_WIM, |
+ EXTENSION_Z, |
+ EXTENSION_LZMA, |
+ EXTENSION_CPIO, |
+ EXTENSION_CMD, |
+ EXTENSION_APP, |
+ EXTENSION_OSX, |
+ |
+ // New values go above this one. |
+ EXTENSION_MAX |
+}; |
+ |
+struct SafeBrowsingFiletype { |
+ const base::FilePath::CharType* const extension; |
+ int uma_value; |
+ bool is_supported_binary; |
+ bool is_archive; |
+}; |
+ |
+const SafeBrowsingFiletype kSafeBrowsingFileTypes[] = { |
+ // KEEP THIS LIST SORTED! |
+ {FILE_PATH_LITERAL(".7z"), EXTENSION_7Z, false, true}, |
+ {FILE_PATH_LITERAL(".apk"), EXTENSION_APK, true, false}, |
+ {FILE_PATH_LITERAL(".app"), EXTENSION_APP, true, false}, |
+ {FILE_PATH_LITERAL(".arj"), EXTENSION_ARJ, false, true}, |
+ {FILE_PATH_LITERAL(".bas"), EXTENSION_BAS, true, false}, |
+ {FILE_PATH_LITERAL(".bat"), EXTENSION_BAT, true, false}, |
+ {FILE_PATH_LITERAL(".bz2"), EXTENSION_BZ2, false, true}, |
+ {FILE_PATH_LITERAL(".cab"), EXTENSION_CAB, false, true}, |
+ {FILE_PATH_LITERAL(".cmd"), EXTENSION_CMD, true, false}, |
+ {FILE_PATH_LITERAL(".com"), EXTENSION_COM, true, false}, |
+ {FILE_PATH_LITERAL(".cpio"), EXTENSION_CPIO, false, true}, |
+ {FILE_PATH_LITERAL(".crx"), EXTENSION_CRX, true, false}, |
+ {FILE_PATH_LITERAL(".dll"), EXTENSION_DLL, true, false}, |
+ {FILE_PATH_LITERAL(".dmg"), EXTENSION_DMG, true, false}, |
+ {FILE_PATH_LITERAL(".exe"), EXTENSION_EXE, true, false}, |
+ {FILE_PATH_LITERAL(".gz"), EXTENSION_GZ, false, true}, |
+ {FILE_PATH_LITERAL(".hta"), EXTENSION_HTA, true, false}, |
+ {FILE_PATH_LITERAL(".js"), EXTENSION_JS, true, false}, |
+ {FILE_PATH_LITERAL(".jse"), EXTENSION_JSE, true, false}, |
+ {FILE_PATH_LITERAL(".lha"), EXTENSION_LHA, false, true}, |
+ {FILE_PATH_LITERAL(".lzh"), EXTENSION_LZH, false, true}, |
+ {FILE_PATH_LITERAL(".lzma"), EXTENSION_LZMA, false, true}, |
+ {FILE_PATH_LITERAL(".mht"), EXTENSION_MHT, true, false}, |
+ {FILE_PATH_LITERAL(".mhtml"), EXTENSION_MHTML, true, false}, |
+ {FILE_PATH_LITERAL(".msc"), EXTENSION_MSC, true, false}, |
+ {FILE_PATH_LITERAL(".msh"), EXTENSION_MSH, true, false}, |
+ {FILE_PATH_LITERAL(".msh1"), EXTENSION_MSH1, true, false}, |
+ {FILE_PATH_LITERAL(".msh1xml"), EXTENSION_MSH1XML, true, false}, |
+ {FILE_PATH_LITERAL(".msh2"), EXTENSION_MSH2, true, false}, |
+ {FILE_PATH_LITERAL(".msh2xml"), EXTENSION_MSH2XML, true, false}, |
+ {FILE_PATH_LITERAL(".mshxml"), EXTENSION_MSHXML, true, false}, |
+ {FILE_PATH_LITERAL(".msi"), EXTENSION_MSI, true, false}, |
+ {FILE_PATH_LITERAL(".msp"), EXTENSION_MSP, true, false}, |
+ {FILE_PATH_LITERAL(".mst"), EXTENSION_MST, true, false}, |
+ {FILE_PATH_LITERAL(".osx"), EXTENSION_OSX, true, false}, |
+ {FILE_PATH_LITERAL(".pif"), EXTENSION_PIF, true, false}, |
+ {FILE_PATH_LITERAL(".pkg"), EXTENSION_PKG, true, false}, |
+ {FILE_PATH_LITERAL(".ps1"), EXTENSION_PS1, true, false}, |
+ {FILE_PATH_LITERAL(".ps1xml"), EXTENSION_PS1XML, true, false}, |
+ {FILE_PATH_LITERAL(".ps2"), EXTENSION_PS2, true, false}, |
+ {FILE_PATH_LITERAL(".ps2xml"), EXTENSION_PS2XML, true, false}, |
+ {FILE_PATH_LITERAL(".psc1"), EXTENSION_PSC1, true, false}, |
+ {FILE_PATH_LITERAL(".psc2"), EXTENSION_PSC2, true, false}, |
+ {FILE_PATH_LITERAL(".rar"), EXTENSION_RAR, false, true}, |
+ {FILE_PATH_LITERAL(".reg"), EXTENSION_REG, true, false}, |
+ {FILE_PATH_LITERAL(".scf"), EXTENSION_SCF, true, false}, |
+ {FILE_PATH_LITERAL(".scr"), EXTENSION_SCR, true, false}, |
+ {FILE_PATH_LITERAL(".sct"), EXTENSION_SCT, true, false}, |
+ {FILE_PATH_LITERAL(".tar"), EXTENSION_TAR, false, true}, |
+ {FILE_PATH_LITERAL(".tgz"), EXTENSION_TGZ, false, true}, |
+ {FILE_PATH_LITERAL(".url"), EXTENSION_URL, true, false}, |
+ {FILE_PATH_LITERAL(".vb"), EXTENSION_VB, true, false}, |
+ {FILE_PATH_LITERAL(".vbe"), EXTENSION_VBE, true, false}, |
+ {FILE_PATH_LITERAL(".vbs"), EXTENSION_VBS, true, false}, |
+ {FILE_PATH_LITERAL(".website"), EXTENSION_WEBSITE, true, false}, |
+ {FILE_PATH_LITERAL(".wim"), EXTENSION_WIM, false, true}, |
+ {FILE_PATH_LITERAL(".wsf"), EXTENSION_WSF, true, false}, |
+ {FILE_PATH_LITERAL(".xz"), EXTENSION_XZ, false, true}, |
+ {FILE_PATH_LITERAL(".z"), EXTENSION_Z, false, true}, |
+ {FILE_PATH_LITERAL(".zip"), EXTENSION_ZIP, true, true}, |
+}; |
+ |
+const SafeBrowsingFiletype& GetFileType(const base::FilePath& file) { |
+ static const SafeBrowsingFiletype kOther = { |
+ nullptr, EXTENSION_OTHER, false, false |
}; |
- for (const auto& extension : kArchiveFileTypes) { |
- if (file.MatchesExtension(extension)) |
- return true; |
- } |
- // TODO(mattm): should .dmg be checked here instead of IsSupportedBinaryFile? |
- return false; |
+ |
+ base::FilePath::StringType extension = file.FinalExtension(); |
+ SafeBrowsingFiletype needle = {extension.c_str()}; |
+ |
+ const auto begin = kSafeBrowsingFileTypes; |
+ const auto end = kSafeBrowsingFileTypes + arraysize(kSafeBrowsingFileTypes); |
+ const auto result = std::lower_bound( |
+ begin, end, needle, |
+ [](const SafeBrowsingFiletype& left, const SafeBrowsingFiletype& right) { |
+ return base::FilePath::CompareLessIgnoreCase(left.extension, |
+ right.extension); |
+ }); |
+ if (result == end || |
+ !base::FilePath::CompareEqualIgnoreCase(needle.extension, |
+ result->extension)) |
+ return kOther; |
+ return *result; |
} |
-bool IsSupportedBinaryFile(const base::FilePath& file) { |
- const base::FilePath::CharType* kSupportedBinaryFileTypes[] = { |
- // Executable extensions for MS Windows. |
- FILE_PATH_LITERAL(".cmd"), |
- FILE_PATH_LITERAL(".com"), |
- FILE_PATH_LITERAL(".dll"), |
- FILE_PATH_LITERAL(".exe"), |
- FILE_PATH_LITERAL(".msc"), |
- FILE_PATH_LITERAL(".msi"), |
- FILE_PATH_LITERAL(".msp"), |
- FILE_PATH_LITERAL(".mst"), |
- FILE_PATH_LITERAL(".pif"), |
- FILE_PATH_LITERAL(".scr"), |
- // Not binary, but still contain executable code, or can be used to launch |
- // other executables. |
- FILE_PATH_LITERAL(".bas"), |
- FILE_PATH_LITERAL(".bat"), |
- FILE_PATH_LITERAL(".hta"), |
- FILE_PATH_LITERAL(".js"), |
- FILE_PATH_LITERAL(".jse"), |
- FILE_PATH_LITERAL(".mht"), |
- FILE_PATH_LITERAL(".mhtml"), |
- FILE_PATH_LITERAL(".msh"), |
- FILE_PATH_LITERAL(".msh1"), |
- FILE_PATH_LITERAL(".msh1xml"), |
- FILE_PATH_LITERAL(".msh2"), |
- FILE_PATH_LITERAL(".msh2xml"), |
- FILE_PATH_LITERAL(".mshxml"), |
- FILE_PATH_LITERAL(".ps1"), |
- FILE_PATH_LITERAL(".ps1xml"), |
- FILE_PATH_LITERAL(".ps2"), |
- FILE_PATH_LITERAL(".ps2xml"), |
- FILE_PATH_LITERAL(".psc1"), |
- FILE_PATH_LITERAL(".psc2"), |
- FILE_PATH_LITERAL(".reg"), |
- FILE_PATH_LITERAL(".scf"), |
- FILE_PATH_LITERAL(".sct"), |
- FILE_PATH_LITERAL(".url"), |
- FILE_PATH_LITERAL(".vb"), |
- FILE_PATH_LITERAL(".vbe"), |
- FILE_PATH_LITERAL(".vbs"), |
- FILE_PATH_LITERAL(".website"), |
- FILE_PATH_LITERAL(".wsf"), |
- // Chrome extensions and android APKs are also reported. |
- FILE_PATH_LITERAL(".apk"), |
- FILE_PATH_LITERAL(".crx"), |
- // Mac extensions. |
- FILE_PATH_LITERAL(".app"), |
- FILE_PATH_LITERAL(".dmg"), |
- FILE_PATH_LITERAL(".osx"), |
- FILE_PATH_LITERAL(".pkg"), |
- }; |
- for (const auto& extension : kSupportedBinaryFileTypes) |
- if (file.MatchesExtension(extension)) |
- return true; |
+} // namespace |
+ |
+const int kSBClientDownloadExtensionsMax = EXTENSION_MAX; |
- // .zip files are examined for any executables or other archives they may |
- // contain. Currently no other archive formats are supported. |
- return file.MatchesExtension(FILE_PATH_LITERAL(".zip")); |
+bool IsArchiveFile(const base::FilePath& file) { |
+ // List of interesting archive file formats in kSafeBrowsingFileTypes is by no |
+ // means exhaustive, but are currently file types that Safe Browsing would |
+ // like to see pings for due to the possibility of them being used as wrapper |
+ // formats for malicious payloads. |
+ return GetFileType(file).is_archive; |
+} |
+ |
+bool IsSupportedBinaryFile(const base::FilePath& file) { |
+ return GetFileType(file).is_supported_binary; |
} |
ClientDownloadRequest::DownloadType GetDownloadType( |
@@ -125,5 +226,9 @@ ClientDownloadRequest::DownloadType GetDownloadType( |
return ClientDownloadRequest::WIN_EXECUTABLE; |
} |
+int GetSBClientDownloadExtensionValueForUMA(const base::FilePath& file) { |
+ return GetFileType(file).uma_value; |
+} |
+ |
} // namespace download_protection_util |
} // namespace safe_browsing |