Index: content/browser/security_exploit_browsertest.cc |
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc |
index a2ca9285b1e37a6304998bcfc9fe2d08f7704e3a..6adbafeff6184ff222e7f4a611f5de1836209983 100644 |
--- a/content/browser/security_exploit_browsertest.cc |
+++ b/content/browser/security_exploit_browsertest.cc |
@@ -34,6 +34,7 @@ |
#include "content/public/test/content_browser_test_utils.h" |
#include "content/public/test/test_utils.h" |
#include "content/shell/browser/shell.h" |
+#include "content/test/content_browser_test_utils_internal.h" |
#include "content/test/test_content_browser_client.h" |
#include "ipc/ipc_security_test_util.h" |
#include "net/dns/mock_host_resolver.h" |
@@ -499,4 +500,60 @@ IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) { |
TryCreateDuplicateRequestIds(shell(), true); |
} |
+// Test that receiving a commit with incorrect origin properly terminates the |
+// renderer process. |
+IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, MismatchedOriginOnCommit) { |
+ GURL start_url(embedded_test_server()->GetURL("/title1.html")); |
+ EXPECT_TRUE(NavigateToURL(shell(), start_url)); |
+ |
+ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) |
+ ->GetFrameTree() |
+ ->root(); |
+ |
+ // Setup an URL which will never commit, allowing this test to send its own, |
+ // malformed, commit message. |
+ GURL url(embedded_test_server()->GetURL("/title2.html")); |
+ NavigationStallDelegate stall_delegate(url); |
+ ResourceDispatcherHost::Get()->SetDelegate(&stall_delegate); |
+ |
+ // Use LoadURL, as the test shouldn't wait for navigation commit. |
+ NavigationController& controller = shell()->web_contents()->GetController(); |
+ controller.LoadURL(url, Referrer(), ui::PAGE_TRANSITION_LINK, std::string()); |
+ EXPECT_NE(nullptr, controller.GetPendingEntry()); |
+ EXPECT_EQ(url, controller.GetPendingEntry()->GetURL()); |
+ |
+ RenderProcessHostWatcher exit_observer( |
+ root->current_frame_host()->GetProcess(), |
+ RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); |
+ |
+ // Create commit params with different origins in params.url and |
+ // params.origin. |
+ FrameHostMsg_DidCommitProvisionalLoad_Params params; |
+ params.page_id = 0; |
+ params.nav_entry_id = 0; |
+ params.did_create_new_entry = false; |
+ params.url = url; |
+ params.transition = ui::PAGE_TRANSITION_LINK; |
+ params.should_update_history = false; |
+ params.gesture = NavigationGestureAuto; |
+ params.was_within_same_page = false; |
+ params.is_post = false; |
+ params.page_state = PageState::CreateFromURL(url); |
+ params.origin = url::Origin(GURL("http://bar.com/")); |
+ |
+ FrameHostMsg_DidCommitProvisionalLoad msg( |
+ root->current_frame_host()->routing_id(), params); |
+ IPC::IpcSecurityTestUtil::PwnMessageReceived( |
+ root->current_frame_host()->GetProcess()->GetChannel(), msg); |
+ |
+ // When the IPC message is received and validation fails, the process is |
+ // terminated. However, the notification for that should be processed in a |
+ // separate task of the message loop, so ensure that the process is still |
+ // considered alive. |
+ EXPECT_TRUE(root->current_frame_host()->GetProcess()->HasConnection()); |
+ |
+ exit_observer.Wait(); |
+ EXPECT_FALSE(exit_observer.did_exit_normally()); |
+} |
+ |
} // namespace content |