diff options
author | raymes <raymes@chromium.org> | 2014-11-25 18:27:56 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-26 02:28:44 +0000 |
commit | 3c02e4d34f7be4ea737688a1a011efb820a4ddd2 (patch) | |
tree | 633d320a328f8991a55c7febb4a30f3a84054f40 /extensions/common/csp_validator.cc | |
parent | 796d1b22d68b3865087954c34fc05e5bbffef9bd (diff) | |
download | chromium_src-3c02e4d34f7be4ea737688a1a011efb820a4ddd2.zip chromium_src-3c02e4d34f7be4ea737688a1a011efb820a4ddd2.tar.gz chromium_src-3c02e4d34f7be4ea737688a1a011efb820a4ddd2.tar.bz2 |
Only allow insecure object-src directives for whitelisted mime types
This CL only allows insecure object-src directives in the CSP of an extension if a set of whitelisted mime types are also specified in the CSP. This is to prevent plugins that aren't fully sandboxed from loading up arbitrary URLs in an extension and maliciously gaining control of the extension.
The set of plugins that are whitelisted should be those that are fully sandboxed.
Review URL: https://codereview.chromium.org/760513003
Cr-Commit-Position: refs/heads/master@{#305761}
Diffstat (limited to 'extensions/common/csp_validator.cc')
-rw-r--r-- | extensions/common/csp_validator.cc | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/extensions/common/csp_validator.cc b/extensions/common/csp_validator.cc index 3224ad6..6895b31 100644 --- a/extensions/common/csp_validator.cc +++ b/extensions/common/csp_validator.cc @@ -22,11 +22,20 @@ namespace { const char kDefaultSrc[] = "default-src"; const char kScriptSrc[] = "script-src"; const char kObjectSrc[] = "object-src"; +const char kPluginTypes[] = "plugin-types"; const char kSandboxDirectiveName[] = "sandbox"; const char kAllowSameOriginToken[] = "allow-same-origin"; const char kAllowTopNavigation[] = "allow-top-navigation"; +// This is the list of plugin types which are fully sandboxed and are safe to +// load up in an extension, regardless of the URL they are navigated to. +const char* const kSandboxedPluginTypes[] = { + "application/pdf", + "application/x-google-chrome-pdf", + "application/x-pnacl" +}; + struct DirectiveStatus { explicit DirectiveStatus(const char* name) : directive_name(name) @@ -156,6 +165,58 @@ bool UpdateStatus(const std::string& directive_name, return true; } +// Parses the plugin-types directive and returns the list of mime types +// specified in |plugin_types|. +bool ParsePluginTypes(const std::string& directive_name, + base::StringTokenizer& tokenizer, + std::vector<std::string>* plugin_types) { + DCHECK(plugin_types); + + if (directive_name != kPluginTypes || !plugin_types->empty()) + return false; + + while (tokenizer.GetNext()) { + std::string mime_type = tokenizer.token(); + base::StringToLowerASCII(&mime_type); + // Since we're comparing the mime types to a whitelist, we don't check them + // for strict validity right now. + plugin_types->push_back(mime_type); + } + + return true; +} + +// Returns true if the |plugin_type| is one of the fully sandboxed plugin types. +bool PluginTypeAllowed(const std::string& plugin_type) { + for (size_t i = 0; i < arraysize(kSandboxedPluginTypes); ++i) { + if (plugin_type == kSandboxedPluginTypes[i]) + return true; + } + return false; +} + +// Returns true if the policy is allowed to contain an insecure object-src +// directive. This requires OPTIONS_ALLOW_INSECURE_OBJECT_SRC to be specified +// as an option and the plugin-types that can be loaded must be restricted to +// the set specified in kSandboxedPluginTypes. +bool AllowedToHaveInsecureObjectSrc( + int options, + const std::vector<std::string>& plugin_types) { + if (!(options & OPTIONS_ALLOW_INSECURE_OBJECT_SRC)) + return false; + + // plugin-types must be specified. + if (plugin_types.empty()) + return false; + + for (const auto& plugin_type : plugin_types) { + if (!PluginTypeAllowed(plugin_type)) + return false; + } + + return true; +} + } // namespace bool ContentSecurityPolicyIsLegal(const std::string& policy) { @@ -177,6 +238,8 @@ bool ContentSecurityPolicyIsSecure(const std::string& policy, DirectiveStatus script_src_status(kScriptSrc); DirectiveStatus object_src_status(kObjectSrc); + std::vector<std::string> plugin_types; + for (size_t i = 0; i < directives.size(); ++i) { std::string& input = directives[i]; base::StringTokenizer tokenizer(input, " \t\r\n"); @@ -192,6 +255,8 @@ bool ContentSecurityPolicyIsSecure(const std::string& policy, continue; if (UpdateStatus(directive_name, tokenizer, &object_src_status, options)) continue; + if (ParsePluginTypes(directive_name, tokenizer, &plugin_types)) + continue; } if (script_src_status.seen_in_policy && !script_src_status.is_secure) @@ -200,7 +265,7 @@ bool ContentSecurityPolicyIsSecure(const std::string& policy, if (object_src_status.seen_in_policy && !object_src_status.is_secure) { // Note that this does not fully check the object-src source list for // validity but Blink will do this anyway. - if (!(options & OPTIONS_ALLOW_INSECURE_OBJECT_SRC)) + if (!AllowedToHaveInsecureObjectSrc(options, plugin_types)) return false; } |