summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/chrome_content_renderer_client.cc
diff options
context:
space:
mode:
authorcreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-18 23:10:36 +0000
committercreis@chromium.org <creis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-18 23:10:36 +0000
commitd55c2380d728c2cc29c1a84970bb1d6f51c397d7 (patch)
treef7167d1248c238ea04ae8a6330da6051057876d6 /chrome/renderer/chrome_content_renderer_client.cc
parenta1d2673933968789af8dcab150ecd065deed9000 (diff)
downloadchromium_src-d55c2380d728c2cc29c1a84970bb1d6f51c397d7.zip
chromium_src-d55c2380d728c2cc29c1a84970bb1d6f51c397d7.tar.gz
chromium_src-d55c2380d728c2cc29c1a84970bb1d6f51c397d7.tar.bz2
Keep normal popups opened from same-origin iframes in an extension process.
This allows the iframe to script the popup, despite being in an extension. Also use safer logic for detecting the popup case. BUG=92669 BUG=87417 TEST=Open a popup from a web iframe inside an extension page and script it. Review URL: http://codereview.chromium.org/7624011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97386 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer/chrome_content_renderer_client.cc')
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc41
1 files changed, 30 insertions, 11 deletions
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 614835e..25ae18d 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -72,6 +72,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.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/WebURL.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
@@ -89,8 +90,10 @@ using WebKit::WebDataSource;
using WebKit::WebFrame;
using WebKit::WebPlugin;
using WebKit::WebPluginParams;
+using WebKit::WebSecurityOrigin;
using WebKit::WebSecurityPolicy;
using WebKit::WebString;
+using WebKit::WebURL;
using WebKit::WebURLError;
using WebKit::WebURLRequest;
using WebKit::WebURLResponse;
@@ -574,13 +577,14 @@ bool ChromeContentRendererClient::AllowPopup(const GURL& creator) {
bool ChromeContentRendererClient::ShouldFork(WebFrame* frame,
const GURL& url,
bool is_content_initiated,
+ bool is_initial_navigation,
bool* send_referrer) {
// If the navigation would cross an app extent boundary, we also need
// to defer to the browser to ensure process isolation.
// TODO(erikkay) This is happening inside of a check to is_content_initiated
// which means that things like the back button won't trigger it. Is that
// OK?
- if (!CrossesExtensionExtents(frame, url))
+ if (!CrossesExtensionExtents(frame, url, is_initial_navigation))
return false;
// Include the referrer in this case since we're going from a hosted web
@@ -682,25 +686,40 @@ void ChromeContentRendererClient::SetExtensionDispatcher(
extension_dispatcher_.reset(extension_dispatcher);
}
-bool ChromeContentRendererClient::CrossesExtensionExtents(WebFrame* frame,
- const GURL& new_url) {
+bool ChromeContentRendererClient::CrossesExtensionExtents(
+ WebFrame* frame,
+ const GURL& new_url,
+ bool is_initial_navigation) {
const ExtensionSet* extensions = extension_dispatcher_->extensions();
- // If the URL is still empty, this is a window.open navigation. Check the
- // opener's URL. In all cases we use the top frame's URL (as opposed to our
- // frame's) since that's what determines the type of process.
- // TODO(abarth): This code is super sketchy! Are you sure looking at the
- // opener is correct here? This appears to let me steal my opener's
- // privileges if I can make my URL be "empty."
+ bool is_extension_url = !!extensions->GetByURL(new_url);
GURL old_url(frame->top()->document().url());
- if (old_url.is_empty() && frame->opener())
+
+ // If old_url is still empty and this is an initial navigation, then this is
+ // a window.open operation. We should look at the opener URL.
+ if (is_initial_navigation && old_url.is_empty() && frame->opener()) {
+ // If we're about to open a normal web page from a same-origin opener stuck
+ // in an extension process, we want to keep it in process to allow the
+ // opener to script it.
+ GURL opener_url = frame->opener()->document().url();
+ bool opener_is_extension_url = !!extensions->GetByURL(opener_url);
+ WebSecurityOrigin opener = frame->opener()->document().securityOrigin();
+ if (!is_extension_url &&
+ !opener_is_extension_url &&
+ extension_dispatcher_->is_extension_process() &&
+ opener.canRequest(WebURL(new_url)))
+ return false;
+
+ // In all other cases, we want to compare against the top frame's URL (as
+ // opposed to the opener frame's), since that's what determines the type of
+ // process. This allows iframes outside an app to open a popup in the app.
old_url = frame->top()->opener()->top()->document().url();
+ }
// If this is a reload, check whether it has the wrong process type. We
// should send it to the browser if it's an extension URL (e.g., hosted app)
// in a normal process, or if it's a process for an extension that has been
// uninstalled.
if (old_url == new_url) {
- bool is_extension_url = !!extensions->GetByURL(new_url);
if (is_extension_url != extension_dispatcher_->is_extension_process())
return true;
}