summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 08:40:49 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-24 08:40:49 +0000
commitd725947e8a370c790794a66fd36d349b7b33b8b8 (patch)
treea4e71071b7efee3341da93b451989b95ba8f8920 /chrome
parentc83658c33bdf286c7d4cf8f766616e297624daec (diff)
downloadchromium_src-d725947e8a370c790794a66fd36d349b7b33b8b8.zip
chromium_src-d725947e8a370c790794a66fd36d349b7b33b8b8.tar.gz
chromium_src-d725947e8a370c790794a66fd36d349b7b33b8b8.tar.bz2
Enforce extension permissions in C++ (instead of Javascript).
BUG=38920 TEST=ExtensionApiTest.Incognito Review URL: http://codereview.chromium.org/1148009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42441 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/extension_port_container.cc4
-rw-r--r--chrome/browser/automation/extension_port_container.h3
-rw-r--r--chrome/browser/debugger/extension_ports_remote_service.cc4
-rw-r--r--chrome/browser/debugger/extension_ports_remote_service.h5
-rw-r--r--chrome/browser/extensions/extension_message_service.cc17
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc6
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/renderer/extensions/event_bindings.cc16
-rw-r--r--chrome/renderer/extensions/event_bindings.h3
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc20
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.h3
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.cc9
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.h2
-rw-r--r--chrome/renderer/render_thread.cc5
-rw-r--r--chrome/renderer/render_thread.h3
-rw-r--r--chrome/renderer/render_view.cc6
-rw-r--r--chrome/renderer/render_view.h3
-rw-r--r--chrome/renderer/resources/event_bindings.js10
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js5
19 files changed, 72 insertions, 57 deletions
diff --git a/chrome/browser/automation/extension_port_container.cc b/chrome/browser/automation/extension_port_container.cc
index 1fd4b70..e167e7e 100644
--- a/chrome/browser/automation/extension_port_container.cc
+++ b/chrome/browser/automation/extension_port_container.cc
@@ -112,7 +112,9 @@ bool ExtensionPortContainer::Send(IPC::Message *message) {
}
void ExtensionPortContainer::OnExtensionMessageInvoke(
- const std::string& function_name, const ListValue& args) {
+ const std::string& function_name,
+ const ListValue& args,
+ bool requires_incognito_access) {
if (function_name == ExtensionMessageService::kDispatchOnMessage) {
DCHECK_EQ(args.GetSize(), 2u);
diff --git a/chrome/browser/automation/extension_port_container.h b/chrome/browser/automation/extension_port_container.h
index a9d61ef..b74709d 100644
--- a/chrome/browser/automation/extension_port_container.h
+++ b/chrome/browser/automation/extension_port_container.h
@@ -63,7 +63,8 @@ class ExtensionPortContainer : public IPC::Message::Sender {
void SendConnectionResponse(int connection_id, int port_id);
void OnExtensionMessageInvoke(const std::string& function_name,
- const ListValue& args);
+ const ListValue& args,
+ bool requires_incognito_access);
void OnExtensionHandleMessage(const std::string& message, int source_port_id);
void OnExtensionPortDisconnected(int source_port_id);
diff --git a/chrome/browser/debugger/extension_ports_remote_service.cc b/chrome/browser/debugger/extension_ports_remote_service.cc
index df549fd..c4380d5 100644
--- a/chrome/browser/debugger/extension_ports_remote_service.cc
+++ b/chrome/browser/debugger/extension_ports_remote_service.cc
@@ -241,7 +241,9 @@ bool ExtensionPortsRemoteService::Send(IPC::Message *message) {
}
void ExtensionPortsRemoteService::OnExtensionMessageInvoke(
- const std::string& function_name, const ListValue& args) {
+ const std::string& function_name,
+ const ListValue& args,
+ bool requires_incognito_access) {
if (function_name == ExtensionMessageService::kDispatchOnMessage) {
DCHECK_EQ(args.GetSize(), 2u);
std::string message;
diff --git a/chrome/browser/debugger/extension_ports_remote_service.h b/chrome/browser/debugger/extension_ports_remote_service.h
index 005905c..3a9e53b 100644
--- a/chrome/browser/debugger/extension_ports_remote_service.h
+++ b/chrome/browser/debugger/extension_ports_remote_service.h
@@ -73,8 +73,9 @@ class ExtensionPortsRemoteService : public DevToolsRemoteListener,
const std::string& destination);
// Handles a message from the ExtensionMessageService.
- void OnExtensionMessageInvoke(
- const std::string& function_name, const ListValue& args);
+ void OnExtensionMessageInvoke(const std::string& function_name,
+ const ListValue& args,
+ bool requires_incognito_access);
// Handles a message sent from an extension through the
// ExtensionMessageService, to be passed to the external client.
void OnExtensionMessage(const std::string& message, int port_id);
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 45b5304..2586151 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -69,16 +69,16 @@ static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port,
args.Set(3, Value::CreateStringValue(source_extension_id));
args.Set(4, Value::CreateStringValue(target_extension_id));
CHECK(port.sender);
- port.sender->Send(new ViewMsg_ExtensionMessageInvoke(
- port.routing_id, ExtensionMessageService::kDispatchOnConnect, args));
+ port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
+ ExtensionMessageService::kDispatchOnConnect, args, false));
}
static void DispatchOnDisconnect(
const ExtensionMessageService::MessagePort& port, int source_port_id) {
ListValue args;
args.Set(0, Value::CreateIntegerValue(source_port_id));
- port.sender->Send(new ViewMsg_ExtensionMessageInvoke(
- port.routing_id, ExtensionMessageService::kDispatchOnDisconnect, args));
+ port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
+ ExtensionMessageService::kDispatchOnDisconnect, args, false));
}
static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
@@ -86,8 +86,8 @@ static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
ListValue args;
args.Set(0, Value::CreateStringValue(message));
args.Set(1, Value::CreateIntegerValue(source_port_id));
- port.sender->Send(new ViewMsg_ExtensionMessageInvoke(
- port.routing_id, ExtensionMessageService::kDispatchOnMessage, args));
+ port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
+ ExtensionMessageService::kDispatchOnMessage, args, false));
}
static void DispatchEvent(const ExtensionMessageService::MessagePort& port,
@@ -97,9 +97,8 @@ static void DispatchEvent(const ExtensionMessageService::MessagePort& port,
ListValue args;
args.Set(0, Value::CreateStringValue(event_name));
args.Set(1, Value::CreateStringValue(event_args));
- args.Set(2, Value::CreateBooleanValue(has_incognito_data));
- port.sender->Send(new ViewMsg_ExtensionMessageInvoke(
- port.routing_id, ExtensionMessageService::kDispatchEvent, args));
+ port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
+ ExtensionMessageService::kDispatchEvent, args, has_incognito_data));
}
} // namespace
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index 98d4db0..5d06654 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -18,14 +18,14 @@ static void DispatchOnConnect(int source_port_id, const std::string& name,
args.Set(3, Value::CreateStringValue("")); // extension ID is empty for tests
args.Set(4, Value::CreateStringValue("")); // extension ID is empty for tests
RendererExtensionBindings::Invoke(
- ExtensionMessageService::kDispatchOnConnect, args, NULL);
+ ExtensionMessageService::kDispatchOnConnect, args, NULL, false);
}
static void DispatchOnDisconnect(int source_port_id) {
ListValue args;
args.Set(0, Value::CreateIntegerValue(source_port_id));
RendererExtensionBindings::Invoke(
- ExtensionMessageService::kDispatchOnDisconnect, args, NULL);
+ ExtensionMessageService::kDispatchOnDisconnect, args, NULL, false);
}
static void DispatchOnMessage(const std::string& message, int source_port_id) {
@@ -33,7 +33,7 @@ static void DispatchOnMessage(const std::string& message, int source_port_id) {
args.Set(0, Value::CreateStringValue(message));
args.Set(1, Value::CreateIntegerValue(source_port_id));
RendererExtensionBindings::Invoke(
- ExtensionMessageService::kDispatchOnMessage, args, NULL);
+ ExtensionMessageService::kDispatchOnMessage, args, NULL, false);
}
// Tests that the bindings for opening a channel to an extension and sending
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index adac8b5..afc9a4c 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -707,9 +707,10 @@ IPC_BEGIN_MESSAGES(View)
// target process. If routed, it will be restricted to the contexts that
// are part of the target RenderView.
// |args| is a list of primitive Value types that are passed to the function.
- IPC_MESSAGE_ROUTED2(ViewMsg_ExtensionMessageInvoke,
+ IPC_MESSAGE_ROUTED3(ViewMsg_ExtensionMessageInvoke,
std::string /* function_name */,
- ListValue /* args */)
+ ListValue /* args */,
+ bool /* requires incognito access */)
// Tell the renderer process all known extension function names.
IPC_MESSAGE_CONTROL1(ViewMsg_Extension_SetFunctionNames,
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index a751785..f1dfa19 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -128,6 +128,14 @@ class ExtensionImpl : public ExtensionBase {
}
};
+// Returns true if the extension running in the given |context| has sufficient
+// permissions to access the data.
+static bool HasSufficientPermissions(ContextInfo* context,
+ bool requires_incognito_access) {
+ return (!requires_incognito_access ||
+ ExtensionProcessBindings::HasIncognitoEnabled(context->extension_id));
+}
+
} // namespace
const char* EventBindings::kName = "chrome/EventBindings";
@@ -290,7 +298,8 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) {
// static
void EventBindings::CallFunction(const std::string& function_name,
int argc, v8::Handle<v8::Value>* argv,
- RenderView* render_view) {
+ RenderView* render_view,
+ bool requires_incognito_access) {
// We copy the context list, because calling into javascript may modify it
// out from under us. We also guard against deleted contexts by checking if
// they have been cleared first.
@@ -300,8 +309,13 @@ void EventBindings::CallFunction(const std::string& function_name,
it != contexts.end(); ++it) {
if (render_view && render_view != (*it)->render_view)
continue;
+
if ((*it)->context.IsEmpty())
continue;
+
+ if (!HasSufficientPermissions(it->get(), requires_incognito_access))
+ continue;
+
v8::Handle<v8::Value> retval = CallFunctionInContext((*it)->context,
function_name, argc, argv);
// In debug, the js will validate the event parameters and return a
diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h
index 736cb8a..74edb68 100644
--- a/chrome/renderer/extensions/event_bindings.h
+++ b/chrome/renderer/extensions/event_bindings.h
@@ -39,7 +39,8 @@ class EventBindings {
// v8::Undefined(). A DCHECK is setup to break if it is otherwise.
static void CallFunction(const std::string& function_name, int argc,
v8::Handle<v8::Value>* argv,
- RenderView* render_view);
+ RenderView* render_view,
+ bool requires_incognito_access);
};
#endif // CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 694c276..78285b1 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -71,7 +71,7 @@ struct SingletonData {
std::set<std::string> function_names_;
PageActionIdMap page_action_ids_;
ExtensionPermissionsMap permissions_;
- std::map<std::string, bool> incognito_enabled_map_;
+ IncognitoEnabledMap incognito_enabled_map_;
};
static std::set<std::string>* GetFunctionNameSet() {
@@ -245,8 +245,6 @@ class ExtensionImpl : public ExtensionBase {
return v8::FunctionTemplate::New(GetPopupParentWindow);
} else if (name->Equals(v8::String::New("SetExtensionActionIcon"))) {
return v8::FunctionTemplate::New(SetExtensionActionIcon);
- } else if (name->Equals(v8::String::New("CanAccessIncognito"))) {
- return v8::FunctionTemplate::New(CanAccessIncognito);
}
return ExtensionBase::GetNativeFunction(name);
@@ -505,16 +503,6 @@ class ExtensionImpl : public ExtensionBase {
return StartRequestCommon(args, dict);
}
- // Returns true if the extension can access incognito data.
- static v8::Handle<v8::Value> CanAccessIncognito(const v8::Arguments& args) {
- std::string extension_id = ExtensionIdForCurrentContext();
- if (extension_id.empty())
- return v8::False();
-
- bool enabled = (*GetIncognitoEnabledMap())[extension_id];
- return v8::Boolean::New(enabled);
- }
-
static v8::Handle<v8::Value> GetRenderViewId(const v8::Arguments& args) {
RenderView* renderview = bindings_utils::GetRenderViewForCurrentContext();
if (!renderview)
@@ -546,6 +534,12 @@ void ExtensionProcessBindings::SetIncognitoEnabled(
}
// static
+bool ExtensionProcessBindings::HasIncognitoEnabled(
+ const std::string& extension_id) {
+ return (!extension_id.empty() && (*GetIncognitoEnabledMap())[extension_id]);
+}
+
+// static
void ExtensionProcessBindings::HandleResponse(int request_id, bool success,
const std::string& response,
const std::string& error) {
diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h
index 93c7d24..e95e737 100644
--- a/chrome/renderer/extensions/extension_process_bindings.h
+++ b/chrome/renderer/extensions/extension_process_bindings.h
@@ -50,6 +50,9 @@ class ExtensionProcessBindings {
static void SetIncognitoEnabled(const std::string& extension_id,
bool enabled);
+ // Checks whether incognito is enabled for a particular extension.
+ static bool HasIncognitoEnabled(const std::string& extension_id);
+
// Check if the extension in the currently running context has permission to
// access the given extension function. Must be called with a valid V8
// context in scope.
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index 5e78932b..d393089 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -298,8 +298,13 @@ v8::Extension* RendererExtensionBindings::Get() {
void RendererExtensionBindings::Invoke(const std::string& function_name,
const ListValue& args,
- RenderView* renderview) {
+ RenderView* renderview,
+ bool requires_incognito_access) {
v8::HandleScope handle_scope;
std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args);
- EventBindings::CallFunction(function_name, argv.size(), &argv[0], renderview);
+ EventBindings::CallFunction(function_name,
+ argv.size(),
+ &argv[0],
+ renderview,
+ requires_incognito_access);
}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h
index 89e903d..04233f6 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.h
+++ b/chrome/renderer/extensions/renderer_extension_bindings.h
@@ -24,7 +24,7 @@ class RendererExtensionBindings {
// Call the given javascript function with the specified arguments.
static void Invoke(const std::string& function_name, const ListValue& args,
- RenderView* renderview);
+ RenderView* renderview, bool requires_incognito_access);
};
#endif // CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 6448cf5..ab97f2a 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -865,8 +865,9 @@ void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
}
void RenderThread::OnExtensionMessageInvoke(const std::string& function_name,
- const ListValue& args) {
- RendererExtensionBindings::Invoke(function_name, args, NULL);
+ const ListValue& args,
+ bool requires_incognito_access) {
+ RendererExtensionBindings::Invoke(function_name, args, NULL, requires_incognito_access);
// Reset the idle handler each time there's any activity like event or message
// dispatch, for which Invoke is the chokepoint.
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 504ecc5..fea7e41 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -208,7 +208,8 @@ class RenderThread : public RenderThreadBase,
void OnGetV8HeapStats();
void OnExtensionMessageInvoke(const std::string& function_name,
- const ListValue& args);
+ const ListValue& args,
+ bool requires_incognito_access);
void OnPurgeMemory();
void OnPurgePluginListCache(bool reload_pages);
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index c0d5b3f..fb2e70e 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -4109,8 +4109,10 @@ void RenderView::InjectToolstripCSS() {
}
void RenderView::OnExtensionMessageInvoke(const std::string& function_name,
- const ListValue& args) {
- RendererExtensionBindings::Invoke(function_name, args, this);
+ const ListValue& args,
+ bool requires_incognito_access) {
+ RendererExtensionBindings::Invoke(
+ function_name, args, this, requires_incognito_access);
}
// Dump all load time histograms.
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 3695545..0c4e660 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -714,7 +714,8 @@ class RenderView : public RenderWidget,
void OnClearAccessibilityInfo(int acc_obj_id, bool clear_all);
void OnExtensionMessageInvoke(const std::string& function_name,
- const ListValue& args);
+ const ListValue& args,
+ bool requires_incognito_access);
void OnMoveOrResizeStarted();
diff --git a/chrome/renderer/resources/event_bindings.js b/chrome/renderer/resources/event_bindings.js
index 7ea6bbf..aaea01c 100644
--- a/chrome/renderer/resources/event_bindings.js
+++ b/chrome/renderer/resources/event_bindings.js
@@ -45,20 +45,12 @@ var chrome = chrome || {};
// An array of all attached event objects, used for detaching on unload.
var allAttachedEvents = [];
- // By default (for content scripts), this function returns false. Extension
- // contexts override this to do the right thing.
- chromeHidden.canAccessIncognito = function() {
- return false;
- }
-
chromeHidden.Event = {};
// Dispatches a named event with the given JSON array, which is deserialized
// before dispatch. The JSON array is the list of arguments that will be
// sent with the event callback.
- chromeHidden.Event.dispatchJSON = function(name, args, hasIncognitoData) {
- if (hasIncognitoData && !chromeHidden.canAccessIncognito())
- return;
+ chromeHidden.Event.dispatchJSON = function(name, args) {
if (attachedNamedEvents[name]) {
if (args) {
args = JSON.parse(args);
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 7e803b5..5d80919 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -18,17 +18,12 @@ var chrome = chrome || {};
native function GetPopupParentWindow();
native function GetPopupView();
native function SetExtensionActionIcon();
- native function CanAccessIncognito();
if (!chrome)
chrome = {};
var chromeHidden = GetChromeHidden();
- chromeHidden.canAccessIncognito = function() {
- return CanAccessIncognito();
- }
-
// Validate arguments.
chromeHidden.validationTypes = [];
chromeHidden.validate = function(args, schemas) {