// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include "base/command_line.h"
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/dom_storage/dom_storage_context_wrapper.h"
#include "content/browser/dom_storage/session_storage_namespace_impl.h"
#include "content/browser/frame_host/navigator.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/frame.mojom.h"
#include "content/common/frame_messages.h"
#include "content/common/render_message_filter.mojom.h"
#include "content/common/resource_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/interstitial_page.h"
#include "content/public/browser/interstitial_page_delegate.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/appcache_info.h"
#include "content/public/common/browser_side_navigation_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/resource_request.h"
#include "content/public/common/resource_request_body.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#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"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/url_request/url_request_slow_download_job.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "third_party/WebKit/public/web/WebTriggeringEventInfo.h"

using IPC::IpcSecurityTestUtil;

namespace content {

namespace {

// This request id is used by tests that craft a
// ResourceHostMsg_RequestResource. The id is sufficiently large that it doesn't
// collide with ids used by previous navigation requests.
const int kRequestIdNotPreviouslyUsed = 10000;

// This is a helper function for the tests which attempt to create a
// duplicate RenderViewHost or RenderWidgetHost. It tries to create two objects
// with the same process and routing ids, which causes a collision.
// It creates a couple of windows in process 1, which causes a few routing ids
// to be allocated. Then a cross-process navigation is initiated, which causes a
// new process 2 to be created and have a pending RenderViewHost for it. The
// routing id of the RenderViewHost which is target for a duplicate is set
// into |target_routing_id| and the pending RenderViewHost which is used for
// the attempt is the return value.
RenderViewHostImpl* PrepareToDuplicateHosts(Shell* shell,
                                            int* target_routing_id) {
  GURL foo("http://foo.com/simple_page.html");

  // Start off with initial navigation, so we get the first process allocated.
  NavigateToURL(shell, foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell->web_contents()->GetTitle());

  // Open another window, so we generate some more routing ids.
  ShellAddedObserver shell2_observer;
  EXPECT_TRUE(ExecuteScript(shell, "window.open(document.URL + '#2');"));
  Shell* shell2 = shell2_observer.GetShell();

  // The new window must be in the same process, but have a new routing id.
  EXPECT_EQ(shell->web_contents()->GetMainFrame()->GetProcess()->GetID(),
            shell2->web_contents()->GetMainFrame()->GetProcess()->GetID());
  *target_routing_id =
      shell2->web_contents()->GetRenderViewHost()->GetRoutingID();
  EXPECT_NE(*target_routing_id,
            shell->web_contents()->GetRenderViewHost()->GetRoutingID());

  // Now, simulate a link click coming from the renderer.
  GURL extension_url("https://bar.com/simple_page.html");
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents());
  wc->GetFrameTree()->root()->navigator()->RequestOpenURL(
      wc->GetFrameTree()->root()->current_frame_host(), extension_url, false,
      nullptr, std::string(), Referrer(), WindowOpenDisposition::CURRENT_TAB,
      false, false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent);

  // Since the navigation above requires a cross-process swap, there will be a
  // speculative/pending RenderFrameHost. Ensure it exists and is in a different
  // process than the initial page.
  RenderFrameHostImpl* next_rfh;
  if (IsBrowserSideNavigationEnabled())
    next_rfh = wc->GetRenderManagerForTesting()->speculative_frame_host();
  else
    next_rfh = wc->GetRenderManagerForTesting()->pending_frame_host();

  EXPECT_TRUE(next_rfh);
  EXPECT_NE(shell->web_contents()->GetRenderProcessHost()->GetID(),
            next_rfh->GetProcess()->GetID());

  return next_rfh->render_view_host();
}

ResourceRequest CreateXHRRequest(const char* url) {
  ResourceRequest request;
  request.method = "GET";
  request.url = GURL(url);
  request.referrer_policy = blink::kWebReferrerPolicyDefault;
  request.request_initiator = url::Origin();
  request.load_flags = 0;
  request.origin_pid = 0;
  request.resource_type = RESOURCE_TYPE_XHR;
  request.request_context = 0;
  request.appcache_host_id = kAppCacheNoHostId;
  request.download_to_file = false;
  request.should_reset_appcache = false;
  request.is_main_frame = true;
  request.parent_is_main_frame = false;
  request.parent_render_frame_id = -1;
  request.transition_type = ui::PAGE_TRANSITION_LINK;
  request.allow_download = true;
  return request;
}

ResourceRequest CreateXHRRequestWithOrigin(const char* origin) {
  ResourceRequest request = CreateXHRRequest("http://bar.com/simple_page.html");
  request.first_party_for_cookies = GURL(origin);
  request.headers = base::StringPrintf("Origin: %s\r\n", origin);
  return request;
}

void TryCreateDuplicateRequestIds(Shell* shell, bool block_loaders) {
  NavigateToURL(shell, GURL("http://foo.com/simple_page.html"));
  RenderFrameHost* rfh = shell->web_contents()->GetMainFrame();

  if (block_loaders) {
    // Test the case where loaders are placed into blocked_loaders_map_.
    rfh->BlockRequestsForFrame();
  }

  // URLRequestSlowDownloadJob waits for another request to kFinishDownloadUrl
  // to finish all pending requests. It is never sent, so the following URL
  // blocks indefinitely, which is good because the request stays alive and the
  // test can try to reuse the request id without a race.
  const char* blocking_url = net::URLRequestSlowDownloadJob::kUnknownSizeUrl;
  ResourceRequest request(CreateXHRRequest(blocking_url));

  // Use the same request id twice.
  RenderProcessHostWatcher process_killed(
      rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  IPC::IpcSecurityTestUtil::PwnMessageReceived(
      rfh->GetProcess()->GetChannel(),
      ResourceHostMsg_RequestResource(rfh->GetRoutingID(),
                                      kRequestIdNotPreviouslyUsed, request,
                                      net::MutableNetworkTrafficAnnotationTag(
                                          TRAFFIC_ANNOTATION_FOR_TESTS)));
  IPC::IpcSecurityTestUtil::PwnMessageReceived(
      rfh->GetProcess()->GetChannel(),
      ResourceHostMsg_RequestResource(rfh->GetRoutingID(),
                                      kRequestIdNotPreviouslyUsed, request,
                                      net::MutableNetworkTrafficAnnotationTag(
                                          TRAFFIC_ANNOTATION_FOR_TESTS)));
  process_killed.Wait();
}

}  // namespace

class WidgetImpl : public mojom::Widget {
 public:
  explicit WidgetImpl(mojo::InterfaceRequest<mojom::Widget> request)
      : binding_(this, std::move(request)) {}

 private:
  mojo::Binding<mojom::Widget> binding_;
};

// The goal of these tests will be to "simulate" exploited renderer processes,
// which can send arbitrary IPC messages and confuse browser process internal
// state, leading to security bugs. We are trying to verify that the browser
// doesn't perform any dangerous operations in such cases.
class SecurityExploitBrowserTest : public ContentBrowserTest {
 public:
  SecurityExploitBrowserTest() {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // EmbeddedTestServer::InitializeAndListen() initializes its |base_url_|
    // which is required below. This cannot invoke Start() however as that kicks
    // off the "EmbeddedTestServer IO Thread" which then races with
    // initialization in ContentBrowserTest::SetUp(), http://crbug.com/674545.
    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());

    // Add a host resolver rule to map all outgoing requests to the test server.
    // This allows us to use "real" hostnames in URLs, which we can use to
    // create arbitrary SiteInstances.
    command_line->AppendSwitchASCII(
        switches::kHostResolverRules,
        "MAP * " +
            net::HostPortPair::FromURL(embedded_test_server()->base_url())
                .ToString() +
            ",EXCLUDE localhost");
  }

  void SetUpOnMainThread() override {
    // Complete the manual Start() after ContentBrowserTest's own
    // initialization, ref. comment on InitializeAndListen() above.
    embedded_test_server()->StartAcceptingConnections();

    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler));
  }

 protected:
  // Tests that a given file path sent in a FrameHostMsg_RunFileChooser will
  // cause renderer to be killed.
  void TestFileChooserWithPath(const base::FilePath& path);
};

