Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: chrome/renderer/extensions/dispatcher.cc

Issue 16625012: Remove ExtensionURLInfo, make security decisions in render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased and review feedback Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/extensions/dispatcher.h" 5 #include "chrome/renderer/extensions/dispatcher.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/alias.h" 9 #include "base/debug/alias.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 // CSP blocks extension page loading by switching the extension ID to 1008 // CSP blocks extension page loading by switching the extension ID to
1009 // "invalid". This isn't interesting. 1009 // "invalid". This isn't interesting.
1010 if (extension_id != "invalid") { 1010 if (extension_id != "invalid") {
1011 LOG(ERROR) << "Extension \"" << extension_id << "\" not found"; 1011 LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
1012 RenderThread::Get()->RecordUserMetrics("ExtensionNotFound_ED"); 1012 RenderThread::Get()->RecordUserMetrics("ExtensionNotFound_ED");
1013 } 1013 }
1014 1014
1015 extension_id = ""; 1015 extension_id = "";
1016 } 1016 }
1017 1017
1018 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1018 // Frames loaded on a unique security origin are not accessible to extensions.
not at google - send to devlin 2013/07/15 22:09:12 I've convinced myself that this seems kind of arbi
1019 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1019 GURL effective_frame_url;
1020 if (!frame->document().securityOrigin().isUnique())
1021 effective_frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
1020 1022
1021 Feature::Context context_type = 1023 Feature::Context context_type = ClassifyJavaScriptContext(
1022 ClassifyJavaScriptContext(extension_id, extension_group, url_info); 1024 extension_id, extension_group, effective_frame_url);
Matt Perry 2013/07/15 21:24:31 The call to IsSandboxedPage in ClassifyJavaScriptC
not at google - send to devlin 2013/07/15 22:09:12 yes I think this is another place where isUnique i
1023 1025
1024 ChromeV8Context* context = 1026 ChromeV8Context* context =
1025 new ChromeV8Context(v8_context, frame, extension, context_type); 1027 new ChromeV8Context(v8_context, frame, extension, context_type);
1026 v8_context_set_.Add(context); 1028 v8_context_set_.Add(context);
1027 1029
1028 { 1030 {
1029 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context, 1031 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context,
1030 &source_map_)); 1032 &source_map_));
1031 context->set_module_system(module_system.Pass()); 1033 context->set_module_system(module_system.Pass());
1032 } 1034 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 1122
1121 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); 1123 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
1122 } 1124 }
1123 1125
1124 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) { 1126 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) {
1125 if (world_id != 0) { 1127 if (world_id != 0) {
1126 // Isolated worlds (content script). 1128 // Isolated worlds (content script).
1127 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); 1129 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
1128 } 1130 }
1129 1131
1132 if (frame->document().securityOrigin().isUnique())
1133 return std::string();
not at google - send to devlin 2013/07/15 22:09:12 also here
1134
1130 // Extension pages (chrome-extension:// URLs). 1135 // Extension pages (chrome-extension:// URLs).
1131 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); 1136 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
1132 return extensions_.GetExtensionOrAppIDByURL( 1137 return extensions_.GetExtensionOrAppIDByURL(frame_url);
1133 ExtensionURLInfo(frame->document().securityOrigin(), frame_url));
1134 } 1138 }
1135 1139
1136 bool Dispatcher::IsWithinPlatformApp(const WebFrame* frame) { 1140 bool Dispatcher::IsWithinPlatformApp(const WebFrame* frame) {
1137 // We intentionally don't use the origin parameter for ExtensionURLInfo since 1141 GURL url(UserScriptSlave::GetDataSourceURLForFrame(frame->top()));
1138 // it would be empty (i.e. unique) for sandboxed resources and thus not match. 1142 const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
1139 ExtensionURLInfo url_info(
1140 UserScriptSlave::GetDataSourceURLForFrame(frame->top()));
1141 const Extension* extension = extensions_.GetExtensionOrAppByURL(url_info);
1142 1143
1143 return extension && extension->is_platform_app(); 1144 return extension && extension->is_platform_app();
1144 } 1145 }
1145 1146
1146 void Dispatcher::WillReleaseScriptContext( 1147 void Dispatcher::WillReleaseScriptContext(
1147 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { 1148 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
1148 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); 1149 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context);
1149 if (!context) 1150 if (!context)
1150 return; 1151 return;
1151 1152
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); 1372 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
1372 } 1373 }
1373 1374
1374 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { 1375 void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
1375 DispatchEvent(extension_id, kOnSuspendCanceledEvent); 1376 DispatchEvent(extension_id, kOnSuspendCanceledEvent);
1376 } 1377 }
1377 1378
1378 Feature::Context Dispatcher::ClassifyJavaScriptContext( 1379 Feature::Context Dispatcher::ClassifyJavaScriptContext(
1379 const std::string& extension_id, 1380 const std::string& extension_id,
1380 int extension_group, 1381 int extension_group,
1381 const ExtensionURLInfo& url_info) { 1382 const GURL& url) {
1382 DCHECK_GE(extension_group, 0); 1383 DCHECK_GE(extension_group, 0);
1383 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { 1384 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
1384 return extensions_.Contains(extension_id) ? 1385 return extensions_.Contains(extension_id) ?
1385 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1386 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1386 } 1387 }
1387 1388
1388 // We have an explicit check for sandboxed pages before checking whether the 1389 // We have an explicit check for sandboxed pages before checking whether the
1389 // extension is active in this process because: 1390 // extension is active in this process because:
1390 // 1. Sandboxed pages run in the same process as regular extension pages, so 1391 // 1. Sandboxed pages run in the same process as regular extension pages, so
1391 // the extension is considered active. 1392 // the extension is considered active.
1392 // 2. ScriptContext creation (which triggers bindings injection) happens 1393 // 2. ScriptContext creation (which triggers bindings injection) happens
1393 // before the SecurityContext is updated with the sandbox flags (after 1394 // before the SecurityContext is updated with the sandbox flags (after
1394 // reading the CSP header), so url_info.url().securityOrigin() is not 1395 // reading the CSP header), so the caller can't check if the context's
1395 // unique yet. 1396 // security origin is unique yet.
1396 if (extensions_.IsSandboxedPage(url_info)) 1397 if (extensions_.IsSandboxedPage(url))
1397 return Feature::WEB_PAGE_CONTEXT; 1398 return Feature::WEB_PAGE_CONTEXT;
1398 1399
1399 if (IsExtensionActive(extension_id)) 1400 if (IsExtensionActive(extension_id))
1400 return Feature::BLESSED_EXTENSION_CONTEXT; 1401 return Feature::BLESSED_EXTENSION_CONTEXT;
1401 1402
1402 if (extensions_.ExtensionBindingsAllowed(url_info)) { 1403 if (extensions_.ExtensionBindingsAllowed(url)) {
1403 return extensions_.Contains(extension_id) ? 1404 return extensions_.Contains(extension_id) ?
1404 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1405 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1405 } 1406 }
1406 1407
1407 if (url_info.url().is_valid()) 1408 if (url.is_valid())
1408 return Feature::WEB_PAGE_CONTEXT; 1409 return Feature::WEB_PAGE_CONTEXT;
1409 1410
1410 return Feature::UNSPECIFIED_CONTEXT; 1411 return Feature::UNSPECIFIED_CONTEXT;
1411 } 1412 }
1412 1413
1413 void Dispatcher::OnExtensionResponse(int request_id, 1414 void Dispatcher::OnExtensionResponse(int request_id,
1414 bool success, 1415 bool success,
1415 const base::ListValue& response, 1416 const base::ListValue& response,
1416 const std::string& error) { 1417 const std::string& error) {
1417 request_sender_->HandleResponse(request_id, success, response, error); 1418 request_sender_->HandleResponse(request_id, success, response, error);
1418 } 1419 }
1419 1420
1420 bool Dispatcher::CheckContextAccessToExtensionAPI( 1421 bool Dispatcher::CheckContextAccessToExtensionAPI(
1421 const std::string& function_name, ChromeV8Context* context) const { 1422 const std::string& function_name, ChromeV8Context* context) const {
1422 if (!context) { 1423 if (!context) {
1423 DLOG(ERROR) << "Not in a v8::Context"; 1424 DLOG(ERROR) << "Not in a v8::Context";
1424 return false; 1425 return false;
1425 } 1426 }
1426 1427
1427 if (!context->extension()) { 1428 if (!context->extension()) {
1428 v8::ThrowException( 1429 v8::ThrowException(
1429 v8::Exception::Error(v8::String::New("Not in an extension."))); 1430 v8::Exception::Error(v8::String::New("Not in an extension.")));
1430 return false; 1431 return false;
1431 } 1432 }
1432 1433
1433 // Theoretically we could end up with bindings being injected into sandboxed 1434 // Theoretically we could end up with bindings being injected into sandboxed
1434 // frames, for example content scripts. Don't let them execute API functions. 1435 // frames, for example content scripts. Don't let them execute API functions.
1435 WebKit::WebFrame* frame = context->web_frame(); 1436 WebKit::WebFrame* frame = context->web_frame();
1436 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1437 if (frame->document().securityOrigin().isUnique() ||
1437 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1438 extensions_.IsSandboxedPage(
1438 if (extensions_.IsSandboxedPage(url_info)) { 1439 UserScriptSlave::GetDataSourceURLForFrame(frame))) {
not at google - send to devlin 2013/07/15 22:09:12 I don't actually think we should be preventing scr
not at google - send to devlin 2013/07/15 22:27:10 Ok I'm being dense and mixed up host and API permi
jamesr 2013/07/15 22:55:27 It appears that chrome.runtime.sendMessage() fails
not at google - send to devlin 2013/07/15 23:00:53 Yeah looks like there's an existing issue at play
1439 static const char kMessage[] = 1440 static const char kMessage[] =
1440 "%s cannot be used within a sandboxed frame."; 1441 "%s cannot be used within a sandboxed frame.";
1441 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1442 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1442 v8::ThrowException( 1443 v8::ThrowException(
1443 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1444 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1444 return false; 1445 return false;
1445 } 1446 }
1446 1447
1447 Feature::Availability availability = context->GetAvailability(function_name); 1448 Feature::Availability availability = context->GetAvailability(function_name);
1448 if (!availability.is_available()) { 1449 if (!availability.is_available()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 RenderView* background_view = 1503 RenderView* background_view =
1503 ExtensionHelper::GetBackgroundPage(extension_id); 1504 ExtensionHelper::GetBackgroundPage(extension_id);
1504 if (background_view) { 1505 if (background_view) {
1505 background_view->Send(new ExtensionHostMsg_EventAck( 1506 background_view->Send(new ExtensionHostMsg_EventAck(
1506 background_view->GetRoutingID())); 1507 background_view->GetRoutingID()));
1507 } 1508 }
1508 } 1509 }
1509 } 1510 }
1510 1511
1511 } // namespace extensions 1512 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698