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

Unified Diff: content/renderer/render_view_impl.cc

Issue 10387074: Only disallow top-level navigations in platform apps (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nits Created 8 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
« no previous file with comments | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_view_impl.cc
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index ed32995b615b0071d3b8b68264c939335082662f..0d25a6bee04a704bccc902aefa401e525e773c75 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -389,6 +389,47 @@ static void MaybeHandleDebugURL(const GURL& url) {
}
}
+// Returns false unless this is a top-level navigation.
+static bool IsTopLevelNavigation(WebFrame* frame) {
+ return frame->parent() == NULL;
+}
+
+// Returns false unless this is a top-level navigation that crosses origins.
+static bool IsNonLocalTopLevelNavigation(const GURL& url,
+ WebFrame* frame,
+ WebNavigationType type) {
+ if (!IsTopLevelNavigation(frame))
+ return false;
+
+ // Navigations initiated within Webkit are not sent out to the external host
+ // in the following cases.
+ // 1. The url scheme is not http/https
+ // 2. The origin of the url and the opener is the same in which case the
+ // opener relationship is maintained.
+ // 3. Reloads/form submits/back forward navigations
+ if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme))
+ return false;
+
+ // Not interested in reloads/form submits/resubmits/back forward navigations.
+ if (type != WebKit::WebNavigationTypeReload &&
+ type != WebKit::WebNavigationTypeFormSubmitted &&
+ type != WebKit::WebNavigationTypeFormResubmitted &&
+ type != WebKit::WebNavigationTypeBackForward) {
+ // The opener relationship between the new window and the parent allows the
+ // new window to script the parent and vice versa. This is not allowed if
+ // the origins of the two domains are different. This can be treated as a
+ // top level navigation and routed back to the host.
+ WebKit::WebFrame* opener = frame->opener();
+ if (!opener) {
+ return true;
+ }
+
+ if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin())
+ return true;
+ }
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
struct RenderViewImpl::PendingFileChooser {
@@ -2375,14 +2416,18 @@ WebNavigationPolicy RenderViewImpl::decidePolicyForNavigation(
}
}
- // If the browser is interested, then give it a chance to look at top level
- // navigations.
+ // If the browser is interested, then give it a chance to look at the request.
if (is_content_initiated) {
- bool browser_handles_top_level_requests =
- renderer_preferences_.browser_handles_top_level_requests &&
+ bool browser_handles_request =
+ renderer_preferences_.browser_handles_non_local_top_level_requests &&
IsNonLocalTopLevelNavigation(url, frame, type);
- if (browser_handles_top_level_requests ||
- renderer_preferences_.browser_handles_all_requests) {
+ if (!browser_handles_request) {
+ browser_handles_request =
+ renderer_preferences_.browser_handles_all_top_level_requests &&
+ IsTopLevelNavigation(frame);
+ }
+
+ if (browser_handles_request) {
// Reset these counters as the RenderView could be reused for the next
// navigation.
page_id_ = -1;
@@ -5338,41 +5383,6 @@ WebKit::WebUserMediaClient* RenderViewImpl::userMediaClient() {
return media_stream_impl_;
}
-bool RenderViewImpl::IsNonLocalTopLevelNavigation(
- const GURL& url, WebKit::WebFrame* frame, WebKit::WebNavigationType type) {
- // Must be a top level frame.
- if (frame->parent() != NULL)
- return false;
-
- // Navigations initiated within Webkit are not sent out to the external host
- // in the following cases.
- // 1. The url scheme is not http/https
- // 2. The origin of the url and the opener is the same in which case the
- // opener relationship is maintained.
- // 3. Reloads/form submits/back forward navigations
- if (!url.SchemeIs(chrome::kHttpScheme) && !url.SchemeIs(chrome::kHttpsScheme))
- return false;
-
- // Not interested in reloads/form submits/resubmits/back forward navigations.
- if (type != WebKit::WebNavigationTypeReload &&
- type != WebKit::WebNavigationTypeFormSubmitted &&
- type != WebKit::WebNavigationTypeFormResubmitted &&
- type != WebKit::WebNavigationTypeBackForward) {
- // The opener relationship between the new window and the parent allows the
- // new window to script the parent and vice versa. This is not allowed if
- // the origins of the two domains are different. This can be treated as a
- // top level navigation and routed back to the host.
- WebKit::WebFrame* opener = frame->opener();
- if (!opener) {
- return true;
- } else {
- if (url.GetOrigin() != GURL(opener->document().url()).GetOrigin())
- return true;
- }
- }
- return false;
-}
-
void RenderViewImpl::OnAsyncFileOpened(
base::PlatformFileError error_code,
IPC::PlatformFileForTransit file_for_transit,
« no previous file with comments | « content/renderer/render_view_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698