Commit 1ada5673 authored by kalman@chromium.org's avatar kalman@chromium.org

Move the event URL security check out of the renderer and into the browser.

R=mpcomplete@chromium.org
BUG=55316

Review URL: https://chromiumcodereview.appspot.com/15825008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203024 0039d316-1c4b-4281-b951-d872f2087c98
parent fb3cd665
...@@ -1099,7 +1099,7 @@ bool ExtensionWebRequestEventRouter::DispatchEvent( ...@@ -1099,7 +1099,7 @@ bool ExtensionWebRequestEventRouter::DispatchEvent(
extensions::EventRouter::DispatchEvent( extensions::EventRouter::DispatchEvent(
(*it)->ipc_sender.get(), profile_id, (*it)->ipc_sender.get(), profile_id,
(*it)->extension_id, (*it)->sub_event_name, (*it)->extension_id, (*it)->sub_event_name,
args_filtered.Pass(), GURL(), args_filtered.Pass(),
extensions::EventRouter::USER_GESTURE_UNKNOWN, extensions::EventRouter::USER_GESTURE_UNKNOWN,
extensions::EventFilteringInfo()); extensions::EventFilteringInfo());
if ((*it)->extra_info_spec & if ((*it)->extra_info_spec &
......
...@@ -97,9 +97,7 @@ void AppWindowContents::NativeWindowChanged( ...@@ -97,9 +97,7 @@ void AppWindowContents::NativeWindowChanged(
host_->extension()->id(), host_->extension()->id(),
"updateAppWindowProperties", "updateAppWindowProperties",
args, args,
GURL(),
false)); false));
} }
void AppWindowContents::NativeWindowClosed() { void AppWindowContents::NativeWindowClosed() {
......
...@@ -139,7 +139,6 @@ void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, ...@@ -139,7 +139,6 @@ void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender,
const std::string& extension_id, const std::string& extension_id,
const std::string& event_name, const std::string& event_name,
ListValue* event_args, ListValue* event_args,
const GURL& event_url,
UserGestureState user_gesture, UserGestureState user_gesture,
const EventFilteringInfo& info) { const EventFilteringInfo& info) {
if (ActivityLog::IsLogEnabled()) { if (ActivityLog::IsLogEnabled()) {
...@@ -151,8 +150,11 @@ void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, ...@@ -151,8 +150,11 @@ void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender,
args.Set(0, Value::CreateStringValue(event_name)); args.Set(0, Value::CreateStringValue(event_name));
args.Set(1, event_args); args.Set(1, event_args);
args.Set(2, info.AsValue().release()); args.Set(2, info.AsValue().release());
ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, ipc_sender->Send(new ExtensionMsg_MessageInvoke(
extension_id, kDispatchEvent, args, event_url, MSG_ROUTING_CONTROL,
extension_id,
kDispatchEvent,
args,
user_gesture == USER_GESTURE_ENABLED)); user_gesture == USER_GESTURE_ENABLED));
// DispatchExtensionMessage does _not_ take ownership of event_args, so we // DispatchExtensionMessage does _not_ take ownership of event_args, so we
...@@ -167,11 +169,10 @@ void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, ...@@ -167,11 +169,10 @@ void EventRouter::DispatchEvent(IPC::Sender* ipc_sender,
const std::string& extension_id, const std::string& extension_id,
const std::string& event_name, const std::string& event_name,
scoped_ptr<ListValue> event_args, scoped_ptr<ListValue> event_args,
const GURL& event_url,
UserGestureState user_gesture, UserGestureState user_gesture,
const EventFilteringInfo& info) { const EventFilteringInfo& info) {
DispatchExtensionMessage(ipc_sender, profile_id, extension_id, event_name, DispatchExtensionMessage(ipc_sender, profile_id, extension_id, event_name,
event_args.get(), event_url, user_gesture, info); event_args.get(), user_gesture, info);
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, BrowserThread::UI,
...@@ -605,6 +606,15 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id, ...@@ -605,6 +606,15 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id,
return; return;
} }
// If the event is restricted to a URL, only dispatch if the extension has
// permission for it (or if the event originated from itself).
if (!event->event_url.is_empty() &&
event->event_url.host() != extension->id() &&
!extension->GetActivePermissions()->HasEffectiveAccessToURL(
event->event_url)) {
return;
}
if (!CanDispatchEventToProfile(listener_profile, extension, event)) if (!CanDispatchEventToProfile(listener_profile, extension, event))
return; return;
...@@ -613,10 +623,9 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id, ...@@ -613,10 +623,9 @@ void EventRouter::DispatchEventToProcess(const std::string& extension_id,
event->event_args.get()); event->event_args.get());
} }
DispatchExtensionMessage(process, listener_profile, extension_id, DispatchExtensionMessage(process, listener_profile, extension->id(),
event->event_name, event->event_args.get(), event->event_name, event->event_args.get(),
event->event_url, event->user_gesture, event->user_gesture, event->filter_info);
event->filter_info);
IncrementInFlightEvents(listener_profile, extension); IncrementInFlightEvents(listener_profile, extension);
} }
......
...@@ -71,7 +71,6 @@ class EventRouter : public content::NotificationObserver, ...@@ -71,7 +71,6 @@ class EventRouter : public content::NotificationObserver,
const std::string& extension_id, const std::string& extension_id,
const std::string& event_name, const std::string& event_name,
scoped_ptr<base::ListValue> event_args, scoped_ptr<base::ListValue> event_args,
const GURL& event_url,
UserGestureState user_gesture, UserGestureState user_gesture,
const EventFilteringInfo& info); const EventFilteringInfo& info);
...@@ -175,7 +174,6 @@ class EventRouter : public content::NotificationObserver, ...@@ -175,7 +174,6 @@ class EventRouter : public content::NotificationObserver,
const std::string& extension_id, const std::string& extension_id,
const std::string& event_name, const std::string& event_name,
base::ListValue* event_args, base::ListValue* event_args,
const GURL& event_url,
UserGestureState user_gesture, UserGestureState user_gesture,
const extensions::EventFilteringInfo& info); const extensions::EventFilteringInfo& info);
......
...@@ -297,11 +297,10 @@ IPC_MESSAGE_ROUTED4(ExtensionMsg_Response, ...@@ -297,11 +297,10 @@ IPC_MESSAGE_ROUTED4(ExtensionMsg_Response,
// If |extension_id| is non-empty, the function will be invoked only in // If |extension_id| is non-empty, the function will be invoked only in
// contexts owned by the extension. |args| is a list of primitive Value types // contexts owned by the extension. |args| is a list of primitive Value types
// that are passed to the function. // that are passed to the function.
IPC_MESSAGE_ROUTED5(ExtensionMsg_MessageInvoke, IPC_MESSAGE_ROUTED4(ExtensionMsg_MessageInvoke,
std::string /* extension_id */, std::string /* extension_id */,
std::string /* function_name */, std::string /* function_name */,
ListValue /* args */, ListValue /* args */,
GURL /* event URL */,
bool /* delivered as part of a user gesture */) bool /* delivered as part of a user gesture */)
// Tell the renderer process all known extension function names. // Tell the renderer process all known extension function names.
......
...@@ -27,29 +27,6 @@ using content::V8ValueConverter; ...@@ -27,29 +27,6 @@ using content::V8ValueConverter;
namespace extensions { namespace extensions {
namespace {
// Returns true if the extension running in the given |render_view| has
// sufficient permissions to access the data.
//
// TODO(aa): This looks super suspicious. Is it correct? Can we use something
// else already in the system? Should it be moved elsewhere?
bool HasSufficientPermissions(content::RenderView* render_view,
const GURL& event_url) {
// During unit tests, we might be invoked without a v8 context. In these
// cases, we only allow empty event_urls and short-circuit before retrieving
// the render view from the current context.
if (!event_url.is_valid())
return true;
WebKit::WebDocument document =
render_view->GetWebView()->mainFrame()->document();
return GURL(document.url()).SchemeIs(extensions::kExtensionScheme) &&
document.securityOrigin().canRequest(event_url);
}
} // namespace
ChromeV8ContextSet::ChromeV8ContextSet() { ChromeV8ContextSet::ChromeV8ContextSet() {
} }
ChromeV8ContextSet::~ChromeV8ContextSet() { ChromeV8ContextSet::~ChromeV8ContextSet() {
...@@ -106,8 +83,7 @@ void ChromeV8ContextSet::DispatchChromeHiddenMethod( ...@@ -106,8 +83,7 @@ void ChromeV8ContextSet::DispatchChromeHiddenMethod(
const std::string& extension_id, const std::string& extension_id,
const std::string& method_name, const std::string& method_name,
const base::ListValue& arguments, const base::ListValue& arguments,
content::RenderView* render_view, content::RenderView* render_view) const {
const GURL& event_url) const {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
// We copy the context list, because calling into javascript may modify it // We copy the context list, because calling into javascript may modify it
...@@ -133,9 +109,6 @@ void ChromeV8ContextSet::DispatchChromeHiddenMethod( ...@@ -133,9 +109,6 @@ void ChromeV8ContextSet::DispatchChromeHiddenMethod(
if (render_view && render_view != context_render_view) if (render_view && render_view != context_render_view)
continue; continue;
if (!HasSufficientPermissions(context_render_view, event_url))
continue;
v8::Local<v8::Context> context(*((*it)->v8_context())); v8::Local<v8::Context> context(*((*it)->v8_context()));
std::vector<v8::Handle<v8::Value> > v8_arguments; std::vector<v8::Handle<v8::Value> > v8_arguments;
for (size_t i = 0; i < arguments.GetSize(); ++i) { for (size_t i = 0; i < arguments.GetSize(); ++i) {
......
...@@ -66,8 +66,7 @@ class ChromeV8ContextSet { ...@@ -66,8 +66,7 @@ class ChromeV8ContextSet {
void DispatchChromeHiddenMethod(const std::string& extension_id, void DispatchChromeHiddenMethod(const std::string& extension_id,
const std::string& method_name, const std::string& method_name,
const base::ListValue& arguments, const base::ListValue& arguments,
content::RenderView* render_view, content::RenderView* render_view) const;
const GURL& event_url) const;
// Cleans up contexts belonging to an unloaded extension. // Cleans up contexts belonging to an unloaded extension.
// //
......
...@@ -552,7 +552,6 @@ void Dispatcher::OnSetChannel(int channel) { ...@@ -552,7 +552,6 @@ void Dispatcher::OnSetChannel(int channel) {
void Dispatcher::OnMessageInvoke(const std::string& extension_id, void Dispatcher::OnMessageInvoke(const std::string& extension_id,
const std::string& function_name, const std::string& function_name,
const base::ListValue& args, const base::ListValue& args,
const GURL& event_url,
bool user_gesture) { bool user_gesture) {
scoped_ptr<WebScopedUserGesture> web_user_gesture; scoped_ptr<WebScopedUserGesture> web_user_gesture;
if (user_gesture) { if (user_gesture) {
...@@ -560,7 +559,7 @@ void Dispatcher::OnMessageInvoke(const std::string& extension_id, ...@@ -560,7 +559,7 @@ void Dispatcher::OnMessageInvoke(const std::string& extension_id,
} }
v8_context_set_.DispatchChromeHiddenMethod( v8_context_set_.DispatchChromeHiddenMethod(
extension_id, function_name, args, NULL, event_url); extension_id, function_name, args, NULL);
// Reset the idle handler each time there's any activity like event or message // Reset the idle handler each time there's any activity like event or message
// dispatch, for which Invoke is the chokepoint. // dispatch, for which Invoke is the chokepoint.
...@@ -1359,7 +1358,7 @@ void Dispatcher::OnSuspend(const std::string& extension_id) { ...@@ -1359,7 +1358,7 @@ void Dispatcher::OnSuspend(const std::string& extension_id) {
args.Set(0, new base::StringValue(kOnSuspendEvent)); args.Set(0, new base::StringValue(kOnSuspendEvent));
args.Set(1, new base::ListValue()); args.Set(1, new base::ListValue());
v8_context_set_.DispatchChromeHiddenMethod( v8_context_set_.DispatchChromeHiddenMethod(
extension_id, kEventDispatchFunction, args, NULL, GURL()); extension_id, kEventDispatchFunction, args, NULL);
RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
} }
...@@ -1369,7 +1368,7 @@ void Dispatcher::OnCancelSuspend(const std::string& extension_id) { ...@@ -1369,7 +1368,7 @@ void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
args.Set(0, new base::StringValue(kOnSuspendCanceledEvent)); args.Set(0, new base::StringValue(kOnSuspendCanceledEvent));
args.Set(1, new base::ListValue()); args.Set(1, new base::ListValue());
v8_context_set_.DispatchChromeHiddenMethod( v8_context_set_.DispatchChromeHiddenMethod(
extension_id, kEventDispatchFunction, args, NULL, GURL()); extension_id, kEventDispatchFunction, args, NULL);
} }
Feature::Context Dispatcher::ClassifyJavaScriptContext( Feature::Context Dispatcher::ClassifyJavaScriptContext(
......
...@@ -146,7 +146,6 @@ class Dispatcher : public content::RenderProcessObserver { ...@@ -146,7 +146,6 @@ class Dispatcher : public content::RenderProcessObserver {
void OnMessageInvoke(const std::string& extension_id, void OnMessageInvoke(const std::string& extension_id,
const std::string& function_name, const std::string& function_name,
const base::ListValue& args, const base::ListValue& args,
const GURL& event_url,
bool user_gesture); bool user_gesture);
void OnDispatchOnConnect(int target_port_id, void OnDispatchOnConnect(int target_port_id,
const std::string& channel_name, const std::string& channel_name,
......
...@@ -252,7 +252,6 @@ void ExtensionHelper::OnExtensionResponse(int request_id, ...@@ -252,7 +252,6 @@ void ExtensionHelper::OnExtensionResponse(int request_id,
void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id, void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id,
const std::string& function_name, const std::string& function_name,
const base::ListValue& args, const base::ListValue& args,
const GURL& event_url,
bool user_gesture) { bool user_gesture) {
scoped_ptr<WebScopedUserGesture> web_user_gesture; scoped_ptr<WebScopedUserGesture> web_user_gesture;
if (user_gesture) { if (user_gesture) {
...@@ -260,7 +259,7 @@ void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id, ...@@ -260,7 +259,7 @@ void ExtensionHelper::OnExtensionMessageInvoke(const std::string& extension_id,
} }
dispatcher_->v8_context_set().DispatchChromeHiddenMethod( dispatcher_->v8_context_set().DispatchChromeHiddenMethod(
extension_id, function_name, args, render_view(), event_url); extension_id, function_name, args, render_view());
} }
void ExtensionHelper::OnExtensionDispatchOnConnect( void ExtensionHelper::OnExtensionDispatchOnConnect(
......
...@@ -73,7 +73,6 @@ class ExtensionHelper ...@@ -73,7 +73,6 @@ class ExtensionHelper
void OnExtensionMessageInvoke(const std::string& extension_id, void OnExtensionMessageInvoke(const std::string& extension_id,
const std::string& function_name, const std::string& function_name,
const base::ListValue& args, const base::ListValue& args,
const GURL& event_url,
bool user_gesture); bool user_gesture);
void OnExtensionDispatchOnConnect( void OnExtensionDispatchOnConnect(
int target_port_id, int target_port_id,
......
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