diff options
-rw-r--r-- | content/browser/frame_host/navigator_impl.cc | 13 | ||||
-rw-r--r-- | content/browser/frame_host/navigator_impl_unittest.cc | 30 | ||||
-rw-r--r-- | content/test/test_render_frame_host.cc | 4 |
3 files changed, 46 insertions, 1 deletions
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index ea89de6..2acedd7 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc @@ -438,6 +438,19 @@ void NavigatorImpl::DidNavigate( bool is_navigation_within_page = controller_->IsURLInPageNavigation( params.url, params.was_within_same_page, render_frame_host); + + // If a frame claims it navigated within page, it must be the current frame, + // not a pending one. + if (is_navigation_within_page && + render_frame_host != + render_frame_host->frame_tree_node() + ->render_manager() + ->current_frame_host()) { + bad_message::ReceivedBadMessage(render_frame_host->GetProcess(), + bad_message::NC_IN_PAGE_NAVIGATION); + is_navigation_within_page = false; + } + if (ui::PageTransitionIsMainFrame(params.transition)) { if (delegate_) { // When overscroll navigation gesture is enabled, a screenshot of the page diff --git a/content/browser/frame_host/navigator_impl_unittest.cc b/content/browser/frame_host/navigator_impl_unittest.cc index efb8576..28cce07 100644 --- a/content/browser/frame_host/navigator_impl_unittest.cc +++ b/content/browser/frame_host/navigator_impl_unittest.cc @@ -1146,4 +1146,34 @@ TEST_F(NavigatorTestWithBrowserSideNavigation, } } +namespace { +void SetWithinPage(const GURL& url, + FrameHostMsg_DidCommitProvisionalLoad_Params* params) { + params->was_within_same_page = true; + params->url = url; +} +} + +// A renderer process might try and claim that a cross site navigation was +// within the same page by setting was_within_same_page = true for +// FrameHostMsg_DidCommitProvisionalLoad. Such case should be detected on the +// browser side and the renderer process should be killed. +TEST_F(NavigatorTestWithBrowserSideNavigation, CrossSiteClaimWithinPage) { + const GURL kUrl1("http://www.chromium.org/"); + const GURL kUrl2("http://www.google.com/"); + + contents()->NavigateAndCommit(kUrl1); + FrameTreeNode* node = main_test_rfh()->frame_tree_node(); + + // Navigate to a different site. + int entry_id = RequestNavigation(node, kUrl2); + main_test_rfh()->PrepareForCommit(); + + // Claim that the navigation was within same page. + int bad_msg_count = process()->bad_msg_count(); + GetSpeculativeRenderFrameHost(node)->SendNavigateWithModificationCallback( + 0, entry_id, true, kUrl2, base::Bind(SetWithinPage, kUrl1)); + EXPECT_EQ(process()->bad_msg_count(), bad_msg_count + 1); +} + } // namespace content diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index 5ae3fd8..16bb781 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc @@ -259,10 +259,12 @@ void TestRenderFrameHost::SendNavigateWithParameters( ui::PageTransition transition, int response_code, const ModificationCallback& callback) { + if (!IsBrowserSideNavigationEnabled()) + OnDidStartLoading(true); + // DidStartProvisionalLoad may delete the pending entry that holds |url|, // so we keep a copy of it to use below. GURL url_copy(url); - OnDidStartLoading(true); OnDidStartProvisionalLoad(url_copy, base::TimeTicks::Now()); FrameHostMsg_DidCommitProvisionalLoad_Params params; |