summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 16:51:28 +0000
committerkalman@chromium.org <kalman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-29 16:51:28 +0000
commit7415e329ce844348328e54a99d36f31dc72d890c (patch)
tree40ea05abf21ef027f66c97f38c71925a3fbeacfb /chrome
parentdb64549243ff94833254385cbdd236ecf2d431c5 (diff)
downloadchromium_src-7415e329ce844348328e54a99d36f31dc72d890c.zip
chromium_src-7415e329ce844348328e54a99d36f31dc72d890c.tar.gz
chromium_src-7415e329ce844348328e54a99d36f31dc72d890c.tar.bz2
Merge 241969 "Add a BLESSED_WEB_PAGE extension JS context type t..."
> Add a BLESSED_WEB_PAGE extension JS context type to describe the context in > which hosted apps run. Currently they're running in BLESSED_EXTENSION which is > dangerous not to mention wrong. WEB_PAGE is also wrong because additional APIs > are available to hosted apps. > > The immediate need for this change is so that websites with hosted apps can > still use chrome.runtime.connect/sendMessage if they're connectable. As they're > currently classed as extension contexts the security checks are done as though > the messages originate from an extension. This CL doesn't quite fix the bug but > is half way there. > > BUG=326250 > R=koz@chromium.org,jochen@chromium.org > > Review URL: https://codereview.chromium.org/112293003 TBR=kalman@chromium.org Review URL: https://codereview.chromium.org/149523003 git-svn-id: svn://svn.chromium.org/chrome/branches/1750/src@247702 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc3
-rw-r--r--chrome/common/extensions/api/_api_features.json12
-rw-r--r--chrome/common/extensions/features/simple_feature.cc3
-rw-r--r--chrome/common/extensions/features/simple_feature_unittest.cc5
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc21
-rw-r--r--chrome/renderer/extensions/chrome_v8_context.cc1
-rw-r--r--chrome/renderer/extensions/dispatcher.cc27
-rw-r--r--chrome/renderer/extensions/dispatcher.h2
8 files changed, 55 insertions, 19 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 1365e4a..f648657 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -427,6 +427,9 @@ bool AllowHostedAppAPICall(const Extension& extension,
if (!extension.web_extent().MatchesURL(source_url))
return false;
+ // Note: Not BLESSED_WEB_PAGE_CONTEXT here because these component hosted app
+ // entities have traditionally been treated as blessed extensions, for better
+ // or worse.
Feature::Availability availability =
ExtensionAPI::GetSharedInstance()->IsAvailable(
function_name, &extension, Feature::BLESSED_EXTENSION_CONTEXT,
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index 62db5f7..eb87ca2 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -22,7 +22,11 @@
"channel": "stable",
"extension_types": ["hosted_app", "extension", "legacy_packaged_app"],
"contexts": [
- "blessed_extension", "unblessed_extension", "content_script", "web_page"
+ "blessed_extension",
+ "unblessed_extension",
+ "content_script",
+ "web_page",
+ "blessed_web_page"
],
"matches": [
"http://*/*", "https://*/*", "chrome-extension://*/*", "file://*/*"
@@ -237,9 +241,7 @@
"internal": true,
"channel": "stable",
"extension_types": ["platform_app", "extension"],
- "contexts": [
- "blessed_extension", "unblessed_extension", "content_script", "web_page"
- ],
+ "contexts": "all",
"matches": ["<all_urls>"]
},
"experimental.accessibility": {
@@ -709,7 +711,7 @@
// Hosted apps can use the webstore API from within a blessed context.
"channel": "stable",
"extension_types": ["hosted_app"],
- "contexts": ["blessed_extension", "web_page"],
+ "contexts": ["blessed_web_page", "web_page"],
// Any webpage can use the webstore API.
"matches": ["http://*/*", "https://*/*"]
},
diff --git a/chrome/common/extensions/features/simple_feature.cc b/chrome/common/extensions/features/simple_feature.cc
index b971ed6..01431ce 100644
--- a/chrome/common/extensions/features/simple_feature.cc
+++ b/chrome/common/extensions/features/simple_feature.cc
@@ -35,6 +35,7 @@ struct Mappings {
contexts["unblessed_extension"] = Feature::UNBLESSED_EXTENSION_CONTEXT;
contexts["content_script"] = Feature::CONTENT_SCRIPT_CONTEXT;
contexts["web_page"] = Feature::WEB_PAGE_CONTEXT;
+ contexts["blessed_web_page"] = Feature::BLESSED_WEB_PAGE_CONTEXT;
locations["component"] = Feature::COMPONENT_LOCATION;
@@ -197,6 +198,8 @@ std::string GetDisplayName(Feature::Context context) {
return "content script";
case Feature::WEB_PAGE_CONTEXT:
return "web page";
+ case Feature::BLESSED_WEB_PAGE_CONTEXT:
+ return "hosted app";
}
NOTREACHED();
return "";
diff --git a/chrome/common/extensions/features/simple_feature_unittest.cc b/chrome/common/extensions/features/simple_feature_unittest.cc
index b2ea868..38ba4af 100644
--- a/chrome/common/extensions/features/simple_feature_unittest.cc
+++ b/chrome/common/extensions/features/simple_feature_unittest.cc
@@ -430,10 +430,11 @@ TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
contexts->Append(new base::StringValue("unblessed_extension"));
contexts->Append(new base::StringValue("content_script"));
contexts->Append(new base::StringValue("web_page"));
+ contexts->Append(new base::StringValue("blessed_web_page"));
value->Set("contexts", contexts);
scoped_ptr<SimpleFeature> feature(new SimpleFeature());
feature->Parse(value.get());
- EXPECT_EQ(4u, feature->GetContexts()->size());
+ EXPECT_EQ(5u, feature->GetContexts()->size());
EXPECT_TRUE(
feature->GetContexts()->count(Feature::BLESSED_EXTENSION_CONTEXT));
EXPECT_TRUE(
@@ -442,6 +443,8 @@ TEST_F(ExtensionSimpleFeatureTest, ParseContexts) {
feature->GetContexts()->count(Feature::CONTENT_SCRIPT_CONTEXT));
EXPECT_TRUE(
feature->GetContexts()->count(Feature::WEB_PAGE_CONTEXT));
+ EXPECT_TRUE(
+ feature->GetContexts()->count(Feature::BLESSED_WEB_PAGE_CONTEXT));
value->SetString("contexts", "all");
scoped_ptr<SimpleFeature> feature2(new SimpleFeature());
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 2fa016e..72e04f0 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -991,11 +991,22 @@ bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
bool ChromeContentRendererClient::AllowPopup() {
extensions::ChromeV8Context* current_context =
extension_dispatcher_->v8_context_set().GetCurrent();
- return current_context && current_context->extension() &&
- (current_context->context_type() ==
- extensions::Feature::BLESSED_EXTENSION_CONTEXT ||
- current_context->context_type() ==
- extensions::Feature::CONTENT_SCRIPT_CONTEXT);
+ if (!current_context || !current_context->extension())
+ return false;
+ // See http://crbug.com/117446 for the subtlety of this check.
+ switch (current_context->context_type()) {
+ case extensions::Feature::UNSPECIFIED_CONTEXT:
+ case extensions::Feature::WEB_PAGE_CONTEXT:
+ case extensions::Feature::UNBLESSED_EXTENSION_CONTEXT:
+ return false;
+ case extensions::Feature::BLESSED_EXTENSION_CONTEXT:
+ case extensions::Feature::CONTENT_SCRIPT_CONTEXT:
+ return true;
+ case extensions::Feature::BLESSED_WEB_PAGE_CONTEXT:
+ return !current_context->web_frame()->parent();
+ }
+ NOTREACHED();
+ return false;
}
bool ChromeContentRendererClient::ShouldFork(WebFrame* frame,
diff --git a/chrome/renderer/extensions/chrome_v8_context.cc b/chrome/renderer/extensions/chrome_v8_context.cc
index bdeebd1..e6e8d18 100644
--- a/chrome/renderer/extensions/chrome_v8_context.cc
+++ b/chrome/renderer/extensions/chrome_v8_context.cc
@@ -123,6 +123,7 @@ std::string ChromeV8Context::GetContextTypeDescription() {
case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION";
case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT";
case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE";
+ case Feature::BLESSED_WEB_PAGE_CONTEXT: return "BLESSED_WEB_PAGE";
}
NOTREACHED();
return std::string();
diff --git a/chrome/renderer/extensions/dispatcher.cc b/chrome/renderer/extensions/dispatcher.cc
index 3a21e8e..bc3aad0 100644
--- a/chrome/renderer/extensions/dispatcher.cc
+++ b/chrome/renderer/extensions/dispatcher.cc
@@ -732,6 +732,7 @@ void Dispatcher::AddOrRemoveBindingsForContext(ChromeV8Context* context) {
}
case Feature::BLESSED_EXTENSION_CONTEXT:
+ case Feature::BLESSED_WEB_PAGE_CONTEXT:
case Feature::UNBLESSED_EXTENSION_CONTEXT:
case Feature::CONTENT_SCRIPT_CONTEXT: {
// Extension context; iterate through all the APIs and bind the available
@@ -1113,7 +1114,8 @@ void Dispatcher::DidCreateScriptContext(
}
Feature::Context context_type = ClassifyJavaScriptContext(
- extension_id, extension_group,
+ extension,
+ extension_group,
UserScriptSlave::GetDataSourceURLForFrame(frame),
frame->document().securityOrigin());
@@ -1528,13 +1530,13 @@ bool Dispatcher::IsSandboxedPage(const GURL& url) const {
}
Feature::Context Dispatcher::ClassifyJavaScriptContext(
- const std::string& extension_id,
+ const Extension* extension,
int extension_group,
const GURL& url,
const blink::WebSecurityOrigin& origin) {
DCHECK_GE(extension_group, 0);
if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
- return extensions_.Contains(extension_id) ?
+ return extension ? // TODO(kalman): when does this happen?
Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
}
@@ -1549,14 +1551,25 @@ Feature::Context Dispatcher::ClassifyJavaScriptContext(
if (IsSandboxedPage(url))
return Feature::WEB_PAGE_CONTEXT;
- if (IsExtensionActive(extension_id))
- return Feature::BLESSED_EXTENSION_CONTEXT;
+ if (extension && IsExtensionActive(extension->id())) {
+ // |extension| is active in this process, but it could be either a true
+ // extension process or within the extent of a hosted app. In the latter
+ // case this would usually be considered a (blessed) web page context,
+ // unless the extension in question is a component extension, in which case
+ // we cheat and call it blessed.
+ return (extension->is_hosted_app() &&
+ extension->location() != Manifest::COMPONENT) ?
+ Feature::BLESSED_WEB_PAGE_CONTEXT : Feature::BLESSED_EXTENSION_CONTEXT;
+ }
// TODO(kalman): This isUnique() check is wrong, it should be performed as
// part of IsSandboxedPage().
if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) {
- return extensions_.Contains(extension_id) ?
- Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
+ if (!extension) // TODO(kalman): when does this happen?
+ return Feature::UNSPECIFIED_CONTEXT;
+ return extension->is_hosted_app() ?
+ Feature::BLESSED_WEB_PAGE_CONTEXT :
+ Feature::UNBLESSED_EXTENSION_CONTEXT;
}
if (url.is_valid())
diff --git a/chrome/renderer/extensions/dispatcher.h b/chrome/renderer/extensions/dispatcher.h
index c0cf115..a111805 100644
--- a/chrome/renderer/extensions/dispatcher.h
+++ b/chrome/renderer/extensions/dispatcher.h
@@ -243,7 +243,7 @@ class Dispatcher : public content::RenderProcessObserver {
// Returns the Feature::Context type of context for a JavaScript context.
Feature::Context ClassifyJavaScriptContext(
- const std::string& extension_id,
+ const Extension* extension,
int extension_group,
const GURL& url,
const blink::WebSecurityOrigin& origin);