Commit a47c8a2c authored by abarth@chromium.org's avatar abarth@chromium.org

Enable CSP by default for extensions with manifest_version >= 2.

Review URL: http://codereview.chromium.org/8585020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110531 0039d316-1c4b-4281-b951-d872f2087c98
parent d8e68201
// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -7,8 +7,12 @@ ...@@ -7,8 +7,12 @@
#include "net/base/mock_host_resolver.h" #include "net/base/mock_host_resolver.h"
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentSecurityPolicy) { IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentSecurityPolicy) {
CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kEnableExperimentalExtensionApis);
ASSERT_TRUE(StartTestServer()); ASSERT_TRUE(StartTestServer());
ASSERT_TRUE(RunExtensionTest("content_security_policy")) << message_; ASSERT_TRUE(RunExtensionTest("content_security_policy")) << message_;
} }
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DefaultContentSecurityPolicy) {
ASSERT_TRUE(StartTestServer());
ASSERT_TRUE(RunExtensionTest("default_content_security_policy")) <<
message_;
}
...@@ -63,6 +63,9 @@ const char kPrivate[] = "PRIVATE"; ...@@ -63,6 +63,9 @@ const char kPrivate[] = "PRIVATE";
const int kRSAKeySize = 1024; const int kRSAKeySize = 1024;
const char kDefaultContentSecurityPolicy[] =
"script-src 'self'; object-src 'self'";
// Converts a normal hexadecimal string into the alphabet used by extensions. // Converts a normal hexadecimal string into the alphabet used by extensions.
// We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a // We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a
// completely numeric host, since some software interprets that as an IP // completely numeric host, since some software interprets that as an IP
...@@ -1275,7 +1278,8 @@ bool Extension::IsTrustedId(const std::string& id) { ...@@ -1275,7 +1278,8 @@ bool Extension::IsTrustedId(const std::string& id) {
} }
Extension::Extension(const FilePath& path, Location location) Extension::Extension(const FilePath& path, Location location)
: incognito_split_mode_(false), : manifest_version_(0),
incognito_split_mode_(false),
offline_enabled_(false), offline_enabled_(false),
location_(location), location_(location),
converted_from_user_script_(false), converted_from_user_script_(false),
...@@ -1454,6 +1458,19 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags, ...@@ -1454,6 +1458,19 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags,
optional_permission_set_ = new ExtensionPermissionSet(); optional_permission_set_ = new ExtensionPermissionSet();
required_permission_set_ = new ExtensionPermissionSet(); required_permission_set_ = new ExtensionPermissionSet();
if (source.HasKey(keys::kManifestVersion)) {
int manifest_version = 0;
if (!source.GetInteger(keys::kManifestVersion, &manifest_version) ||
manifest_version < 1) {
*error = errors::kInvalidManifestVersion;
return false;
}
manifest_version_ = manifest_version;
} else {
// Version 1 was the original version, which lacked a version indicator.
manifest_version_ = 1;
}
if (source.HasKey(keys::kPublicKey)) { if (source.HasKey(keys::kPublicKey)) {
std::string public_key_bytes; std::string public_key_bytes;
if (!source.GetString(keys::kPublicKey, if (!source.GetString(keys::kPublicKey,
...@@ -2217,6 +2234,11 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags, ...@@ -2217,6 +2234,11 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags,
return false; return false;
} }
content_security_policy_ = content_security_policy; content_security_policy_ = content_security_policy;
} else if (manifest_version_ >= 2) {
// Manifest version 2 introduced a default Content-Security-Policy.
// TODO(abarth): Should we continue to let extensions override the
// default Content-Security-Policy?
content_security_policy_ = kDefaultContentSecurityPolicy;
} }
// Initialize devtools page url (optional). // Initialize devtools page url (optional).
......
...@@ -494,6 +494,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -494,6 +494,7 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
const std::string& public_key() const { return public_key_; } const std::string& public_key() const { return public_key_; }
const std::string& description() const { return description_; } const std::string& description() const { return description_; }
int manifest_version() const { return manifest_version_; }
bool converted_from_user_script() const { bool converted_from_user_script() const {
return converted_from_user_script_; return converted_from_user_script_;
} }
...@@ -714,6 +715,14 @@ class Extension : public base::RefCountedThreadSafe<Extension> { ...@@ -714,6 +715,14 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// The absolute path to the directory the extension is stored in. // The absolute path to the directory the extension is stored in.
FilePath path_; FilePath path_;
// The version of this extension's manifest. We increase the manifest
// version when making breaking changes to the extension system.
// Version 1 was the first manifest version (implied by a lack of a
// manifest_version attribute in the extension's manifest). We initialize
// this member variable to 0 to distinguish the "uninitialized" case from
// the case when we know the manifest version actually is 1.
int manifest_version_;
// Default locale for fall back. Can be empty if extension is not localized. // Default locale for fall back. Can be empty if extension is not localized.
std::string default_locale_; std::string default_locale_;
......
...@@ -53,6 +53,7 @@ const char* kLaunchLocalPath = "app.launch.local_path"; ...@@ -53,6 +53,7 @@ const char* kLaunchLocalPath = "app.launch.local_path";
const char* kLaunchWebURL = "app.launch.web_url"; const char* kLaunchWebURL = "app.launch.web_url";
const char* kLaunchWidth = "app.launch.width"; const char* kLaunchWidth = "app.launch.width";
const char* kLayouts = "layouts"; const char* kLayouts = "layouts";
const char* kManifestVersion = "manifest_version";
const char* kMatches = "matches"; const char* kMatches = "matches";
const char* kMinimumChromeVersion = "minimum_chrome_version"; const char* kMinimumChromeVersion = "minimum_chrome_version";
const char* kName = "name"; const char* kName = "name";
...@@ -271,6 +272,8 @@ const char* kInvalidLaunchWidthContainer = ...@@ -271,6 +272,8 @@ const char* kInvalidLaunchWidthContainer =
"Invalid container type for 'app.launch.width'."; "Invalid container type for 'app.launch.width'.";
const char* kInvalidManifest = const char* kInvalidManifest =
"Manifest file is invalid."; "Manifest file is invalid.";
const char* kInvalidManifestVersion =
"Invalid value for 'manifest_version'.";
const char* kInvalidMatch = const char* kInvalidMatch =
"Invalid value for 'content_scripts[*].matches[*]': *"; "Invalid value for 'content_scripts[*].matches[*]': *";
const char* kInvalidMatchCount = const char* kInvalidMatchCount =
......
...@@ -55,6 +55,7 @@ namespace extension_manifest_keys { ...@@ -55,6 +55,7 @@ namespace extension_manifest_keys {
extern const char* kLaunchWebURL; extern const char* kLaunchWebURL;
extern const char* kLaunchWidth; extern const char* kLaunchWidth;
extern const char* kLayouts; extern const char* kLayouts;
extern const char* kManifestVersion;
extern const char* kMatches; extern const char* kMatches;
extern const char* kMinimumChromeVersion; extern const char* kMinimumChromeVersion;
extern const char* kNaClModules; extern const char* kNaClModules;
...@@ -203,6 +204,7 @@ namespace extension_manifest_errors { ...@@ -203,6 +204,7 @@ namespace extension_manifest_errors {
extern const char* kInvalidLaunchWidth; extern const char* kInvalidLaunchWidth;
extern const char* kInvalidLaunchWidthContainer; extern const char* kInvalidLaunchWidthContainer;
extern const char* kInvalidManifest; extern const char* kInvalidManifest;
extern const char* kInvalidManifestVersion;
extern const char* kInvalidMatch; extern const char* kInvalidMatch;
extern const char* kInvalidMatchCount; extern const char* kInvalidMatchCount;
extern const char* kInvalidMatches; extern const char* kInvalidMatches;
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
window.externalCanary = "Alive"; window.externalCanary = "Alive";
chrome.test.getConfig(function(config) { chrome.test.getConfig(function(config) {
......
{
"name": "default content security policy tests",
"version": "0.1",
"manifest_version": 2,
"description": "Checks that extensions with version 2 manifests have a default Content-Security-Policy.",
"background_page": "test.html"
}
<script>
window.inlineCanary = "FAIL: This script should not run!";
</script>
<script src="test.js"></script>
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
window.externalCanary = "Alive";
chrome.test.getConfig(function(config) {
function inlineScriptDoesNotRun() {
chrome.test.assertEq(window.inlineCanary, undefined);
chrome.test.runNextTest();
}
function externalScriptDoesRun() {
// This test is somewhat zen in the sense that if external scripts are
// blocked, we don't be able to even execute the test harness...
chrome.test.assertEq(window.externalCanary, "Alive");
chrome.test.runNextTest();
}
chrome.test.runTests([
inlineScriptDoesNotRun,
externalScriptDoesRun
]);
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment