// 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.site_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
