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

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: address 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
« 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 Feature::Context context_type = ClassifyJavaScriptContext(
1019 UserScriptSlave::GetDataSourceURLForFrame(frame)); 1021 extension_id, extension_group,
1020 1022 UserScriptSlave::GetDataSourceURLForFrame(frame),
1021 Feature::Context context_type = 1023 frame->document().securityOrigin());
1022 ClassifyJavaScriptContext(extension_id, extension_group, url_info);
1023 1024
1024 ChromeV8Context* context = 1025 ChromeV8Context* context =
1025 new ChromeV8Context(v8_context, frame, extension, context_type); 1026 new ChromeV8Context(v8_context, frame, extension, context_type);
1026 v8_context_set_.Add(context); 1027 v8_context_set_.Add(context);
1027 1028
1028 { 1029 {
1029 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context, 1030 scoped_ptr<ModuleSystem> module_system(new ModuleSystem(context,
1030 &source_map_)); 1031 &source_map_));
1031 context->set_module_system(module_system.Pass()); 1032 context->set_module_system(module_system.Pass());
1032 } 1033 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 1121
1121 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); 1122 VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
1122 } 1123 }
1123 1124
1124 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) { 1125 std::string Dispatcher::GetExtensionID(const WebFrame* frame, int world_id) {
1125 if (world_id != 0) { 1126 if (world_id != 0) {
1126 // Isolated worlds (content script). 1127 // Isolated worlds (content script).
1127 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id); 1128 return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
1128 } 1129 }
1129 1130
1131 // TODO(kalman): Delete this check.
1132 if (frame->document().securityOrigin().isUnique())
1133 return std::string();
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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
1368 // that it still considers the extension idle despite any activity the suspend 1369 // that it still considers the extension idle despite any activity the suspend
1369 // event creates. 1370 // event creates.
1370 DispatchEvent(extension_id, kOnSuspendEvent); 1371 DispatchEvent(extension_id, kOnSuspendEvent);
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
1379 // TODO(kalman): This is checking for the wrong thing, it should be checking if
1380 // the frame's security origin is unique. The extension sandbox directive is
1381 // checked for in chrome/common/extensions/csp_handler.cc.
1382 bool Dispatcher::IsSandboxedPage(const GURL& url) const {
1383 if (url.SchemeIs(extensions::kExtensionScheme)) {
1384 const Extension* extension = extensions_.GetByID(url.host());
1385 if (extension) {
1386 return extensions::SandboxedPageInfo::IsSandboxedPage(extension,
1387 url.path());
1388 }
1389 }
1390 return false;
1391 }
1392
1378 Feature::Context Dispatcher::ClassifyJavaScriptContext( 1393 Feature::Context Dispatcher::ClassifyJavaScriptContext(
1379 const std::string& extension_id, 1394 const std::string& extension_id,
1380 int extension_group, 1395 int extension_group,
1381 const ExtensionURLInfo& url_info) { 1396 const GURL& url,
1397 const WebKit::WebSecurityOrigin& origin) {
1382 DCHECK_GE(extension_group, 0); 1398 DCHECK_GE(extension_group, 0);
1383 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { 1399 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) {
1384 return extensions_.Contains(extension_id) ? 1400 return extensions_.Contains(extension_id) ?
1385 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1401 Feature::CONTENT_SCRIPT_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1386 } 1402 }
1387 1403
1388 // We have an explicit check for sandboxed pages before checking whether the 1404 // We have an explicit check for sandboxed pages before checking whether the
1389 // extension is active in this process because: 1405 // extension is active in this process because:
1390 // 1. Sandboxed pages run in the same process as regular extension pages, so 1406 // 1. Sandboxed pages run in the same process as regular extension pages, so
1391 // the extension is considered active. 1407 // the extension is considered active.
1392 // 2. ScriptContext creation (which triggers bindings injection) happens 1408 // 2. ScriptContext creation (which triggers bindings injection) happens
1393 // before the SecurityContext is updated with the sandbox flags (after 1409 // before the SecurityContext is updated with the sandbox flags (after
1394 // reading the CSP header), so url_info.url().securityOrigin() is not 1410 // reading the CSP header), so the caller can't check if the context's
1395 // unique yet. 1411 // security origin is unique yet.
1396 if (extensions_.IsSandboxedPage(url_info)) 1412 if (IsSandboxedPage(url))
1397 return Feature::WEB_PAGE_CONTEXT; 1413 return Feature::WEB_PAGE_CONTEXT;
1398 1414
1399 if (IsExtensionActive(extension_id)) 1415 if (IsExtensionActive(extension_id))
1400 return Feature::BLESSED_EXTENSION_CONTEXT; 1416 return Feature::BLESSED_EXTENSION_CONTEXT;
1401 1417
1402 if (extensions_.ExtensionBindingsAllowed(url_info)) { 1418 // TODO(kalman): This isUnique() check is wrong, it should be performed as
1419 // part of IsSandboxedPage().
1420 if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) {
1403 return extensions_.Contains(extension_id) ? 1421 return extensions_.Contains(extension_id) ?
1404 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT; 1422 Feature::UNBLESSED_EXTENSION_CONTEXT : Feature::UNSPECIFIED_CONTEXT;
1405 } 1423 }
1406 1424
1407 if (url_info.url().is_valid()) 1425 if (url.is_valid())
1408 return Feature::WEB_PAGE_CONTEXT; 1426 return Feature::WEB_PAGE_CONTEXT;
1409 1427
1410 return Feature::UNSPECIFIED_CONTEXT; 1428 return Feature::UNSPECIFIED_CONTEXT;
1411 } 1429 }
1412 1430
1413 void Dispatcher::OnExtensionResponse(int request_id, 1431 void Dispatcher::OnExtensionResponse(int request_id,
1414 bool success, 1432 bool success,
1415 const base::ListValue& response, 1433 const base::ListValue& response,
1416 const std::string& error) { 1434 const std::string& error) {
1417 request_sender_->HandleResponse(request_id, success, response, error); 1435 request_sender_->HandleResponse(request_id, success, response, error);
1418 } 1436 }
1419 1437
1420 bool Dispatcher::CheckContextAccessToExtensionAPI( 1438 bool Dispatcher::CheckContextAccessToExtensionAPI(
1421 const std::string& function_name, ChromeV8Context* context) const { 1439 const std::string& function_name, ChromeV8Context* context) const {
1422 if (!context) { 1440 if (!context) {
1423 DLOG(ERROR) << "Not in a v8::Context"; 1441 DLOG(ERROR) << "Not in a v8::Context";
1424 return false; 1442 return false;
1425 } 1443 }
1426 1444
1427 if (!context->extension()) { 1445 if (!context->extension()) {
1428 v8::ThrowException( 1446 v8::ThrowException(
1429 v8::Exception::Error(v8::String::New("Not in an extension."))); 1447 v8::Exception::Error(v8::String::New("Not in an extension.")));
1430 return false; 1448 return false;
1431 } 1449 }
1432 1450
1433 // Theoretically we could end up with bindings being injected into sandboxed 1451 // Theoretically we could end up with bindings being injected into sandboxed
1434 // frames, for example content scripts. Don't let them execute API functions. 1452 // frames, for example content scripts. Don't let them execute API functions.
1435 WebKit::WebFrame* frame = context->web_frame(); 1453 WebKit::WebFrame* frame = context->web_frame();
1436 ExtensionURLInfo url_info(frame->document().securityOrigin(), 1454 if (IsSandboxedPage(UserScriptSlave::GetDataSourceURLForFrame(frame))) {
1437 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