void SecurityExploitBrowserTest::TestFileChooserWithPath(
    const base::FilePath& path) {
  GURL foo("http://foo.com/simple_page.html");
  NavigateToURL(shell(), foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle());

  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetMainFrame();
  RenderProcessHostWatcher terminated(
      shell()->web_contents(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  FileChooserParams params;
  params.default_file_name = path;

  FrameHostMsg_RunFileChooser evil(compromised_renderer->GetRoutingID(),
                                   params);

  IpcSecurityTestUtil::PwnMessageReceived(
      compromised_renderer->GetProcess()->GetChannel(), evil);
  terminated.Wait();
}

// Ensure that we kill the renderer process if we try to give it WebUI
// properties and it doesn't have enabled WebUI bindings.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, SetWebUIProperty) {
  GURL foo("http://foo.com/simple_page.html");

  NavigateToURL(shell(), foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle());
  EXPECT_EQ(0, shell()->web_contents()->GetMainFrame()->GetEnabledBindings());

  RenderProcessHostWatcher terminated(
      shell()->web_contents(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  shell()->web_contents()->GetRenderViewHost()->SetWebUIProperty(
      "toolkit", "views");
  terminated.Wait();
}

// This is a test for crbug.com/312016 attempting to create duplicate
// RenderViewHosts. SetupForDuplicateHosts sets up this test case and leaves
// it in a state with pending RenderViewHost. Before the commit of the new
// pending RenderViewHost, this test case creates a new window through the new
// process.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       AttemptDuplicateRenderViewHost) {
  int32_t duplicate_routing_id = MSG_ROUTING_NONE;
  RenderViewHostImpl* pending_rvh =
      PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
  EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);

  RenderFrameHostImpl* opener =
      static_cast<RenderFrameHostImpl*>(pending_rvh->GetMainFrame());
  mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
  params->target_url = GURL("about:blank");
  opener->CreateNewWindow(std::move(params),
                          base::Bind([](mojom::CreateNewWindowReplyPtr) {}));
  // If the above operation doesn't cause a crash, the test has succeeded!
}

// This is a test for crbug.com/312016. It tries to create two RenderWidgetHosts
// with the same process and routing ids, which causes a collision. It is almost
// identical to the AttemptDuplicateRenderViewHost test case.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       AttemptDuplicateRenderWidgetHost) {
#if defined(OS_WIN)
  // PlzNavigate
  // This test is failing in a flaky manner on Android as it appears to be
  // leaking URLRequests. See crbug.com/702584.
  if (IsBrowserSideNavigationEnabled())
    return;
#endif
  int duplicate_routing_id = MSG_ROUTING_NONE;
  RenderViewHostImpl* pending_rvh =
      PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
  EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);

  mojom::WidgetPtr widget;
  std::unique_ptr<WidgetImpl> widget_impl =
      base::MakeUnique<WidgetImpl>(mojo::MakeRequest(&widget));

  // Since this test executes on the UI thread and hopping threads might cause
  // different timing in the test, let's simulate a CreateNewWidget call coming
  // from the IO thread.  Use the existing window routing id to cause a
  // deliberate collision.
  pending_rvh->CreateNewWidget(duplicate_routing_id, std::move(widget),
                               blink::kWebPopupTypePage);

  // If the above operation doesn't crash, the test has succeeded!
}

// This is a test for crbug.com/444198. It tries to send a
// FrameHostMsg_RunFileChooser containing an invalid path. The browser should
// correctly terminate the renderer in these cases.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, AttemptRunFileChoosers) {
  TestFileChooserWithPath(base::FilePath(FILE_PATH_LITERAL("../../*.txt")));
  TestFileChooserWithPath(base::FilePath(FILE_PATH_LITERAL("/etc/*.conf")));
#if defined(OS_WIN)
  TestFileChooserWithPath(
      base::FilePath(FILE_PATH_LITERAL("\\\\evilserver\\evilshare\\*.txt")));
  TestFileChooserWithPath(base::FilePath(FILE_PATH_LITERAL("c:\\*.txt")));
  TestFileChooserWithPath(base::FilePath(FILE_PATH_LITERAL("..\\..\\*.txt")));
#endif
}

class SecurityExploitTestInterstitialPage : public InterstitialPageDelegate {
 public:
  explicit SecurityExploitTestInterstitialPage(WebContents* contents) {
    InterstitialPage* interstitial = InterstitialPage::Create(
        contents, true, contents->GetLastCommittedURL(), this);
    interstitial->Show();
  }

  // InterstitialPageDelegate implementation.
  void CommandReceived(const std::string& command) override {
    last_command_ = command;
  }

  std::string GetHTMLContents() override {
    return "<html><head><script>"
           "window.domAutomationController.send(\"okay\");"
           "</script></head>"
           "<body>this page is an interstitial</body></html>";
  }

  std::string last_command() { return last_command_; }

 private:
  std::string last_command_;
  DISALLOW_COPY_AND_ASSIGN(SecurityExploitTestInterstitialPage);
};

