• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • 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@netscape.com>
41  *   Dean Tessman <dean_tessman@hotmail.com>
42  *   Brodie Thiesfield <brofield@jellycan.com>
43  *   Jungshik Shin <jshin@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 
GetFileDangerLevel(const FilePath & path)190 DownloadDangerLevel GetFileDangerLevel(const FilePath& path) {
191   return GetFileExtensionDangerLevel(path.Extension());
192 }
193 
GetFileExtensionDangerLevel(const FilePath::StringType & extension)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 
IsFileSafe(const FilePath & path)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 
IsExecutableMimeType(const std::string & mime_type)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