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

Unified Diff: chrome/renderer/extensions/user_script_slave.cc

Issue 7071025: Use WebFrame::setIsolatedWorldSecurityOrigin to allow cross-origin XHRs in content scripts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove ExtensionOriginEntry Created 9 years, 7 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 side-by-side diff with in-line comments
Download patch
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 b8309ac74042484ad7ec7d5694f870a5cc8f8855..e9fa98837c4015bf2105ab248ab683ba289d5773 100644
--- a/chrome/renderer/extensions/user_script_slave.cc
+++ b/chrome/renderer/extensions/user_script_slave.cc
@@ -17,15 +17,20 @@
#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/chrome_render_process_observer.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_groups.h"
#include "googleurl/src/gurl.h"
#include "grit/renderer_resources.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "ui/base/resource/resource_bundle.h"
using WebKit::WebFrame;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebSecurityPolicy;
using WebKit::WebString;
using WebKit::WebVector;
using WebKit::WebView;
@@ -40,7 +45,6 @@ static const char kUserScriptTail[] = "\n})(window);";
static const char kInitExtension[] =
"if (chrome.initExtension) chrome.initExtension('%s', true, %s);";
-
int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) {
typedef std::map<std::string, int> IsolatedWorldMap;
@@ -60,6 +64,86 @@ int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) {
return new_id;
}
+// Associates the extension's isolated world with the extension's URL as the
+// origin, and whitelists that origin to have access to 1) the current frame's
+// origin 2) origins whitelisted in host permission.
+// Unlike the whitelisting done in the extension process by
+// ExtensionDispatcher::InitHostPermissions, this is more complex because the
+// 1) the current frame's origin changes as the page is navigated 2) the set of
+// extensions may change as they are loaded, unloaded and reloaded.
+// To solve 1), we keep track of the last origin that we whitelisted for a
+// frame, and un-whitelist it when getting a new one. To solve 2), we keep track
+// of what host permission origins we've already whitelisted, and don't
+// whitelist them again. This means that if an extension is reloaded with fewer
+// host permissions we will not remove now-obsolete permissions.
+void UserScriptSlave::InitializeIsolatedWorld(
Matt Perry 2011/05/27 19:10:54 This seems like a lot of effort to work around def
+ WebFrame* frame,
+ int isolated_world_id,
+ const Extension* extension) {
+ frame->setIsolatedWorldSecurityOrigin(
+ isolated_world_id,
+ WebSecurityOrigin::create(extension->url()));
+
+ // We always have access to the origin of the frame that we're injecting in.
+ FrameOriginMap::iterator iter = frame_origins_.find(frame->identifier());
+ if (iter != frame_origins_.end()) {
+ std::pair<std::string, std::string> frame_origin = iter->second;
+ WebSecurityPolicy::removeOriginAccessWhitelistEntry(
+ extension->url(),
+ WebString::fromUTF8(frame_origin.first),
+ WebString::fromUTF8(frame_origin.second),
+ false); // do not match subdomains
+ }
+
+ GURL frame_url = GURL(frame->url());
+ WebSecurityPolicy::addOriginAccessWhitelistEntry(
+ extension->url(),
+ WebString::fromUTF8(frame_url.scheme()),
+ WebString::fromUTF8(frame_url.host()),
+ false); // do not match subdomains
+ frame_origins_[frame->identifier()] =
+ std::pair<std::string, std::string>(frame_url.scheme(), frame_url.host());
+
+ const URLPatternList& permissions = extension->host_permissions();
+ for (size_t i = 0; i < permissions.size(); ++i) {
+ const URLPattern& permission = permissions[i];
+
+ bool already_whitelisted = false;
+ ExtensionOriginMap::iterator iter =
+ extension_origins_.find(extension->id());
+ ExtensionOriginMap::iterator end =
+ extension_origins_.upper_bound(extension->id());
+ for (; iter != end; ++iter) {
+ if (iter->second.scheme() == permission.scheme() &&
+ iter->second.host() == permission.host() &&
+ iter->second.match_subdomains() == permission.match_subdomains()) {
+ already_whitelisted = true;
+ break;
+ }
+ }
+ if (already_whitelisted) continue;
+
+ extension_origins_.insert(
+ std::pair<std::string, URLPattern>(extension->id(), permission));
+
+ const char* schemes[] = {
+ chrome::kHttpScheme,
+ chrome::kHttpsScheme,
+ chrome::kFileScheme,
+ chrome::kChromeUIScheme,
+ };
+ for (size_t j = 0; j < arraysize(schemes); ++j) {
+ if (permission.MatchesScheme(schemes[j])) {
+ WebSecurityPolicy::addOriginAccessWhitelistEntry(
+ extension->url(),
+ WebString::fromUTF8(schemes[j]),
+ WebString::fromUTF8(permission.host()),
+ permission.match_subdomains());
+ }
+ }
+ }
+}
+
UserScriptSlave::UserScriptSlave(const ExtensionSet* extensions)
: shared_memory_(NULL),
script_deleter_(&scripts_),
@@ -249,6 +333,7 @@ void UserScriptSlave::InjectScripts(WebFrame* frame,
if (!script->extension_id().empty()) {
InsertInitExtensionCode(&sources, script->extension_id());
isolated_world_id = GetIsolatedWorldId(script->extension_id());
+ InitializeIsolatedWorld(frame, isolated_world_id, extension);
}
PerfTimer exec_timer;

Powered by Google App Engine
This is Rietveld 408576698