Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2010 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.
      4 
      5 #include <set>
      6 #include <string>
      7 
      8 #include "chrome/browser/download/download_extensions.h"
      9 
     10 #include "base/string_util.h"
     11 #include "net/base/mime_util.h"
     12 #include "net/base/net_util.h"
     13 
     14 namespace download_util {
     15 
     16 // For file extensions taken from mozilla:
     17 
     18 /* ***** BEGIN LICENSE BLOCK *****
     19  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
     20  *
     21  * The contents of this file are subject to the Mozilla Public License Version
     22  * 1.1 (the "License"); you may not use this file except in compliance with
     23  * the License. You may obtain a copy of the License at
     24  * http://www.mozilla.org/MPL/
     25  *
     26  * Software distributed under the License is distributed on an "AS IS" basis,
     27  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
     28  * for the specific language governing rights and limitations under the
     29  * License.
     30  *
     31  * The Original Code is Mozilla Communicator client code, released
     32  * March 31, 1998.
     33  *
     34  * The Initial Developer of the Original Code is
     35  * Netscape Communications Corporation.
     36  * Portions created by the Initial Developer are Copyright (C) 1998-1999
     37  * the Initial Developer. All Rights Reserved.
     38  *
     39  * Contributor(s):
     40  *   Doug Turner <dougt (at) netscape.com>
     41  *   Dean Tessman <dean_tessman (at) hotmail.com>
     42  *   Brodie Thiesfield <brofield (at) jellycan.com>
     43  *   Jungshik Shin <jshin (at) i18nl10n.com>
     44  *
     45  * Alternatively, the contents of this file may be used under the terms of
     46  * either of the GNU General Public License Version 2 or later (the "GPL"),
     47  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
     48  * in which case the provisions of the GPL or the LGPL are applicable instead
     49  * of those above. If you wish to allow use of your version of this file only
     50  * under the terms of either the GPL or the LGPL, and not to allow others to
     51  * use your version of this file under the terms of the MPL, indicate your
     52  * decision by deleting the provisions above and replace them with the notice
     53  * and other provisions required by the GPL or the LGPL. If you do not delete
     54  * the provisions above, a recipient may use your version of this file under
     55  * the terms of any one of the MPL, the GPL or the LGPL.
     56  *
     57  * ***** END LICENSE BLOCK ***** */
     58 
     59 static const struct Executables {
     60     const char* extension;
     61     DownloadDangerLevel level;
     62 } g_executables[] = {
     63   { "class", Dangerous },
     64   { "htm", AllowOnUserGesture },
     65   { "html", AllowOnUserGesture },
     66   { "jar", Dangerous },
     67   { "jnlp", Dangerous },
     68   { "pdf", AllowOnUserGesture },
     69   { "pdfxml", AllowOnUserGesture },
     70   { "mars", AllowOnUserGesture },
     71   { "fdf", AllowOnUserGesture },
     72   { "xfdf", AllowOnUserGesture },
     73   { "xdp", AllowOnUserGesture },
     74   { "xfd", AllowOnUserGesture },
     75   { "pl", AllowOnUserGesture },
     76   { "py", AllowOnUserGesture },
     77   { "rb", AllowOnUserGesture },
     78   { "shtm", AllowOnUserGesture },
     79   { "shtml", AllowOnUserGesture },
     80   { "svg", AllowOnUserGesture },
     81   { "swf", AllowOnUserGesture },
     82   { "xht", AllowOnUserGesture },
     83   { "xhtm", AllowOnUserGesture },
     84   { "xhtml", AllowOnUserGesture },
     85   { "xml", AllowOnUserGesture },
     86   { "xsl", AllowOnUserGesture },
     87   { "xslt", AllowOnUserGesture },
     88 #if defined(OS_WIN)
     89   { "ad", AllowOnUserGesture },
     90   { "ade", AllowOnUserGesture },
     91   { "adp", AllowOnUserGesture },
     92   { "app", AllowOnUserGesture },
     93   { "application", AllowOnUserGesture },
     94   { "asp", AllowOnUserGesture },
     95   { "asx", AllowOnUserGesture },
     96   { "bas", AllowOnUserGesture },
     97   { "bat", AllowOnUserGesture },
     98   { "chi", AllowOnUserGesture },
     99   { "chm", AllowOnUserGesture },
    100   { "cmd", AllowOnUserGesture },
    101   { "com", AllowOnUserGesture },
    102   { "cpl", AllowOnUserGesture },
    103   { "crt", AllowOnUserGesture },
    104   { "dll", Dangerous },
    105   { "drv", Dangerous },
    106   { "exe", AllowOnUserGesture },
    107   { "fxp", AllowOnUserGesture },
    108   { "grp", Dangerous },
    109   { "hlp", AllowOnUserGesture },
    110   { "hta", AllowOnUserGesture },
    111   { "htt", AllowOnUserGesture },
    112   { "inf", AllowOnUserGesture },
    113   { "ins", AllowOnUserGesture },
    114   { "isp", AllowOnUserGesture },
    115   { "js", AllowOnUserGesture },
    116   { "jse", AllowOnUserGesture },
    117   { "lnk", AllowOnUserGesture },
    118   { "mad", AllowOnUserGesture },
    119   { "maf", AllowOnUserGesture },
    120   { "mag", AllowOnUserGesture },
    121   { "mam", AllowOnUserGesture },
    122   { "maq", AllowOnUserGesture },
    123   { "mar", AllowOnUserGesture },
    124   { "mas", AllowOnUserGesture },
    125   { "mat", AllowOnUserGesture },
    126   { "mau", AllowOnUserGesture },
    127   { "mav", AllowOnUserGesture },
    128   { "maw", AllowOnUserGesture },
    129   { "mda", AllowOnUserGesture },
    130   { "mdb", AllowOnUserGesture },
    131   { "mde", AllowOnUserGesture },
    132   { "mdt", AllowOnUserGesture },
    133   { "mdw", AllowOnUserGesture },
    134   { "mdz", AllowOnUserGesture },
    135   { "mht", AllowOnUserGesture },
    136   { "mhtml", AllowOnUserGesture },
    137   { "mmc", AllowOnUserGesture },
    138   { "msc", AllowOnUserGesture },
    139   { "msh", AllowOnUserGesture },
    140   { "mshxml", AllowOnUserGesture },
    141   { "msi", AllowOnUserGesture },
    142   { "msp", AllowOnUserGesture },
    143   { "mst", AllowOnUserGesture },
    144   { "ocx", AllowOnUserGesture },
    145   { "ops", AllowOnUserGesture },
    146   { "pcd", AllowOnUserGesture },
    147   { "pif", AllowOnUserGesture },
    148   { "plg", AllowOnUserGesture },
    149   { "prf", AllowOnUserGesture },
    150   { "prg", AllowOnUserGesture },
    151   { "pst", AllowOnUserGesture },
    152   { "reg", AllowOnUserGesture },
    153   { "scf", AllowOnUserGesture },
    154   { "scr", AllowOnUserGesture },
    155   { "sct", AllowOnUserGesture },
    156   { "shb", AllowOnUserGesture },
    157   { "shs", AllowOnUserGesture },
    158   { "sys", Dangerous },
    159   { "url", AllowOnUserGesture },
    160   { "vb", AllowOnUserGesture },
    161   { "vbe", AllowOnUserGesture },
    162   { "vbs", AllowOnUserGesture },
    163   { "vsd", AllowOnUserGesture },
    164   { "vsmacros", AllowOnUserGesture },
    165   { "vss", AllowOnUserGesture },
    166   { "vst", AllowOnUserGesture },
    167   { "vsw", AllowOnUserGesture },
    168   { "ws", AllowOnUserGesture },
    169   { "wsc", AllowOnUserGesture },
    170   { "wsf", AllowOnUserGesture },
    171   { "wsh", AllowOnUserGesture },
    172   { "xbap", Dangerous },
    173 #elif defined(OS_MACOSX)
    174   // TODO(thakis): Figure out what makes sense here -- crbug.com/19096
    175   { "app", AllowOnUserGesture },
    176   { "dmg", AllowOnUserGesture },
    177 #elif defined(OS_POSIX)
    178   // TODO(estade): lengthen this list.
    179   { "bash", AllowOnUserGesture },
    180   { "csh", AllowOnUserGesture },
    181   { "deb", AllowOnUserGesture },
    182   { "exe", AllowOnUserGesture },
    183   { "ksh", AllowOnUserGesture },
    184   { "rpm", AllowOnUserGesture },
    185   { "sh", AllowOnUserGesture },
    186   { "tcsh", AllowOnUserGesture },
    187 #endif
    188 };
    189 
    190 DownloadDangerLevel GetFileDangerLevel(const FilePath& path) {
    191   return GetFileExtensionDangerLevel(path.Extension());
    192 }
    193 
    194 DownloadDangerLevel GetFileExtensionDangerLevel(
    195     const FilePath::StringType& extension) {
    196   if (extension.empty())
    197     return NotDangerous;
    198   if (!IsStringASCII(extension))
    199     return NotDangerous;
    200 #if defined(OS_WIN)
    201   std::string ascii_extension = WideToASCII(extension);
    202 #elif defined(OS_POSIX)
    203   std::string ascii_extension = extension;
    204 #endif
    205 
    206   // Strip out leading dot if it's still there
    207   if (ascii_extension[0] == FilePath::kExtensionSeparator)
    208     ascii_extension.erase(0, 1);
    209 
    210   for (size_t i = 0; i < arraysize(g_executables); ++i) {
    211     if (LowerCaseEqualsASCII(ascii_extension, g_executables[i].extension))
    212       return g_executables[i].level;
    213   }
    214   return NotDangerous;
    215 }
    216 
    217 bool IsFileSafe(const FilePath& path) {
    218   return GetFileDangerLevel(path) == NotDangerous;
    219 }
    220 
    221 static const char* kExecutableWhiteList[] = {
    222   // JavaScript is just as powerful as EXE.
    223   "text/javascript",
    224   "text/javascript;version=*",
    225   "text/html",
    226   // Registry files can cause critical changes to the MS OS behavior.
    227   // Addition of this mimetype also addresses bug 7337.
    228   "text/x-registry",
    229   "text/x-sh",
    230   // Some sites use binary/octet-stream to mean application/octet-stream.
    231   // See http://code.google.com/p/chromium/issues/detail?id=1573
    232   "binary/octet-stream"
    233 };
    234 
    235 static const char* kExecutableBlackList[] = {
    236   // These application types are not executable.
    237   "application/*+xml",
    238   "application/xml"
    239 };
    240 
    241 bool IsExecutableMimeType(const std::string& mime_type) {
    242   for (size_t i = 0; i < arraysize(kExecutableWhiteList); ++i) {
    243     if (net::MatchesMimeType(kExecutableWhiteList[i], mime_type))
    244       return true;
    245   }
    246   for (size_t i = 0; i < arraysize(kExecutableBlackList); ++i) {
    247     if (net::MatchesMimeType(kExecutableBlackList[i], mime_type))
    248       return false;
    249   }
    250   // We consider only other application types to be executable.
    251   return net::MatchesMimeType("application/*", mime_type);
    252 }
    253 
    254 
    255 }  // namespace download_util
    256