| Index: content/browser/frame_host/navigation_controller_impl.cc
|
| diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
|
| index cfd1310b33122f1781d3ff4d923d0c5238d285c6..cb69349ee7b6c77a0d5061015092465c1e589fb3 100644
|
| --- a/content/browser/frame_host/navigation_controller_impl.cc
|
| +++ b/content/browser/frame_host/navigation_controller_impl.cc
|
| @@ -87,6 +87,50 @@
|
| namespace content {
|
| namespace {
|
|
|
| +// Determine if the current page and the destination page could belong to the
|
| +// same origin, in the given |rfh|. This is useful in cases like in-page
|
| +// navigations that can't be cross-origin, but may look cross-origin at first
|
| +// glance in some cases (e.g., about:blank to a web URL, or file:// to web URL
|
| +// when universal access is granted to files).
|
| +//
|
| +// To resolve these, we can use url::Origin to ensure the actual origin isn't
|
| +// changing. However, we also fall back to GURL::GetOrigin() to let a current
|
| +// and destination unique origin return true, since unique url::Origins don't
|
| +// appear equal to themselves.
|
| +//
|
| +// TODO(creis): Clarify that this shouldn't be used to determine script access.
|
| +bool CouldBeSameOrigin(const GURL& current_url,
|
| + const url::Origin& current_origin,
|
| + const GURL& dest_url,
|
| + const url::Origin& dest_origin,
|
| + const WebPreferences& prefs) {
|
| + // We don't care if web security is disabled.
|
| + if (!prefs.web_security_enabled)
|
| + return true;
|
| +
|
| + // File URLs may have been granted universal access to any URL.
|
| + if (prefs.allow_universal_access_from_file_urls &&
|
| + current_origin.scheme() == url::kFileScheme)
|
| + return true;
|
| +
|
| + // It's possible for the URLs to look different but the url::Origins to match,
|
| + // such as when about:blank inherits its origin from a web page.
|
| + if (current_origin == dest_origin)
|
| + return true;
|
| +
|
| + // For unique origins like data: URLs, they won't appear equal to themselves.
|
| + //
|
| + // TODO(creis): Data URLs to/from about:blank, which fail url::Origin check.
|
| + // TODO(creis): Other unique origins that can do in-page, like data->data.
|
| + // TODO(creis): This is bad for sandboxed iframe URLs. Only return true if
|
| + // both url::Origins are unique. Test this.
|
| + //if (current_url.GetOrigin() == dest_url.GetOrigin())
|
| + if (current_origin.unique() && dest_origin.unique())
|
| + return true;
|
| +
|
| + return false;
|
| +}
|
| +
|
| // Invoked when entries have been pruned, or removed. For example, if the
|
| // current entries are [google, digg, yahoo], with the current entry google,
|
| // and the user types in cnet, then digg and yahoo are pruned.
|
| @@ -1306,8 +1350,28 @@ bool NavigationControllerImpl::RendererDidNavigateAutoSubframe(
|
| // origin. Otherwise the renderer process may be confused, leading to a
|
| // URL spoof. We can't check the path since that may change
|
| // (https://crbug.com/373041).
|
| - if (GetLastCommittedEntry()->GetURL().GetOrigin() !=
|
| - GetEntryAtIndex(entry_index)->GetURL().GetOrigin()) {
|
| +// RenderFrameHostImpl* main_frame =
|
| +// delegate_->GetFrameTree()->root()->current_frame_host();
|
| + GURL dest_top_url = GetEntryAtIndex(entry_index)->GetURL();
|
| + GURL current_top_url = GetLastCommittedEntry()->GetURL();
|
| + GURL blank_url(url::kAboutBlankURL);
|
| + url::Origin current_origin =
|
| + delegate_->GetFrameTree()->root()->current_origin();
|
| +
|
| + // Allow about:blank to be the current or destination origin, beyond the
|
| + // other checks in CouldBeSameOrigin. We can't verify the about:blank
|
| + // cases any more strictly, since we don't know the destination origin.
|
| + // TODO(creis): If we track url::Origin on NavigationEntry, we might be
|
| + // able to call IsUrlInPageNavigation here instead, to share code.
|
| + bool could_be_same_origin =
|
| + dest_top_url == blank_url ||
|
| + // TODO(creis): This part isn't needed, due to the constructed origin.
|
| + //(current_top_url == blank_url &&
|
| + // dest_top_url.GetOrigin() == GURL(current_origin.Serialize())) ||
|
| + CouldBeSameOrigin(current_top_url, current_origin,
|
| + dest_top_url, url::Origin(dest_top_url),
|
| + rfh->GetRenderViewHost()->GetWebkitPreferences());
|
| + if (!could_be_same_origin) {
|
| bad_message::ReceivedBadMessage(rfh->GetProcess(),
|
| bad_message::NC_AUTO_SUBFRAME);
|
| }
|
| @@ -1397,7 +1461,9 @@ bool NavigationControllerImpl::IsURLInPageNavigation(
|
| WebPreferences prefs = rfh->GetRenderViewHost()->GetWebkitPreferences();
|
| const url::Origin& committed_origin =
|
| rfhi->frame_tree_node()->current_origin();
|
| - bool is_same_origin = last_committed_url.is_empty() ||
|
| + bool is_same_origin = CouldBeSameOrigin(last_committed_url, committed_origin,
|
| + url, origin, prefs);
|
| + /*last_committed_url.is_empty() ||
|
| // TODO(japhet): We should only permit navigations
|
| // originating from about:blank to be in-page if the
|
| // about:blank is the first document that frame loaded.
|
| @@ -1409,7 +1475,7 @@ bool NavigationControllerImpl::IsURLInPageNavigation(
|
| committed_origin == origin ||
|
| !prefs.web_security_enabled ||
|
| (prefs.allow_universal_access_from_file_urls &&
|
| - committed_origin.scheme() == url::kFileScheme);
|
| + committed_origin.scheme() == url::kFileScheme);*/
|
| if (!is_same_origin && renderer_says_in_page) {
|
| bad_message::ReceivedBadMessage(rfh->GetProcess(),
|
| bad_message::NC_IN_PAGE_NAVIGATION);
|
|
|