// Fails due to InterstitialPage's reliance on PostNonNestableTask
// http://crbug.com/432737
#if defined(OS_ANDROID)
#define MAYBE_InterstitialCommandFromUnderlyingContent \
  DISABLED_InterstitialCommandFromUnderlyingContent
#else
#define MAYBE_InterstitialCommandFromUnderlyingContent \
  InterstitialCommandFromUnderlyingContent
#endif

// The interstitial should not be controllable by the underlying content.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       MAYBE_InterstitialCommandFromUnderlyingContent) {
  // Start off with initial navigation, to allocate the process.
  GURL foo("http://foo.com/simple_page.html");
  NavigateToURL(shell(), foo);
  EXPECT_EQ(base::ASCIIToUTF16("OK"), shell()->web_contents()->GetTitle());

  DOMMessageQueue message_queue;

  // Install and show an interstitial page.
  SecurityExploitTestInterstitialPage* interstitial =
      new SecurityExploitTestInterstitialPage(shell()->web_contents());

  ASSERT_EQ("", interstitial->last_command());
  WaitForInterstitialAttach(shell()->web_contents());

  InterstitialPage* interstitial_page =
      shell()->web_contents()->GetInterstitialPage();
  ASSERT_TRUE(interstitial_page != NULL);
  ASSERT_TRUE(shell()->web_contents()->ShowingInterstitialPage());
  ASSERT_TRUE(interstitial_page->GetDelegateForTesting() == interstitial);

  // The interstitial page ought to be able to send a message.
  std::string message;
  ASSERT_TRUE(message_queue.WaitForMessage(&message));
  ASSERT_EQ("\"okay\"", message);
  ASSERT_EQ("\"okay\"", interstitial->last_command());

  // Send an automation message from the underlying content and wait for it to
  // be dispatched on this thread. This message should not be received by the
  // interstitial.
  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetMainFrame();
  FrameHostMsg_DomOperationResponse evil(compromised_renderer->GetRoutingID(),
                                         "evil");
  IpcSecurityTestUtil::PwnMessageReceived(
      compromised_renderer->GetProcess()->GetChannel(), evil);

  ASSERT_TRUE(message_queue.WaitForMessage(&message));
  ASSERT_EQ("evil", message)
      << "Automation message should be received by WebContents.";
  ASSERT_EQ("\"okay\"", interstitial->last_command())
      << "Interstitial should not be affected.";

  // Send a second message from the interstitial page, and make sure that the
  // "evil" message doesn't arrive in the intervening period.
  ExecuteScriptAsync(interstitial_page->GetMainFrame(),
                     "window.domAutomationController.send(\"okay2\");");
  ASSERT_TRUE(message_queue.WaitForMessage(&message));
  ASSERT_EQ("\"okay2\"", message);
  ASSERT_EQ("\"okay2\"", interstitial->last_command());
}

// Intercepts the HTTP origin header and on being invoked once it is found
// aborts the requeest.
void OnHttpHeaderReceived(const std::string& header,
                          const std::string& value,
                          int child_process_id,
                          content::ResourceContext* resource_context,
                          OnHeaderProcessedCallback callback) {
  callback.Run(HeaderInterceptorResult::KILL);
}

