Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |