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
3 // found in the LICENSE file.
5 #include "chrome/common/safe_browsing/download_protection_util.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
12 namespace safe_browsing
{
13 namespace download_protection_util
{
17 // This enum matches the SBClientDownloadExtensions enum in histograms.xml. If
18 // you are adding a value here, you should also add to the enum definition in
19 // histograms.xml. Additions only at the end just in front of EXTENSION_MAX,
21 enum SBClientDownloadExtensions
{
40 EXTENSION_OTHER
, // The "other" bucket. This is in the middle of the enum
41 // due to historical reasons.
93 EXTENSION_APPLICATION
,
177 // New values go above this one.
181 struct SafeBrowsingFiletype
{
182 const base::FilePath::CharType
* const extension
;
184 bool is_supported_binary
;
188 const SafeBrowsingFiletype kSafeBrowsingFileTypes
[] = {
189 // KEEP THIS LIST SORTED!
190 {FILE_PATH_LITERAL(".7z"), EXTENSION_7Z
, true, true},
191 {FILE_PATH_LITERAL(".ade"), EXTENSION_ADE
, true, false},
192 {FILE_PATH_LITERAL(".adp"), EXTENSION_ADP
, true, false},
193 {FILE_PATH_LITERAL(".apk"), EXTENSION_APK
, true, false},
194 {FILE_PATH_LITERAL(".app"), EXTENSION_APP
, true, false},
195 {FILE_PATH_LITERAL(".application"), EXTENSION_APPLICATION
, true, false},
196 {FILE_PATH_LITERAL(".appref-ms"), EXTENSION_APPREF_MS
, true, false},
197 {FILE_PATH_LITERAL(".arj"), EXTENSION_ARJ
, true, true},
198 {FILE_PATH_LITERAL(".asp"), EXTENSION_ASP
, true, false},
199 {FILE_PATH_LITERAL(".asx"), EXTENSION_ASX
, true, false},
200 {FILE_PATH_LITERAL(".bas"), EXTENSION_BAS
, true, false},
201 {FILE_PATH_LITERAL(".bash"), EXTENSION_BASH
, true, false},
202 {FILE_PATH_LITERAL(".bat"), EXTENSION_BAT
, true, false},
203 {FILE_PATH_LITERAL(".bz2"), EXTENSION_BZ2
, true, true},
204 {FILE_PATH_LITERAL(".bzip2"), EXTENSION_BZIP2
, true, true},
205 {FILE_PATH_LITERAL(".cab"), EXTENSION_CAB
, true, true},
206 {FILE_PATH_LITERAL(".cfg"), EXTENSION_CFG
, true, false},
207 {FILE_PATH_LITERAL(".chi"), EXTENSION_CHI
, true, false},
208 {FILE_PATH_LITERAL(".chm"), EXTENSION_CHM
, true, false},
209 {FILE_PATH_LITERAL(".class"), EXTENSION_CLASS
, true, false},
210 {FILE_PATH_LITERAL(".cmd"), EXTENSION_CMD
, true, false},
211 {FILE_PATH_LITERAL(".com"), EXTENSION_COM
, true, false},
212 {FILE_PATH_LITERAL(".command"), EXTENSION_COMMAND
, true, false},
213 {FILE_PATH_LITERAL(".cpio"), EXTENSION_CPIO
, true, true},
214 {FILE_PATH_LITERAL(".cpl"), EXTENSION_CPL
, true, false},
215 {FILE_PATH_LITERAL(".crt"), EXTENSION_CRT
, true, false},
216 {FILE_PATH_LITERAL(".crx"), EXTENSION_CRX
, true, false},
217 {FILE_PATH_LITERAL(".csh"), EXTENSION_CSH
, true, false},
218 {FILE_PATH_LITERAL(".deb"), EXTENSION_DEB
, true, false},
219 {FILE_PATH_LITERAL(".dex"), EXTENSION_DEX
, true, false},
220 {FILE_PATH_LITERAL(".dll"), EXTENSION_DLL
, true, false},
221 {FILE_PATH_LITERAL(".dmg"), EXTENSION_DMG
, true, false},
222 {FILE_PATH_LITERAL(".drv"), EXTENSION_DRV
, true, false},
223 {FILE_PATH_LITERAL(".efi"), EXTENSION_EFI
, true, false},
224 {FILE_PATH_LITERAL(".exe"), EXTENSION_EXE
, true, false},
225 {FILE_PATH_LITERAL(".fon"), EXTENSION_FON
, true, false},
226 {FILE_PATH_LITERAL(".fxp"), EXTENSION_FXP
, true, false},
227 {FILE_PATH_LITERAL(".gadget"), EXTENSION_GADGET
, true, false},
228 {FILE_PATH_LITERAL(".grp"), EXTENSION_GRP
, true, false},
229 {FILE_PATH_LITERAL(".gz"), EXTENSION_GZ
, true, true},
230 {FILE_PATH_LITERAL(".gzip"), EXTENSION_GZIP
, true, true},
231 {FILE_PATH_LITERAL(".hlp"), EXTENSION_HLP
, true, false},
232 {FILE_PATH_LITERAL(".hta"), EXTENSION_HTA
, true, false},
233 {FILE_PATH_LITERAL(".htt"), EXTENSION_HTT
, true, false},
234 {FILE_PATH_LITERAL(".inf"), EXTENSION_INF
, true, false},
235 {FILE_PATH_LITERAL(".ini"), EXTENSION_INI
, true, false},
236 {FILE_PATH_LITERAL(".ins"), EXTENSION_INS
, true, false},
237 {FILE_PATH_LITERAL(".isp"), EXTENSION_ISP
, true, false},
238 {FILE_PATH_LITERAL(".jar"), EXTENSION_JAR
, true, false},
239 {FILE_PATH_LITERAL(".jnlp"), EXTENSION_JNLP
, true, false},
240 {FILE_PATH_LITERAL(".js"), EXTENSION_JS
, true, false},
241 {FILE_PATH_LITERAL(".jse"), EXTENSION_JSE
, true, false},
242 {FILE_PATH_LITERAL(".ksh"), EXTENSION_KSH
, true, false},
243 {FILE_PATH_LITERAL(".lha"), EXTENSION_LHA
, true, true},
244 {FILE_PATH_LITERAL(".lnk"), EXTENSION_LNK
, true, false},
245 {FILE_PATH_LITERAL(".local"), EXTENSION_LOCAL
, true, false},
246 {FILE_PATH_LITERAL(".lzh"), EXTENSION_LZH
, true, true},
247 {FILE_PATH_LITERAL(".lzma"), EXTENSION_LZMA
, true, true},
248 {FILE_PATH_LITERAL(".mad"), EXTENSION_MAD
, true, false},
249 {FILE_PATH_LITERAL(".maf"), EXTENSION_MAF
, true, false},
250 {FILE_PATH_LITERAL(".mag"), EXTENSION_MAG
, true, false},
251 {FILE_PATH_LITERAL(".mam"), EXTENSION_MAM
, true, false},
252 {FILE_PATH_LITERAL(".manifest"), EXTENSION_MANIFEST
, true, false},
253 {FILE_PATH_LITERAL(".maq"), EXTENSION_MAQ
, true, false},
254 {FILE_PATH_LITERAL(".mar"), EXTENSION_MAR
, true, false},
255 {FILE_PATH_LITERAL(".mas"), EXTENSION_MAS
, true, false},
256 {FILE_PATH_LITERAL(".mat"), EXTENSION_MAT
, true, false},
257 {FILE_PATH_LITERAL(".mau"), EXTENSION_MAU
, true, false},
258 {FILE_PATH_LITERAL(".mav"), EXTENSION_MAV
, true, false},
259 {FILE_PATH_LITERAL(".maw"), EXTENSION_MAW
, true, false},
260 {FILE_PATH_LITERAL(".mda"), EXTENSION_MDA
, true, false},
261 {FILE_PATH_LITERAL(".mdb"), EXTENSION_MDB
, true, false},
262 {FILE_PATH_LITERAL(".mde"), EXTENSION_MDE
, true, false},
263 {FILE_PATH_LITERAL(".mdt"), EXTENSION_MDT
, true, false},
264 {FILE_PATH_LITERAL(".mdw"), EXTENSION_MDW
, true, false},
265 {FILE_PATH_LITERAL(".mdz"), EXTENSION_MDZ
, true, false},
266 {FILE_PATH_LITERAL(".mht"), EXTENSION_MHT
, true, false},
267 {FILE_PATH_LITERAL(".mhtml"), EXTENSION_MHTML
, true, false},
268 {FILE_PATH_LITERAL(".mmc"), EXTENSION_MMC
, true, false},
269 {FILE_PATH_LITERAL(".mof"), EXTENSION_MOF
, true, false},
270 {FILE_PATH_LITERAL(".msc"), EXTENSION_MSC
, true, false},
271 {FILE_PATH_LITERAL(".msh"), EXTENSION_MSH
, true, false},
272 {FILE_PATH_LITERAL(".msh1"), EXTENSION_MSH1
, true, false},
273 {FILE_PATH_LITERAL(".msh1xml"), EXTENSION_MSH1XML
, true, false},
274 {FILE_PATH_LITERAL(".msh2"), EXTENSION_MSH2
, true, false},
275 {FILE_PATH_LITERAL(".msh2xml"), EXTENSION_MSH2XML
, true, false},
276 {FILE_PATH_LITERAL(".mshxml"), EXTENSION_MSHXML
, true, false},
277 {FILE_PATH_LITERAL(".msi"), EXTENSION_MSI
, true, false},
278 {FILE_PATH_LITERAL(".msp"), EXTENSION_MSP
, true, false},
279 {FILE_PATH_LITERAL(".mst"), EXTENSION_MST
, true, false},
280 {FILE_PATH_LITERAL(".ocx"), EXTENSION_OCX
, true, false},
281 {FILE_PATH_LITERAL(".ops"), EXTENSION_OPS
, true, false},
282 {FILE_PATH_LITERAL(".osx"), EXTENSION_OSX
, true, false},
283 {FILE_PATH_LITERAL(".pcd"), EXTENSION_PCD
, true, false},
284 {FILE_PATH_LITERAL(".pif"), EXTENSION_PIF
, true, false},
285 {FILE_PATH_LITERAL(".pkg"), EXTENSION_PKG
, true, false},
286 {FILE_PATH_LITERAL(".pl"), EXTENSION_PL
, true, false},
287 {FILE_PATH_LITERAL(".plg"), EXTENSION_PLG
, true, false},
288 {FILE_PATH_LITERAL(".prf"), EXTENSION_PRF
, true, false},
289 {FILE_PATH_LITERAL(".prg"), EXTENSION_PRG
, true, false},
290 {FILE_PATH_LITERAL(".ps1"), EXTENSION_PS1
, true, false},
291 {FILE_PATH_LITERAL(".ps1xml"), EXTENSION_PS1XML
, true, false},
292 {FILE_PATH_LITERAL(".ps2"), EXTENSION_PS2
, true, false},
293 {FILE_PATH_LITERAL(".ps2xml"), EXTENSION_PS2XML
, true, false},
294 {FILE_PATH_LITERAL(".psc1"), EXTENSION_PSC1
, true, false},
295 {FILE_PATH_LITERAL(".psc2"), EXTENSION_PSC2
, true, false},
296 {FILE_PATH_LITERAL(".pst"), EXTENSION_PST
, true, false},
297 {FILE_PATH_LITERAL(".py"), EXTENSION_PY
, true, false},
298 {FILE_PATH_LITERAL(".pyc"), EXTENSION_PYC
, true, false},
299 {FILE_PATH_LITERAL(".pyw"), EXTENSION_PYW
, true, false},
300 {FILE_PATH_LITERAL(".rar"), EXTENSION_RAR
, true, true},
301 {FILE_PATH_LITERAL(".rb"), EXTENSION_RB
, true, false},
302 {FILE_PATH_LITERAL(".reg"), EXTENSION_REG
, true, false},
303 {FILE_PATH_LITERAL(".rpm"), EXTENSION_RPM
, true, false},
304 {FILE_PATH_LITERAL(".scf"), EXTENSION_SCF
, true, false},
305 {FILE_PATH_LITERAL(".scr"), EXTENSION_SCR
, true, false},
306 {FILE_PATH_LITERAL(".sct"), EXTENSION_SCT
, true, false},
307 {FILE_PATH_LITERAL(".sh"), EXTENSION_SH
, true, false},
308 {FILE_PATH_LITERAL(".shar"), EXTENSION_SHAR
, true, false},
309 {FILE_PATH_LITERAL(".shb"), EXTENSION_SHB
, true, false},
310 {FILE_PATH_LITERAL(".shs"), EXTENSION_SHS
, true, false},
311 {FILE_PATH_LITERAL(".spl"), EXTENSION_SPL
, true, false},
312 {FILE_PATH_LITERAL(".swf"), EXTENSION_SWF
, true, false},
313 {FILE_PATH_LITERAL(".sys"), EXTENSION_SYS
, true, false},
314 {FILE_PATH_LITERAL(".tar"), EXTENSION_TAR
, true, true},
315 {FILE_PATH_LITERAL(".taz"), EXTENSION_TAZ
, true, true},
316 {FILE_PATH_LITERAL(".tbz"), EXTENSION_TBZ
, true, true},
317 {FILE_PATH_LITERAL(".tbz2"), EXTENSION_TBZ2
, true, true},
318 {FILE_PATH_LITERAL(".tcsh"), EXTENSION_TCSH
, true, false},
319 {FILE_PATH_LITERAL(".tgz"), EXTENSION_TGZ
, true, true},
320 {FILE_PATH_LITERAL(".torrent"), EXTENSION_TORRENT
, true, false},
321 {FILE_PATH_LITERAL(".url"), EXTENSION_URL
, true, false},
322 {FILE_PATH_LITERAL(".vb"), EXTENSION_VB
, true, false},
323 {FILE_PATH_LITERAL(".vbe"), EXTENSION_VBE
, true, false},
324 {FILE_PATH_LITERAL(".vbs"), EXTENSION_VBS
, true, false},
325 {FILE_PATH_LITERAL(".vsd"), EXTENSION_VSD
, true, false},
326 {FILE_PATH_LITERAL(".vsmacros"), EXTENSION_VSMACROS
, true, false},
327 {FILE_PATH_LITERAL(".vss"), EXTENSION_VSS
, true, false},
328 {FILE_PATH_LITERAL(".vst"), EXTENSION_VST
, true, false},
329 {FILE_PATH_LITERAL(".vsw"), EXTENSION_VSW
, true, false},
330 {FILE_PATH_LITERAL(".website"), EXTENSION_WEBSITE
, true, false},
331 {FILE_PATH_LITERAL(".wim"), EXTENSION_WIM
, true, true},
332 {FILE_PATH_LITERAL(".ws"), EXTENSION_WS
, true, false},
333 {FILE_PATH_LITERAL(".wsc"), EXTENSION_WSC
, true, false},
334 {FILE_PATH_LITERAL(".wsf"), EXTENSION_WSF
, true, false},
335 {FILE_PATH_LITERAL(".wsh"), EXTENSION_WSH
, true, false},
336 {FILE_PATH_LITERAL(".xbap"), EXTENSION_XBAP
, true, false},
337 {FILE_PATH_LITERAL(".xnk"), EXTENSION_XNK
, true, false},
338 {FILE_PATH_LITERAL(".xz"), EXTENSION_XZ
, true, true},
339 {FILE_PATH_LITERAL(".z"), EXTENSION_Z
, true, true},
340 {FILE_PATH_LITERAL(".zip"), EXTENSION_ZIP
, true, true},
343 const SafeBrowsingFiletype
& GetFileType(const base::FilePath
& file
) {
344 static const SafeBrowsingFiletype kOther
= {
345 nullptr, EXTENSION_OTHER
, false, false
348 base::FilePath::StringType extension
= file
.FinalExtension();
349 SafeBrowsingFiletype needle
= {extension
.c_str()};
351 const auto begin
= kSafeBrowsingFileTypes
;
352 const auto end
= kSafeBrowsingFileTypes
+ arraysize(kSafeBrowsingFileTypes
);
353 const auto result
= std::lower_bound(
355 [](const SafeBrowsingFiletype
& left
, const SafeBrowsingFiletype
& right
) {
356 return base::FilePath::CompareLessIgnoreCase(left
.extension
,
360 !base::FilePath::CompareEqualIgnoreCase(needle
.extension
,
368 const int kSBClientDownloadExtensionsMax
= EXTENSION_MAX
;
370 bool IsArchiveFile(const base::FilePath
& file
) {
371 // List of interesting archive file formats in kSafeBrowsingFileTypes is by no
372 // means exhaustive, but are currently file types that Safe Browsing would
373 // like to see pings for due to the possibility of them being used as wrapper
374 // formats for malicious payloads.
375 return GetFileType(file
).is_archive
;
378 bool IsSupportedBinaryFile(const base::FilePath
& file
) {
379 return GetFileType(file
).is_supported_binary
;
382 ClientDownloadRequest::DownloadType
GetDownloadType(
383 const base::FilePath
& file
) {
384 DCHECK(IsSupportedBinaryFile(file
));
385 if (file
.MatchesExtension(FILE_PATH_LITERAL(".apk")))
386 return ClientDownloadRequest::ANDROID_APK
;
387 else if (file
.MatchesExtension(FILE_PATH_LITERAL(".crx")))
388 return ClientDownloadRequest::CHROME_EXTENSION
;
389 else if (file
.MatchesExtension(FILE_PATH_LITERAL(".zip")))
390 // DownloadProtectionService doesn't send a ClientDownloadRequest for ZIP
391 // files unless they contain either executables or archives. The resulting
392 // DownloadType is either ZIPPED_EXECUTABLE or ZIPPED_ARCHIVE respectively.
393 // This function will return ZIPPED_EXECUTABLE for ZIP files as a
394 // placeholder. The correct DownloadType will be determined based on the
395 // result of analyzing the ZIP file.
396 return ClientDownloadRequest::ZIPPED_EXECUTABLE
;
397 else if (file
.MatchesExtension(FILE_PATH_LITERAL(".dmg")) ||
398 file
.MatchesExtension(FILE_PATH_LITERAL(".pkg")) ||
399 file
.MatchesExtension(FILE_PATH_LITERAL(".osx")) ||
400 file
.MatchesExtension(FILE_PATH_LITERAL(".app")))
401 return ClientDownloadRequest::MAC_EXECUTABLE
;
402 else if (IsArchiveFile(file
))
403 return ClientDownloadRequest::ARCHIVE
;
404 return ClientDownloadRequest::WIN_EXECUTABLE
;
407 int GetSBClientDownloadExtensionValueForUMA(const base::FilePath
& file
) {
408 return GetFileType(file
).uma_value
;
411 } // namespace download_protection_util
412 } // namespace safe_browsing