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