Chromium Code Reviews| Index: extensions/common/csp_validator.cc |
| diff --git a/extensions/common/csp_validator.cc b/extensions/common/csp_validator.cc |
| index 3224ad6e1324d3348bb6d30be6372e2d982aa8a9..3fa0390fabda3d5487cc5736326a8b6225ca653b 100644 |
| --- a/extensions/common/csp_validator.cc |
| +++ b/extensions/common/csp_validator.cc |
| @@ -22,11 +22,19 @@ 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-pnacl" |
| +}; |
| + |
| struct DirectiveStatus { |
| explicit DirectiveStatus(const char* name) |
| : directive_name(name) |
| @@ -156,6 +164,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 (size_t i = 0; i < plugin_types.size(); ++i) { |
|
not at google - send to devlin
2014/11/25 17:08:46
Perhaps use newfangled for-loop syntax, if you lik
raymes
2014/11/25 22:31:16
Done.
|
| + if (!PluginTypeAllowed(plugin_types[i])) |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| } // namespace |
| bool ContentSecurityPolicyIsLegal(const std::string& policy) { |
| @@ -177,6 +237,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 +254,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 +264,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; |
| } |