summaryrefslogtreecommitdiffstats
path: root/extensions/common/csp_validator.cc
diff options
context:
space:
mode:
authorraymes <raymes@chromium.org>2014-11-25 18:27:56 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-26 02:28:44 +0000
commit3c02e4d34f7be4ea737688a1a011efb820a4ddd2 (patch)
tree633d320a328f8991a55c7febb4a30f3a84054f40 /extensions/common/csp_validator.cc
parent796d1b22d68b3865087954c34fc05e5bbffef9bd (diff)
downloadchromium_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.cc67
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;
}