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

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: Inline IsSandboxedPage check into dispatcher.cc with TODO 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
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/renderer/extensions/request_sender.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/strings/string_piece.h" 12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_split.h" 13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h" 14 #include "base/strings/string_util.h"
15 #include "chrome/common/child_process_logging.h" 15 #include "chrome/common/child_process_logging.h"
16 #include "chrome/common/chrome_switches.h" 16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/common/chrome_version_info.h" 17 #include "chrome/common/chrome_version_info.h"
18 #include "chrome/common/extensions/api/extension_api.h" 18 #include "chrome/common/extensions/api/extension_api.h"
19 #include "chrome/common/extensions/background_info.h" 19 #include "chrome/common/extensions/background_info.h"
20 #include "chrome/common/extensions/extension.h" 20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_manifest_constants.h" 21 #include "chrome/common/extensions/extension_manifest_constants.h"
22 #include "chrome/common/extensions/extension_messages.h" 22 #include "chrome/common/extensions/extension_messages.h"
23 #include "chrome/common/extensions/features/base_feature_provider.h" 23 #include "chrome/common/extensions/features/base_feature_provider.h"
24 #include "chrome/common/extensions/features/feature.h" 24 #include "chrome/common/extensions/features/feature.h"
25 #include "chrome/common/extensions/manifest.h" 25 #include "chrome/common/extensions/manifest.h"
26 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h" 26 #include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
27 #include "chrome/common/extensions/manifest_handlers/sandboxed_page_info.h"
27 #include "chrome/common/extensions/message_bundle.h" 28 #include "chrome/common/extensions/message_bundle.h"
28 #include "chrome/common/extensions/permissions/permission_set.h" 29 #include "chrome/common/extensions/permissions/permission_set.h"
29 #include "chrome/common/extensions/permissions/permissions_data.h" 30 #include "chrome/common/extensions/permissions/permissions_data.h"
30 #include "chrome/common/url_constants.h" 31 #include "chrome/common/url_constants.h"
31 #include "chrome/renderer/chrome_render_process_observer.h" 32 #include "chrome/renderer/chrome_render_process_observer.h"
32 #include "chrome/renderer/extensions/api_activity_logger.h" 33 #include "chrome/renderer/extensions/api_activity_logger.h"
33 #include "chrome/renderer/extensions/api_definitions_natives.h" 34 #include "chrome/renderer/extensions/api_definitions_natives.h"
34 #include "chrome/renderer/extensions/app_bindings.h" 35 #include "chrome/renderer/extensions/app_bindings.h"
35 #include "chrome/renderer/extensions/app_runtime_custom_bindings.h" 36 #include "chrome/renderer/extensions/app_runtime_custom_bindings.h"
36 #include "chrome/renderer/extensions/app_window_custom_bindings.h" 37 #include "chrome/renderer/extensions/app_window_custom_bindings.h"
(...skipping 29 matching lines...) Expand all
66 #include "chrome/renderer/extensions/tab_finder.h" 67 #include "chrome/renderer/extensions/tab_finder.h"
67 #include "chrome/renderer/extensions/tabs_custom_bindings.h" 68 #include "chrome/renderer/extensions/tabs_custom_bindings.h"
68 #include "chrome/renderer/extensions/tts_custom_bindings.h" 69 #include "chrome/renderer/extensions/tts_custom_bindings.h"
69 #include "chrome/renderer/extensions/user_script_slave.h" 70 #include "chrome/renderer/extensions/user_script_slave.h"
70 #include "chrome/renderer/extensions/web_request_custom_bindings.h" 71 #include "chrome/renderer/extensions/web_request_custom_bindings.h"
71 #include "chrome/renderer/extensions/webstore_bindings.h" 72 #include "chrome/renderer/extensions/webstore_bindings.h"
72 #include "chrome/renderer/resource_bundle_source_map.h" 73 #include "chrome/renderer/resource_bundle_source_map.h"
73 #include "content/public/renderer/render_thread.h" 74 #include "content/public/renderer/render_thread.h"
74 #include "content/public/renderer/render_view.h" 75 #include "content/public/renderer/render_view.h"
75 #include "content/public/renderer/v8_value_converter.h" 76 #include "content/public/renderer/v8_value_converter.h"
77 #include "extensions/common/constants.h"
76 #include "extensions/common/view_type.h" 78 #include "extensions/common/view_type.h"
77 #include "grit/common_resources.h" 79 #include "grit/common_resources.h"
78 #include "grit/renderer_resources.h" 80 #include "grit/renderer_resources.h"
79 #include "third_party/WebKit/public/platform/WebString.h" 81 #include "third_party/WebKit/public/platform/WebString.h"
80 #include "third_party/WebKit/public/platform/WebURLRequest.h" 82 #include "third_party/WebKit/public/platform/WebURLRequest.h"
81 #include "third_party/WebKit/public/web/WebDataSource.h" 83 #include "third_party/WebKit/public/web/WebDataSource.h"
82 #include "third_party/WebKit/public/web/WebDocument.h" 84 #include "third_party/WebKit/public/web/WebDocument.h"
83 #include "third_party/WebKit/public/web/WebFrame.h" 85 #include "third_party/WebKit/public/web/WebFrame.h"
84 #include "third_party/WebKit/public/web/WebScopedUserGesture.h" 86 #include "third_party/WebKit/public/web/WebScopedUserGesture.h"
85 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" 87 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 // CSP blocks extension page loading by switching the extension ID to 1010 // CSP blocks extension page loading by switching the extension ID to
1009 // "invalid". This isn't interesting. 1011 // "invalid". This isn't interesting.
1010 if (extension_id != "invalid") { 1012 if (extension_id != "invalid") {
1011 LOG(ERROR) << "Extension \"" << extension_id << "\" not found"; 1013 LOG(ERROR) << "Extension \"" << extension_id << "\" not found";
1012 RenderThread::Get()->RecordUserMetrics("ExtensionNotFound_ED"); 1014 RenderThread::Get()->RecordUserMetrics("ExtensionNotFound_ED");
1013 } 1015 }
1014 1016
1015 extension_id = ""; 1017 extension_id = "";
1016 } 1018 }
1017 1019
1018 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1020 // Frames loaded on a unique security origin are not accessible to extensions.
1019 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1021 GURL effective_frame_url;
1022 if (!frame->document().securityOrigin().isUnique())
1023 effective_frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
not at google - send to devlin 2013/07/17 23:48:24 It's not clear to me why this change is equivalent
jamesr 2013/07/18 00:12:13 Good point. Adding the parameter
1020 1024
1021 Feature::Context context_type = 1025 Feature::Context context_type = ClassifyJavaScriptContext(
1022 ClassifyJavaScriptContext(extension_id, extension_group, url_info); 1026 extension_id, extension_group, effective_frame_url);
1023 1027
1024 ChromeV8Context* context = 1028 ChromeV8Context* context =
1025 new ChromeV8Context(v8_context, frame, extension, context_type); 1029 new ChromeV8Context(v8_context, frame, extension, context_type);
1026 v8_context_set_.Add(context); 1030 v8_context_set_.Add(context);
1027 1031
1028 { 1032 {
1029 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context, 1033 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context,
1030 &source_map_)); 1034 &source_map_));
1031 context->set_module_system(module_system.Pass()); 1035 context->set_module_system(module_system.Pass());
1032 } 1036 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 1124
1121 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); 1125 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
1122 } 1126 }
1123 1127
1124 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) { 1128 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) {
1125 if (world_id != 0) { 1129 if (world_id != 0) {
1126 // Isolated worlds (content script). 1130 // Isolated worlds (content script).
1127 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); 1131 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
1128 } 1132 }
1129 1133
1134 if (frame->document().securityOrigin().isUnique())
not at google - send to devlin 2013/07/17 23:48:24 TODO(kalman): delete me.
jamesr 2013/07/18 00:12:13 Done.
1135 return std::string();
1136
1130 // Extension pages (chrome-extension:// URLs). 1137 // Extension pages (chrome-extension:// URLs).
1131 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame); 1138 GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
1132 return extensions_.GetExtensionOrAppIDByURL( 1139 return extensions_.GetExtensionOrAppIDByURL(frame_url);
1133 ExtensionURLInfo(frame->document().securityOrigin(), frame_url));
1134 } 1140 }
1135 1141
1136 bool Dispatcher::IsWithinPlatformApp(const WebFrame* frame) { 1142 bool Dispatcher::IsWithinPlatformApp(const WebFrame* frame) {
1137 // We intentionally don't use the origin parameter for ExtensionURLInfo since 1143 GURL url(UserScriptSlave::GetDataSourceURLForFrame(frame->top()));
1138 // it would be empty (i.e. unique) for sandboxed resources and thus not match. 1144 const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
1139 ExtensionURLInfo url_info(
1140 UserScriptSlave::GetDataSourceURLForFrame(frame->top()));
1141 const Extension* extension = extensions_.GetExtensionOrAppByURL(url_info);
1142 1145
1143 return extension && extension->is_platform_app(); 1146 return extension && extension->is_platform_app();
1144 } 1147 }
1145 1148
1146 void Dispatcher::WillReleaseScriptContext( 1149 void Dispatcher::WillReleaseScriptContext(
1147 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { 1150 WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
1148 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context); 1151 ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context);
1149 if (!context) 1152 if (!context)
1150 return; 1153 return;
1151 1154
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 // that it still considers the extension idle despite any activity the suspend 1371 // that it still considers the extension idle despite any activity the suspend
1369 // event creates. 1372 // event creates.
1370 DispatchEvent(extension_id, kOnSuspendEvent); 1373 DispatchEvent(extension_id, kOnSuspendEvent);
1371 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); 1374 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id));
1372 } 1375 }
1373 1376
1374 void Dispatcher::OnCancelSuspend(const std::string& extension_id) { 1377 void Dispatcher::OnCancelSuspend(const std::string& extension_id) {
1375 DispatchEvent(extension_id, kOnSuspendCanceledEvent); 1378 DispatchEvent(extension_id, kOnSuspendCanceledEvent);
1376 } 1379 }
1377 1380
1381 // TODO(kalman): This is checking for the wrong thing, it should be checking if
1382 // the frame's security origin is unique. The extension sandbox directive is
1383 // checked for in chrome/common/extensions/csp_handler.cc.
1384 bool Dispatcher::IsSandboxedPage(const GURL& url) const {
1385 if (url.SchemeIs(extensions::kExtensionScheme)) {
1386 const Extension* extension = extensions_.GetByID(url.host());
1387 if (extension) {
1388 return extensions::SandboxedPageInfo::IsSandboxedPage(extension,
1389 url.path());
1390 }
1391 }
1392 return false;
1393 }
1394
1378 Feature::Context Dispatcher::ClassifyJavaScriptContext( 1395 Feature::Context Dispatcher::ClassifyJavaScriptContext(
1379 const std::string& extension_id, 1396 const std::string& extension_id,
1380 int extension_group, 1397 int extension_group,
1381 const ExtensionURLInfo& url_info) { 1398 const GURL& url) {
1382 DCHECK_GE(extension_group, 0); 1399 DCHECK_GE(extension_group, 0);
1383 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { 1400 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
1384 return extensions_.Contains(extension_id) ? 1401 return extensions_.Contains(extension_id) ?
1385 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1402 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1386 } 1403 }
1387 1404
1388 // We have an explicit check for sandboxed pages before checking whether the 1405 // We have an explicit check for sandboxed pages before checking whether the
1389 // extension is active in this process because: 1406 // extension is active in this process because:
1390 // 1. Sandboxed pages run in the same process as regular extension pages, so 1407 // 1. Sandboxed pages run in the same process as regular extension pages, so
1391 // the extension is considered active. 1408 // the extension is considered active.
1392 // 2. ScriptContext creation (which triggers bindings injection) happens 1409 // 2. ScriptContext creation (which triggers bindings injection) happens
1393 // before the SecurityContext is updated with the sandbox flags (after 1410 // before the SecurityContext is updated with the sandbox flags (after
1394 // reading the CSP header), so url_info.url().securityOrigin() is not 1411 // reading the CSP header), so the caller can't check if the context's
1395 // unique yet. 1412 // security origin is unique yet.
1396 if (extensions_.IsSandboxedPage(url_info)) 1413 if (IsSandboxedPage(url))
1397 return Feature::WEB_PAGE_CONTEXT; 1414 return Feature::WEB_PAGE_CONTEXT;
1398 1415
1399 if (IsExtensionActive(extension_id)) 1416 if (IsExtensionActive(extension_id))
1400 return Feature::BLESSED_EXTENSION_CONTEXT; 1417 return Feature::BLESSED_EXTENSION_CONTEXT;
1401 1418
1402 if (extensions_.ExtensionBindingsAllowed(url_info)) { 1419 if (extensions_.ExtensionBindingsAllowed(url)) {
not at google - send to devlin 2013/07/17 23:48:24 and then this would be if (!origin.isUnique() &&
jamesr 2013/07/18 00:12:13 ..and checked it here, with a TODO(kalman) to take
1403 return extensions_.Contains(extension_id) ? 1420 return extensions_.Contains(extension_id) ?
1404 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1421 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1405 } 1422 }
1406 1423
1407 if (url_info.url().is_valid()) 1424 if (url.is_valid())
1408 return Feature::WEB_PAGE_CONTEXT; 1425 return Feature::WEB_PAGE_CONTEXT;
1409 1426
1410 return Feature::UNSPECIFIED_CONTEXT; 1427 return Feature::UNSPECIFIED_CONTEXT;
1411 } 1428 }
1412 1429
1413 void Dispatcher::OnExtensionResponse(int request_id, 1430 void Dispatcher::OnExtensionResponse(int request_id,
1414 bool success, 1431 bool success,
1415 const base::ListValue& response, 1432 const base::ListValue& response,
1416 const std::string& error) { 1433 const std::string& error) {
1417 request_sender_->HandleResponse(request_id, success, response, error); 1434 request_sender_->HandleResponse(request_id, success, response, error);
1418 } 1435 }
1419 1436
1420 bool Dispatcher::CheckContextAccessToExtensionAPI( 1437 bool Dispatcher::CheckContextAccessToExtensionAPI(
1421 const std::string& function_name, ChromeV8Context* context) const { 1438 const std::string& function_name, ChromeV8Context* context) const {
1422 if (!context) { 1439 if (!context) {
1423 DLOG(ERROR) << "Not in a v8::Context"; 1440 DLOG(ERROR) << "Not in a v8::Context";
1424 return false; 1441 return false;
1425 } 1442 }
1426 1443
1427 if (!context->extension()) { 1444 if (!context->extension()) {
1428 v8::ThrowException( 1445 v8::ThrowException(
1429 v8::Exception::Error(v8::String::New("Not in an extension."))); 1446 v8::Exception::Error(v8::String::New("Not in an extension.")));
1430 return false; 1447 return false;
1431 } 1448 }
1432 1449
1433 // Theoretically we could end up with bindings being injected into sandboxed 1450 // Theoretically we could end up with bindings being injected into sandboxed
1434 // frames, for example content scripts. Don't let them execute API functions. 1451 // frames, for example content scripts. Don't let them execute API functions.
1435 WebKit::WebFrame* frame = context->web_frame(); 1452 WebKit::WebFrame* frame = context->web_frame();
1436 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1453 if (frame->document().securityOrigin().isUnique() ||
not at google - send to devlin 2013/07/17 23:48:24 the isUnique() check here doesn't maintain the exi
jamesr 2013/07/18 00:12:13 Right, removed.
1437 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1454 IsSandboxedPage(UserScriptSlave::GetDataSourceURLForFrame(frame))) {
1438 if (extensions_.IsSandboxedPage(url_info)) {
1439 static const char kMessage[] = 1455 static const char kMessage[] =
1440 "%s cannot be used within a sandboxed frame."; 1456 "%s cannot be used within a sandboxed frame.";
1441 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); 1457 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str());
1442 v8::ThrowException( 1458 v8::ThrowException(
1443 v8::Exception::Error(v8::String::New(error_msg.c_str()))); 1459 v8::Exception::Error(v8::String::New(error_msg.c_str())));
1444 return false; 1460 return false;
1445 } 1461 }
1446 1462
1447 Feature::Availability availability = context->GetAvailability(function_name); 1463 Feature::Availability availability = context->GetAvailability(function_name);
1448 if (!availability.is_available()) { 1464 if (!availability.is_available()) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 RenderView* background_view = 1518 RenderView* background_view =
1503 ExtensionHelper::GetBackgroundPage(extension_id); 1519 ExtensionHelper::GetBackgroundPage(extension_id);
1504 if (background_view) { 1520 if (background_view) {
1505 background_view->Send(new ExtensionHostMsg_EventAck( 1521 background_view->Send(new ExtensionHostMsg_EventAck(
1506 background_view->GetRoutingID())); 1522 background_view->GetRoutingID()));
1507 } 1523 }
1508 } 1524 }
1509 } 1525 }
1510 1526
1511 } // namespace extensions 1527 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/dispatcher.h ('k') | chrome/renderer/extensions/request_sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698