diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-02 18:39:55 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-02 18:39:55 +0000 |
commit | 1adff06dc95bd50ac0d6973be2316a3b08f46090 (patch) | |
tree | e3f394d8b1d37799f2b339f61cb10b23a08840fc | |
parent | 8616bbce6d475d10f4db846699dc19bc05f985fe (diff) | |
download | chromium_src-1adff06dc95bd50ac0d6973be2316a3b08f46090.zip chromium_src-1adff06dc95bd50ac0d6973be2316a3b08f46090.tar.gz chromium_src-1adff06dc95bd50ac0d6973be2316a3b08f46090.tar.bz2 |
Add some browser-level checks to prohibit access to extension bindings by
non-extension renderers. Also add a check so that bindings are only exposed
if the top-level frame is the chrome-extension scheme.
BUG=11545
BUG=11993
TEST=none
Review URL: http://codereview.chromium.org/119014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17408 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/child_process_security_policy.cc | 39 | ||||
-rw-r--r-- | chrome/browser/child_process_security_policy.h | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_message_service.cc | 7 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 14 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 4 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_proxy.cpp | 3 |
6 files changed, 65 insertions, 10 deletions
diff --git a/chrome/browser/child_process_security_policy.cc b/chrome/browser/child_process_security_policy.cc index 6a408bb1..b386e8e 100644 --- a/chrome/browser/child_process_security_policy.cc +++ b/chrome/browser/child_process_security_policy.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/stl_util-inl.h" #include "base/string_util.h" +#include "chrome/common/bindings_policy.h" #include "chrome/common/url_constants.h" #include "googleurl/src/gurl.h" #include "net/url_request/url_request.h" @@ -16,7 +17,7 @@ // information. class ChildProcessSecurityPolicy::SecurityState { public: - SecurityState() : has_dom_ui_bindings_(false) { } + SecurityState() : enabled_bindings_(0) { } ~SecurityState() { scheme_policy_.clear(); } @@ -36,8 +37,8 @@ class ChildProcessSecurityPolicy::SecurityState { uploadable_files_.insert(file); } - void GrantDOMUIBindings() { - has_dom_ui_bindings_ = true; + void GrantBindings(int bindings) { + enabled_bindings_ |= bindings; } // Determine whether permission has been granted to request url. @@ -57,7 +58,13 @@ class ChildProcessSecurityPolicy::SecurityState { return uploadable_files_.find(file) != uploadable_files_.end(); } - bool has_dom_ui_bindings() const { return has_dom_ui_bindings_; } + bool has_dom_ui_bindings() const { + return BindingsPolicy::is_dom_ui_enabled(enabled_bindings_); + } + + bool has_extension_bindings() const { + return BindingsPolicy::is_extension_enabled(enabled_bindings_); + } private: typedef std::map<std::string, bool> SchemeMap; @@ -73,7 +80,7 @@ class ChildProcessSecurityPolicy::SecurityState { // The set of files the renderer is permited to upload to the web. FileSet uploadable_files_; - bool has_dom_ui_bindings_; + int enabled_bindings_; DISALLOW_COPY_AND_ASSIGN(SecurityState); }; @@ -218,7 +225,7 @@ void ChildProcessSecurityPolicy::GrantDOMUIBindings(int renderer_id) { if (state == security_state_.end()) return; - state->second->GrantDOMUIBindings(); + state->second->GrantBindings(BindingsPolicy::DOM_UI); // DOM UI bindings need the ability to request chrome: URLs. state->second->GrantScheme(chrome::kChromeUIScheme); @@ -227,6 +234,16 @@ void ChildProcessSecurityPolicy::GrantDOMUIBindings(int renderer_id) { state->second->GrantScheme(chrome::kFileScheme); } +void ChildProcessSecurityPolicy::GrantExtensionBindings(int renderer_id) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return; + + state->second->GrantBindings(BindingsPolicy::EXTENSION); +} + bool ChildProcessSecurityPolicy::CanRequestURL(int renderer_id, const GURL& url) { if (!url.is_valid()) return false; // Can't request invalid URLs. @@ -288,3 +305,13 @@ bool ChildProcessSecurityPolicy::HasDOMUIBindings(int renderer_id) { return state->second->has_dom_ui_bindings(); } + +bool ChildProcessSecurityPolicy::HasExtensionBindings(int renderer_id) { + AutoLock lock(lock_); + + SecurityStateMap::iterator state = security_state_.find(renderer_id); + if (state == security_state_.end()) + return false; + + return state->second->has_extension_bindings(); +} diff --git a/chrome/browser/child_process_security_policy.h b/chrome/browser/child_process_security_policy.h index ae1eb41..22db422 100644 --- a/chrome/browser/child_process_security_policy.h +++ b/chrome/browser/child_process_security_policy.h @@ -78,6 +78,9 @@ class ChildProcessSecurityPolicy { // Grant this renderer the ability to use DOM UI Bindings. void GrantDOMUIBindings(int renderer_id); + // Grant this renderer the ability to use extension Bindings. + void GrantExtensionBindings(int renderer_id); + // Before servicing a renderer's request for a URL, the browser should call // this method to determine whether the renderer has the capability to // request the URL. @@ -93,6 +96,11 @@ class ChildProcessSecurityPolicy { // allowed to use DOMUIBindings. bool HasDOMUIBindings(int renderer_id); + // Returns true of the specified renderer_id has been granted DOMUIBindings. + // The browser should check this property before assuming the renderer is + // allowed to use extension bindings. + bool HasExtensionBindings(int renderer_id); + private: friend class ChildProcessSecurityPolicyInProcessBrowserTest; FRIEND_TEST(ChildProcessSecurityPolicyInProcessBrowserTest, NoLeak); diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 9096e0a..4b7ba14 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -8,6 +8,7 @@ #include "base/singleton.h" #include "base/stl_util-inl.h" #include "base/values.h" +#include "chrome/browser/child_process_security_policy.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extension_view.h" @@ -275,6 +276,12 @@ void ExtensionMessageService::DispatchEventToRenderers( RenderProcessHost* renderer = RenderProcessHost::FromID(*pid); if (!renderer) continue; + if (!ChildProcessSecurityPolicy::GetInstance()-> + HasExtensionBindings(*pid)) { + // Don't send browser-level events to unprivileged processes. + continue; + } + renderer->Send(new ViewMsg_ExtensionHandleEvent(event_name, event_args)); } } diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 826ca6d..1e3e031 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -145,11 +145,16 @@ bool RenderViewHost::CreateRenderView() { DCHECK(process()->channel()); DCHECK(process()->profile()); - if (enabled_bindings_ & BindingsPolicy::DOM_UI) { + if (BindingsPolicy::is_dom_ui_enabled(enabled_bindings_)) { ChildProcessSecurityPolicy::GetInstance()->GrantDOMUIBindings( process()->pid()); } + if (BindingsPolicy::is_extension_enabled(enabled_bindings_)) { + ChildProcessSecurityPolicy::GetInstance()->GrantExtensionBindings( + process()->pid()); + } + renderer_initialized_ = true; #if defined(OS_WIN) @@ -1424,8 +1429,11 @@ void RenderViewHost::OnExtensionRequest(const std::string& name, const std::string& args, int request_id, bool has_callback) { - // TODO(aa): Here is where we can check that this renderer was supposed to be - // able to call extension APIs. + if (!BindingsPolicy::is_extension_enabled(enabled_bindings_)) { + NOTREACHED() << "Blocked unauthorized use of extension bindings."; + return; + } + DCHECK(extension_function_dispatcher_.get()); extension_function_dispatcher_->HandleRequest(name, args, request_id, has_callback); diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index e3a0bb6..a8a1247 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -2392,6 +2392,10 @@ bool TabContents::CreateRenderViewForRenderManager( if (render_manager_.pending_dom_ui()) render_view_host->AllowDOMUIBindings(); + // Ditto for extension bindings. + if (controller().pending_entry()->url().SchemeIs(chrome::kExtensionScheme)) + render_view_host->AllowExtensionBindings(); + RenderWidgetHostView* rwh_view = view_->CreateViewForWidget(render_view_host); if (!render_view_host->CreateRenderView()) return false; diff --git a/webkit/port/bindings/v8/v8_proxy.cpp b/webkit/port/bindings/v8/v8_proxy.cpp index 30fcf09..dcc2092 100644 --- a/webkit/port/bindings/v8/v8_proxy.cpp +++ b/webkit/port/bindings/v8/v8_proxy.cpp @@ -2027,7 +2027,8 @@ v8::Persistent<v8::Context> V8Proxy::createNewContext( // because we might be currently loading an URL into a blank page. // See http://code.google.com/p/chromium/issues/detail?id=10924 if (it->scheme.length() > 0 && - it->scheme != m_frame->loader()->activeDocumentLoader()->url().protocol()) + (it->scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || + it->scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol())) continue; extensionNames[index++] = it->extension->name(); |