Index: chrome/renderer/extensions/user_script_slave.cc |
diff --git a/chrome/renderer/extensions/user_script_slave.cc b/chrome/renderer/extensions/user_script_slave.cc |
index bdaff10bb86692bbe69c3f3e69cadc438f90067c..95c29e391701fa4dab4e2ea2ceefbdcb2b4c7192 100644 |
--- a/chrome/renderer/extensions/user_script_slave.cc |
+++ b/chrome/renderer/extensions/user_script_slave.cc |
@@ -38,6 +38,7 @@ |
#include "url/gurl.h" |
using blink::WebFrame; |
+using blink::WebDocument; |
using blink::WebSecurityOrigin; |
using blink::WebSecurityPolicy; |
using blink::WebString; |
@@ -194,6 +195,35 @@ GURL UserScriptSlave::GetDataSourceURLForFrame(const WebFrame* frame) { |
return GURL(data_source->request().url()); |
} |
+GURL UserScriptSlave::GetEffectiveDocumentURL(const WebFrame* frame, |
+ const GURL& document_url, |
+ bool match_about_blank) { |
+ // Common scenario. If |match_about_blank| is false (as is the case in most |
+ // extensions), or if the frame is not an about:-page, just return |
+ // |document_url| (supposedly the URL of the frame). |
+ if (!match_about_blank || !document_url.SchemeIs(content::kAboutScheme)) |
+ return document_url; |
+ |
+ // Non-sandboxed about:blank and about:srcdoc pages inherit their security |
+ // origin from their parent frame/window. So, traverse the frame/window |
+ // hierarchy to find the closest non-about:-page and return its URL. |
+ const WebFrame* parent = frame; |
+ const WebSecurityOrigin security_origin = frame->document().securityOrigin(); |
+ do { |
+ parent = parent->parent() ? parent->parent() : parent->opener(); |
+ if (parent != NULL) { |
+ const WebDocument& parent_document = parent->document(); |
+ if (security_origin.canAccess(parent_document.securityOrigin())) { |
dcheng
2014/05/08 00:26:05
Hm. Sorry, I think I confused myself when I was re
robwu
2014/05/08 12:44:10
No need to apology, you were right. Consider the f
dcheng
2014/05/09 01:18:50
I don't think we actually exit early =)
But what
robwu
2014/05/09 08:52:21
Ah, of course, because the sandbox is also inherit
|
+ GURL parent_document_url(parent_document.url()); |
+ if (!parent_document_url.SchemeIs(content::kAboutScheme)) |
+ return parent_document_url; |
+ } |
+ } |
+ } while (parent != NULL); |
+ |
+ return document_url; |
+} |
+ |
void UserScriptSlave::InjectScripts(WebFrame* frame, |
UserScript::RunLocation location) { |
GURL data_source_url = GetDataSourceURLForFrame(frame); |
@@ -224,12 +254,15 @@ void UserScriptSlave::InjectScripts(WebFrame* frame, |
if (!extension) |
continue; |
+ const GURL& document_url = GetEffectiveDocumentURL( |
+ frame, data_source_url, script->match_about_blank()); |
+ |
// Content scripts are not tab-specific. |
const int kNoTabId = -1; |
// We don't have a process id in this context. |
const int kNoProcessId = -1; |
if (!PermissionsData::CanExecuteScriptOnPage(extension, |
- data_source_url, |
+ document_url, |
frame->top()->document().url(), |
kNoTabId, |
script, |