// Renderer processes should not be able to spoof Origin HTTP headers.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
  // Create a set of IPC messages with various Origin headers.
  ResourceRequest chrome_origin_msg(
      CreateXHRRequestWithOrigin("chrome://settings"));
  ResourceRequest embedder_isolated_origin_msg(
      CreateXHRRequestWithOrigin("https://isolated.bar.com"));
  ResourceRequest invalid_origin_msg(CreateXHRRequestWithOrigin("invalidurl"));
  ResourceRequest invalid_scheme_origin_msg(
      CreateXHRRequestWithOrigin("fake-scheme://foo"));

  GURL web_url("http://foo.com/simple_page.html");
  NavigateToURL(shell(), web_url);
  RenderFrameHost* web_rfh = shell()->web_contents()->GetMainFrame();

  // Web processes cannot make XHRs with chrome:// Origin headers.
  {
    RenderProcessHostWatcher web_process_killed(
        web_rfh->GetProcess(),
        RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        web_rfh->GetProcess()->GetChannel(),
        ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(),
                                        kRequestIdNotPreviouslyUsed,
                                        chrome_origin_msg,
                                        net::MutableNetworkTrafficAnnotationTag(
                                            TRAFFIC_ANNOTATION_FOR_TESTS)));
    web_process_killed.Wait();
  }

  // Web processes cannot make XHRs with URLs that the content embedder expects
  // to have process isolation.  Ideally this would test chrome-extension://
  // URLs for Chrome Apps, but those can't be tested inside content/ and the
  // ResourceRequest IPC can't be created in a test outside content/.
  NavigateToURL(shell(), web_url);
  {
    content::ResourceDispatcherHost::Get()->RegisterInterceptor(
        "Origin", "", base::Bind(&OnHttpHeaderReceived));

    RenderProcessHostWatcher web_process_killed(
        web_rfh->GetProcess(),
        RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        web_rfh->GetProcess()->GetChannel(),
        ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(),
                                        kRequestIdNotPreviouslyUsed,
                                        embedder_isolated_origin_msg,
                                        net::MutableNetworkTrafficAnnotationTag(
                                            TRAFFIC_ANNOTATION_FOR_TESTS)));
    web_process_killed.Wait();
  }

  // Web processes cannot make XHRs with invalid Origin headers.
  NavigateToURL(shell(), web_url);
  {
    RenderProcessHostWatcher web_process_killed(
        web_rfh->GetProcess(),
        RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        web_rfh->GetProcess()->GetChannel(),
        ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(),
                                        kRequestIdNotPreviouslyUsed,
                                        invalid_origin_msg,
                                        net::MutableNetworkTrafficAnnotationTag(
                                            TRAFFIC_ANNOTATION_FOR_TESTS)));
    web_process_killed.Wait();
  }

  // Web processes cannot make XHRs with invalid scheme Origin headers.
  NavigateToURL(shell(), web_url);
  {
    RenderProcessHostWatcher web_process_killed(
        web_rfh->GetProcess(),
        RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        web_rfh->GetProcess()->GetChannel(),
        ResourceHostMsg_RequestResource(web_rfh->GetRoutingID(),
                                        kRequestIdNotPreviouslyUsed,
                                        invalid_scheme_origin_msg,
                                        net::MutableNetworkTrafficAnnotationTag(
                                            TRAFFIC_ANNOTATION_FOR_TESTS)));
    web_process_killed.Wait();
  }
}

// Renderer process should not be able to create multiple requests with the same
// id.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) {
  // Existing loader in pending_loaders_.
  TryCreateDuplicateRequestIds(shell(), false);
  // Existing loader in blocked_loaders_map_.
  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.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_document = false;
  params.method = "GET";
  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());
  ResourceDispatcherHost::Get()->SetDelegate(nullptr);
}

// Test that a compromised renderer cannot ask to upload an arbitrary file in
// OpenURL.  This is a regression test for https://crbug.com/726067.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       OpenUrl_ResourceRequestBody) {
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  GURL target_url(embedded_test_server()->GetURL("/echoall"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();

  RenderProcessHostWatcher exit_observer(
      root->current_frame_host()->GetProcess(),
      RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Prepare a file to upload.
  base::ThreadRestrictions::ScopedAllowIO allow_io_for_temp_dir;
  base::ScopedTempDir temp_dir;
  base::FilePath file_path;
  std::string file_content("test-file-content");
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir.GetPath(), &file_path));
  ASSERT_LT(
      0, base::WriteFile(file_path, file_content.data(), file_content.size()));

  // Simulate an IPC message asking to POST a file that the renderer shouldn't
  // have access to.
  FrameHostMsg_OpenURL_Params params;
  params.url = target_url;
  params.uses_post = true;
  params.resource_request_body = new ResourceRequestBody;
  params.resource_request_body->AppendFileRange(
      file_path, 0, file_content.size(), base::Time());
  params.disposition = WindowOpenDisposition::CURRENT_TAB;
  params.should_replace_current_entry = true;
  params.user_gesture = true;
  params.is_history_navigation_in_new_child = false;

  FrameHostMsg_OpenURL msg(root->current_frame_host()->routing_id(), params);
  IPC::IpcSecurityTestUtil::PwnMessageReceived(
      root->current_frame_host()->GetProcess()->GetChannel(), msg);

  // Verify that the malicious navigation did not commit the navigation to
  // |target_url|.
  WaitForLoadStop(shell()->web_contents());
  EXPECT_EQ(start_url, root->current_frame_host()->GetLastCommittedURL());

  // Verify that the malicious renderer got killed.
  exit_observer.Wait();
  EXPECT_FALSE(exit_observer.did_exit_normally());
}

}  // namespace content
