// 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/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/child_process_security_policy_impl.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/frame_host/render_frame_proxy_host.h"
#include "content/browser/renderer_host/render_process_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/view_messages.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/file_select_listener.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/content_switches.h"
#include "content/public/common/navigation_policy.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_navigation_observer.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/did_commit_navigation_interceptor.h"
#include "content/test/frame_host_interceptor.h"
#include "content/test/mock_widget_impl.h"
#include "content/test/test_content_browser_client.h"
#include "ipc/ipc_security_test_util.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.h"
#include "mojo/public/cpp/test_support/test_utils.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 "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/test/test_url_loader_client.h"
#include "storage/browser/blob/blob_registry_impl.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/appcache/appcache.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-test-utils.h"
#include "third_party/blink/public/web/web_triggering_event_info.h"

using IPC::IpcSecurityTestUtil;

namespace content {

namespace {

// This request id is used by tests that call CreateLoaderAndStart. 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 RenderFrameHost which is used for
// the attempt is the return value.
RenderFrameHostImpl* 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,
      url::Origin::Create(foo), false, nullptr, std::string(), Referrer(),
      WindowOpenDisposition::CURRENT_TAB, false, true,
      blink::WebTriggeringEventInfo::kFromTrustedEvent, std::string(),
      nullptr /* blob_url_loader_factory */);

  // 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 =
      wc->GetRenderManagerForTesting()->speculative_frame_host();

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

  return next_rfh;
}

network::ResourceRequest CreateXHRRequest(const char* url) {
  network::ResourceRequest request;
  request.method = "GET";
  request.url = GURL(url);
  request.referrer_policy = Referrer::GetDefaultReferrerPolicy();
  request.request_initiator = url::Origin();
  request.load_flags = 0;
  request.plugin_child_id = -1;
  request.resource_type = ResourceType::kXhr;
  request.appcache_host_id = blink::mojom::kAppCacheNoHostId;
  request.should_reset_appcache = false;
  request.is_main_frame = true;
  request.transition_type = ui::PAGE_TRANSITION_LINK;
  request.allow_download = true;
  return request;
}

network::ResourceRequest CreateXHRRequestWithOrigin(const char* origin) {
  network::ResourceRequest request =
      CreateXHRRequest("http://bar.com/simple_page.html");
  request.site_for_cookies = GURL(origin);
  request.headers.SetHeader(net::HttpRequestHeaders::kOrigin, origin);
  return request;
}

std::unique_ptr<content::BlobHandle> CreateMemoryBackedBlob(
    BrowserContext* browser_context,
    const std::string& contents,
    const std::string& content_type) {
  std::unique_ptr<content::BlobHandle> result;
  base::RunLoop loop;
  BrowserContext::CreateMemoryBackedBlob(
      browser_context, contents.c_str(), contents.length(), content_type,
      base::BindOnce(
          [](std::unique_ptr<content::BlobHandle>* out_blob,
             base::OnceClosure done,
             std::unique_ptr<content::BlobHandle> blob) {
            *out_blob = std::move(blob);
            std::move(done).Run();
          },
          &result, loop.QuitClosure()));
  loop.Run();
  EXPECT_TRUE(result);
  return result;
}

// Helper class to interpose on Blob URL registrations, replacing the URL
// contained in incoming registration requests with the specified URL.
class BlobURLStoreInterceptor
    : public blink::mojom::BlobURLStoreInterceptorForTesting {
 public:
  explicit BlobURLStoreInterceptor(GURL target_url) : target_url_(target_url) {}

  void Intercept(
      mojo::StrongAssociatedBindingPtr<blink::mojom::BlobURLStore> binding) {
    url_store_ = binding->SwapImplForTesting(this);
  }

  blink::mojom::BlobURLStore* GetForwardingInterface() override {
    return url_store_;
  }

  void Register(blink::mojom::BlobPtr blob,
                const GURL& url,
                RegisterCallback callback) override {
    GetForwardingInterface()->Register(std::move(blob), target_url_,
                                       std::move(callback));
  }

 private:
  blink::mojom::BlobURLStore* url_store_;
  GURL target_url_;
};

// Constructs a WebContentsDelegate that mocks a file dialog.
// Unlike content::FileChooserDelegate, this class doesn't make a response in
// RunFileChooser(), and a user needs to call Choose().
class DelayedFileChooserDelegate : public WebContentsDelegate {
 public:
  void Choose(const base::FilePath& file) {
    auto file_info = blink::mojom::FileChooserFileInfo::NewNativeFile(
        blink::mojom::NativeFileInfo::New(file, base::string16()));
    std::vector<blink::mojom::FileChooserFileInfoPtr> files;
    files.push_back(std::move(file_info));
    listener_->FileSelected(std::move(files), base::FilePath(),
                            blink::mojom::FileChooserParams::Mode::kOpen);
    listener_.reset();
  }

  // WebContentsDelegate overrides
  void RunFileChooser(RenderFrameHost* render_frame_host,
                      std::unique_ptr<FileSelectListener> listener,
                      const blink::mojom::FileChooserParams& params) override {
    listener_ = std::move(listener);
  }

  void EnumerateDirectory(WebContents* web_contents,
                          std::unique_ptr<FileSelectListener> listener,
                          const base::FilePath& directory_path) override {
    listener->FileSelectionCanceled();
  }

 private:
  std::unique_ptr<FileSelectListener> listener_;
};

void FileChooserCallback(base::RunLoop* run_loop,
                         blink::mojom::FileChooserResultPtr result) {
  run_loop->Quit();
}

}  // namespace

// 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(
        network::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();

    base::PostTaskWithTraits(
        FROM_HERE, {BrowserThread::IO},
        base::BindOnce(&net::URLRequestSlowDownloadJob::AddUrlHandler));
  }

  static void CreateLoaderAndStart(
      RenderFrameHost* frame,
      int route_id,
      int request_id,
      const network::ResourceRequest& resource_request) {
    network::mojom::URLLoaderPtr loader;
    network::TestURLLoaderClient client;
    CreateLoaderAndStart(frame, mojo::MakeRequest(&loader), route_id,
                         request_id, resource_request,
                         client.CreateInterfacePtr().PassInterface());
  }

  static void CreateLoaderAndStart(
      RenderFrameHost* frame,
      network::mojom::URLLoaderRequest request,
      int route_id,
      int request_id,
      const network::ResourceRequest& resource_request,
      network::mojom::URLLoaderClientPtrInfo client) {
    network::mojom::URLLoaderFactoryPtr factory;
    frame->GetProcess()->CreateURLLoaderFactory(frame->GetLastCommittedOrigin(),
                                                nullptr /* header_client */,
                                                mojo::MakeRequest(&factory));
    factory->CreateLoaderAndStart(
        std::move(request), route_id, request_id,
        network::mojom::kURLLoadOptionNone, resource_request,
        network::mojom::URLLoaderClientPtr(std::move(client)),
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
  }

  void TryCreateDuplicateRequestIds(Shell* shell, bool block_loaders) {
    NavigateToURL(shell, GURL("http://foo.com/simple_page.html"));
    RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
        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;
    network::ResourceRequest request(CreateXHRRequest(blocking_url));

    // Use the same request id twice.
    RenderProcessHostKillWaiter kill_waiter(rfh->GetProcess());
    // We need to keep loader and client to keep the requests alive.
    network::mojom::URLLoaderPtr loader1, loader2;
    network::TestURLLoaderClient client1, client2;

    CreateLoaderAndStart(rfh, mojo::MakeRequest(&loader1), rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed, request,
                         client1.CreateInterfacePtr().PassInterface());
    CreateLoaderAndStart(rfh, mojo::MakeRequest(&loader2), rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed, request,
                         client2.CreateInterfacePtr().PassInterface());
    EXPECT_EQ(bad_message::RDH_INVALID_REQUEST_ID, kill_waiter.Wait());
  }

 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 IsolateOrigin(const std::string& hostname) {
    IsolateOriginsForTesting(embedded_test_server(), shell()->web_contents(),
                             {hostname});
  }
};

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();
  blink::mojom::FileChooserParamsPtr params =
      blink::mojom::FileChooserParams::New();
  params->default_file_name = path;

  mojo::test::BadMessageObserver bad_message_observer;
  blink::mojom::FileChooserPtr factory =
      static_cast<RenderFrameHostImpl*>(compromised_renderer)
          ->BindFileChooserForTesting();
  factory->OpenFileChooser(
      std::move(params), blink::mojom::FileChooser::OpenFileChooserCallback());
  factory.FlushForTesting();
  EXPECT_THAT(bad_message_observer.WaitForBadMessage(),
              ::testing::StartsWith("FileChooser: The default file name"));
}

// 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());

  RenderViewHost* compromised_renderer =
      shell()->web_contents()->GetRenderViewHost();
  RenderProcessHostKillWaiter kill_waiter(compromised_renderer->GetProcess());
  compromised_renderer->SetWebUIProperty("toolkit", "views");
  EXPECT_EQ(bad_message::RVH_WEB_UI_BINDINGS_MISMATCH, kill_waiter.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;
  RenderFrameHostImpl* pending_rfh =
      PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
  EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);

  mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New();
  params->target_url = GURL("about:blank");
  pending_rfh->CreateNewWindow(
      std::move(params), base::BindOnce([](mojom::CreateNewWindowStatus,
                                           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.
// Crashes on all platforms.  http://crbug.com/939338
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       DISABLED_AttemptDuplicateRenderWidgetHost) {
  int duplicate_routing_id = MSG_ROUTING_NONE;
  RenderFrameHostImpl* pending_rfh =
      PrepareToDuplicateHosts(shell(), &duplicate_routing_id);
  EXPECT_NE(MSG_ROUTING_NONE, duplicate_routing_id);

  mojom::WidgetPtr widget;
  std::unique_ptr<MockWidgetImpl> widget_impl =
      std::make_unique<MockWidgetImpl>(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_rfh->render_view_host()->CreateNewWidget(duplicate_routing_id,
                                                   std::move(widget));

  // 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
}

// A test for crbug.com/941008.
// Calling OpenFileChooser() and EnumerateChosenDirectory() for a single
// FileChooser instance had a problem.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, UnexpectedMethodsSequence) {
  NavigateToURL(shell(), GURL("http://foo.com/simple_page.html"));
  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetMainFrame();
  auto delegate = std::make_unique<DelayedFileChooserDelegate>();
  shell()->web_contents()->SetDelegate(delegate.get());

  blink::mojom::FileChooserPtr chooser =
      static_cast<RenderFrameHostImpl*>(compromised_renderer)
          ->BindFileChooserForTesting();
  base::RunLoop run_loop1;
  base::RunLoop run_loop2;
  chooser->OpenFileChooser(blink::mojom::FileChooserParams::New(),
                           base::BindOnce(FileChooserCallback, &run_loop2));
  // The following EnumerateChosenDirectory() runs the specified callback
  // immediately regardless of the content of the first argument FilePath.
  chooser->EnumerateChosenDirectory(
      base::FilePath(FILE_PATH_LITERAL(":*?\"<>|")),
      base::BindOnce(FileChooserCallback, &run_loop1));
  run_loop1.Run();

  delegate->Choose(base::FilePath(FILE_PATH_LITERAL("foo.txt")));
  run_loop2.Run();

  // The test passes if it doesn't crash.
}

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 != nullptr);
  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) {
  std::move(callback).Run(HeaderInterceptorResult::KILL);
}

// Renderer processes should not be able to spoof Origin HTTP headers.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidOriginHeaders) {
  // https://crbug.com/862176
  if (base::FeatureList::IsEnabled(network::features::kNetworkService))
    return;

  // Create a set of IPC messages with various Origin headers.
  network::ResourceRequest chrome_origin_msg(
      CreateXHRRequestWithOrigin("chrome://settings"));
  network::ResourceRequest embedder_isolated_origin_msg(
      CreateXHRRequestWithOrigin("https://isolated.bar.com"));
  network::ResourceRequest invalid_origin_msg(
      CreateXHRRequestWithOrigin("invalidurl"));
  network::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.
  {
    RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());

    CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed, chrome_origin_msg);
    EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.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));

    RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
    CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed,
                         embedder_isolated_origin_msg);
    EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
  }

  // Web processes cannot make XHRs with invalid Origin headers.
  NavigateToURL(shell(), web_url);
  {
    RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
    CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed, invalid_origin_msg);
    EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
  }

  // Web processes cannot make XHRs with invalid scheme Origin headers.
  NavigateToURL(shell(), web_url);
  {
    RenderProcessHostKillWaiter kill_waiter(web_rfh->GetProcess());
    CreateLoaderAndStart(web_rfh, web_rfh->GetRoutingID(),
                         kRequestIdNotPreviouslyUsed,
                         invalid_scheme_origin_msg);
    EXPECT_EQ(bad_message::RDH_ILLEGAL_ORIGIN, kill_waiter.Wait());
  }
}

// Renderer process should not be able to create multiple requests with the same
// id.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidRequestId) {
  // This test is specific to the ResourceDispatcherHost implementation, which
  // is not used with network service enabled.
  if (base::FeatureList::IsEnabled(network::features::kNetworkService))
    return;

  // Existing loader in pending_loaders_.
  TryCreateDuplicateRequestIds(shell(), false);
}

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, InvalidBlockedRequestId) {
  // This test is specific to the ResourceDispatcherHost implementation, which
  // is not used with network service enabled.
  if (base::FeatureList::IsEnabled(network::features::kNetworkService))
    return;

  // 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();

  // Navigate to a new URL, with an interceptor that replaces the origin with
  // one that does not match params.url.
  GURL url(embedded_test_server()->GetURL("/title2.html"));
  PwnCommitIPC(shell()->web_contents(), url, url,
               url::Origin::Create(GURL("http://bar.com/")));

  // 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());

  RenderProcessHostKillWaiter kill_waiter(
      root->current_frame_host()->GetProcess());

  // 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()->IsInitializedAndNotDead());

  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}

namespace {

// Interceptor that replaces |interface_params| with the specified
// value for the first DidCommitProvisionalLoad message it observes in the given
// |web_contents| while in scope.
class ScopedInterfaceParamsReplacer : public DidCommitNavigationInterceptor {
 public:
  ScopedInterfaceParamsReplacer(
      WebContents* web_contents,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr params_override)
      : DidCommitNavigationInterceptor(web_contents),
        params_override_(std::move(params_override)) {}
  ~ScopedInterfaceParamsReplacer() override = default;

 protected:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      ::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params)
      override {
    interface_params->Swap(&params_override_);

    return true;
  }

 private:
  mojom::DidCommitProvisionalLoadInterfaceParamsPtr params_override_;

  DISALLOW_COPY_AND_ASSIGN(ScopedInterfaceParamsReplacer);
};

}  // namespace

// Test that, as a general rule, not receiving new
// DidCommitProvisionalLoadInterfaceParamsPtr for a cross-document navigation
// properly terminates the renderer process. There is one exception to this
// rule, see: RenderFrameHostImplBrowserTest.
// InterfaceProviderRequestIsOptionalForFirstCommit.
// TODO(crbug.com/718652): when all clients are converted to use
// DocumentInterfaceBroker, InterfaceProviderRequest-related code will be
// removed.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       MissingInterfaceProviderOnNonSameDocumentCommit) {
  const GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  const GURL non_same_document_url(
      embedded_test_server()->GetURL("/title2.html"));

  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHostImpl* frame = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetMainFrame());
  RenderProcessHostKillWaiter kill_waiter(frame->GetProcess());

  ScopedInterfaceParamsReplacer replacer(shell()->web_contents(), nullptr);
  NavigateToURLAndExpectNoCommit(shell(), non_same_document_url);
  EXPECT_EQ(bad_message::RFH_INTERFACE_PROVIDER_MISSING, kill_waiter.Wait());

  // Verify that the death of the renderer process doesn't leave behing and leak
  // NavigationRequests - see https://crbug.com/869193.
  EXPECT_EQ(0u, frame->GetNavigationEntryIdsPendingCommit().size());
}

// 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();

  RenderProcessHostKillWaiter kill_waiter(
      root->current_frame_host()->GetProcess());

  // Prepare a file to upload.
  base::ScopedAllowBlockingForTesting allow_blocking;
  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 network::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.
  EXPECT_EQ(bad_message::ILLEGAL_UPLOAD_PARAMS, kill_waiter.Wait());
}

// Test that forging a frame's unique name and commit won't allow changing the
// PageState of a cross-process FrameNavigationEntry.
// See https://crbug.com/766262.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, PageStateToWrongEntry) {
  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  // Commit a page with nested iframes and a separate cross-process iframe.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(a(a),b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  NavigationEntryImpl* back_entry = static_cast<NavigationEntryImpl*>(
      shell()->web_contents()->GetController().GetLastCommittedEntry());
  int nav_entry_id = back_entry->GetUniqueID();

  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  FrameTreeNode* child0_0 = root->child_at(0)->child_at(0);
  std::string child0_0_unique_name = child0_0->unique_name();
  FrameTreeNode* child1 = root->child_at(1);
  GURL child1_url = child1->current_url();
  int child1_pid = child1->current_frame_host()->GetProcess()->GetID();
  PageState child1_page_state = back_entry->GetFrameEntry(child1)->page_state();

  // Add a history item in the nested frame.  It's important to do it there and
  // not the main frame for the repro to work, since we don't walk the subtree
  // when navigating back/forward between same document items.
  TestNavigationObserver fragment_observer(shell()->web_contents());
  EXPECT_TRUE(ExecuteScript(child0_0, "location.href = '#foo';"));
  fragment_observer.Wait();

  // Simulate a name change IPC from the nested iframe, matching the cross-site
  // iframe's unique name.
  child0_0->SetFrameName("foo", child1->unique_name());

  // Simulate a back navigation from the now renamed nested iframe, which would
  // put a PageState on the cross-site iframe's FrameNavigationEntry.  Forge a
  // data URL within the PageState that differs from child1_url.
  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
      std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
  params->nav_entry_id = nav_entry_id;
  params->did_create_new_entry = false;
  params->url = GURL("about:blank");
  params->transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME;
  params->should_update_history = false;
  params->gesture = NavigationGestureAuto;
  params->method = "GET";
  params->page_state = PageState::CreateFromURL(GURL("data:text/html,foo"));
  params->origin = url::Origin::Create(GURL("about:blank"));

  service_manager::mojom::InterfaceProviderPtr isolated_interface_provider;
  blink::mojom::DocumentInterfaceBrokerPtr
      isolated_document_interface_broker_content;
  blink::mojom::DocumentInterfaceBrokerPtr
      isolated_document_interface_broker_blink;
  static_cast<mojom::FrameHost*>(child0_0->current_frame_host())
      ->DidCommitProvisionalLoad(
          std::move(params),
          mojom::DidCommitProvisionalLoadInterfaceParams::New(
              mojo::MakeRequest(&isolated_interface_provider),
              mojo::MakeRequest(&isolated_document_interface_broker_content),
              mojo::MakeRequest(&isolated_document_interface_broker_blink)));

  // Make sure we haven't changed the FrameNavigationEntry.  An attack would
  // modify the PageState but leave the SiteInstance as it was.
  EXPECT_EQ(child1->current_frame_host()->GetSiteInstance(),
            back_entry->GetFrameEntry(child1)->site_instance());
  EXPECT_EQ(child1_page_state, back_entry->GetFrameEntry(child1)->page_state());

  // Put the frame's unique name back.
  child0_0->SetFrameName("bar", child0_0_unique_name);

  // Go forward after the fake back navigation.
  TestNavigationObserver forward_observer(shell()->web_contents());
  shell()->web_contents()->GetController().GoForward();
  forward_observer.Wait();

  // Go back to the possibly corrupted entry and ensure we didn't load the data
  // URL in the previous process.  A test failure here would appear as a failure
  // of the URL check and not the process ID check.
  TestNavigationObserver back_observer(shell()->web_contents());
  shell()->web_contents()->GetController().GoBack();
  back_observer.Wait();
  EXPECT_EQ(child1_pid, child1->current_frame_host()->GetProcess()->GetID());
  ASSERT_EQ(child1_url, child1->current_url());
}

// Check that when site isolation is enabled, an origin can't create a blob URL
// for a different origin.  See https://crbug.com/886976.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       CreateBlobURLInDifferentOrigin) {
  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();

  // All these are attacker controlled values.
  std::string blob_type = "text/html";
  std::string blob_contents = "<html><body>pwned.</body></html>";
  std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";

  // Target a different origin.
  std::string target_origin = "http://b.com";

  // Set up a blob ID and populate it with attacker-controlled value. This
  // is just using the blob APIs directly since creating arbitrary blobs is not
  // what is prohibited; this data is not in any origin.
  std::unique_ptr<BlobHandle> blob = CreateMemoryBackedBlob(
      rfh->GetSiteInstance()->GetBrowserContext(), blob_contents, blob_type);
  std::string blob_id = blob->GetUUID();

  base::HistogramTester histograms;
  // Try registering a blob URL for b.com.  This IPC should result
  // in a kill because a.com should not be abllowed to create blob URLs outside
  // of its own origin.
  RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
  PwnMessageHelper::RegisterBlobURL(
      rfh->GetProcess(), GURL("blob:" + target_origin + "/" + blob_path),
      blob_id);
  // If the process is killed, this test passes.
  crash_observer.Wait();
  histograms.ExpectUniqueSample("Stability.BadMessageTerminated.Content",
                                139 /* BDH_DISALLOWED_ORIGIN */, 1);
}

class SecurityExploitBrowserTestMojoBlobURLs
    : public SecurityExploitBrowserTest {
 public:
  SecurityExploitBrowserTestMojoBlobURLs() {
    scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
  }

  void TearDown() override {
    storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(nullptr);
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Check that when site isolation is enabled, an origin can't create a blob URL
// for a different origin.  Similar to the test above, but checks the
// mojo-based Blob URL implementation.  See https://crbug.com/886976.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestMojoBlobURLs,
                       CreateMojoBlobURLInDifferentOrigin) {
  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();

  // Intercept future blob URL registrations and overwrite the blob URL origin
  // with b.com.
  std::string target_origin = "http://b.com";
  std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";
  BlobURLStoreInterceptor interceptor(
      GURL("blob:" + target_origin + "/" + blob_path));
  auto intercept_hook = base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
                                            base::Unretained(&interceptor));
  storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(&intercept_hook);

  // Register a blob URL from the a.com main frame, which will go through the
  // interceptor above and be rewritten to register the blob URL with the b.com
  // origin. This should result in a kill because a.com should not be allowed
  // to create blob URLs outside of its own origin.
  base::HistogramTester histograms;
  RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(), RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // The renderer should always get killed, but sometimes ExecuteScript returns
  // true anyway, so just ignore the result.
  ignore_result(
      content::ExecuteScript(rfh, "URL.createObjectURL(new Blob(['foo']))"));

  // If the process is killed, this test passes.
  crash_observer.Wait();
  histograms.ExpectUniqueSample("Stability.BadMessageTerminated.Content", 123,
                                1);
}

// Check that with site isolation enabled, an origin can't create a filesystem
// URL for a different origin.  See https://crbug.com/888001.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       CreateFilesystemURLInDifferentOrigin) {
  IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHost* rfh = shell()->web_contents()->GetMainFrame();

  // Block the renderer on operation that never completes, to shield it from
  // receiving unexpected browser->renderer IPCs that might CHECK.
  rfh->ExecuteJavaScriptWithUserGestureForTests(
      base::ASCIIToUTF16("var r = new XMLHttpRequest();"
                         "r.open('GET', '/slow?99999', false);"
                         "r.send(null);"
                         "while (1);"));

  // Set up a blob ID and populate it with attacker-controlled value. This
  // is just using the blob APIs directly since creating arbitrary blobs is not
  // what is prohibited; this data is not in any origin.
  std::string payload = "<html><body>pwned.</body></html>";
  std::string payload_type = "text/html";
  std::unique_ptr<content::BlobHandle> blob = CreateMemoryBackedBlob(
      rfh->GetSiteInstance()->GetBrowserContext(), payload, payload_type);
  std::string blob_id = blob->GetUUID();

  // Target a different origin.
  std::string target_origin = "http://b.com";
  GURL target_url =
      GURL("filesystem:" + target_origin + "/temporary/exploit.html");

  // Note: a well-behaved renderer would always call Open first before calling
  // Create and Write, but it's actually not necessary for the original attack
  // to succeed, so we omit it. As a result there are some log warnings from the
  // quota observer.

  PwnMessageHelper::FileSystemCreate(rfh->GetProcess(), 23, target_url, false,
                                     false, false);

  // Write the blob into the file. If successful, this places an
  // attacker-controlled value in a resource on the target origin.
  PwnMessageHelper::FileSystemWrite(rfh->GetProcess(), 24, target_url, blob_id,
                                    0);

  // Now navigate to |target_url| in a subframe. It should not succeed, and the
  // subframe should not contain |payload|.
  TestNavigationObserver observer(shell()->web_contents());
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  NavigateFrameToURL(root->child_at(0), target_url);
  EXPECT_FALSE(observer.last_navigation_succeeded());
  EXPECT_EQ(net::ERR_FILE_NOT_FOUND, observer.last_net_error_code());

  RenderFrameHost* attacked_rfh = root->child_at(0)->current_frame_host();
  std::string body =
      EvalJs(attacked_rfh, "document.body.innerText").ExtractString();
  EXPECT_TRUE(base::StartsWith(body, "Could not load the requested resource",
                               base::CompareCase::INSENSITIVE_ASCII))
      << " body=" << body;
}

// Verify that when a compromised renderer tries to navigate a remote frame to
// a disallowed URL (e.g., file URL), that navigation is blocked.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       BlockIllegalOpenURLFromRemoteFrame) {
  // Explicitly isolating a.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("a.com");

  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                            ->GetFrameTree()
                            ->root();
  FrameTreeNode* child = root->child_at(0);

  // Simulate an IPC message where the top frame asks the remote subframe to
  // navigate to a file: URL.
  GURL file_url("file:///");
  FrameHostMsg_OpenURL_Params params;
  params.url = file_url;
  params.uses_post = false;
  params.disposition = WindowOpenDisposition::CURRENT_TAB;
  params.should_replace_current_entry = false;
  params.user_gesture = true;
  params.is_history_navigation_in_new_child = false;

  SiteInstance* a_com_instance = root->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* proxy =
      child->render_manager()->GetRenderFrameProxyHost(a_com_instance);
  EXPECT_TRUE(proxy);

  {
    FrameHostMsg_OpenURL msg(proxy->GetRoutingID(), params);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        proxy->GetProcess()->GetChannel(), msg);
  }

  // Verify that the malicious navigation was blocked.  Currently, this happens
  // by rewriting the target URL to about:blank#blocked.
  //
  // TODO(alexmos): Consider killing the renderer process in this case, since
  // this security check is already enforced in the renderer process.
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(GURL(kBlockedURL),
            child->current_frame_host()->GetLastCommittedURL());

  // Navigate to the starting page again to recreate the proxy, then try the
  // same malicious navigation with a chrome:// URL.
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  child = root->child_at(0);
  proxy = child->render_manager()->GetRenderFrameProxyHost(a_com_instance);
  EXPECT_TRUE(proxy);

  GURL chrome_url(std::string(kChromeUIScheme) + "://" +
                  std::string(kChromeUIGpuHost));
  params.url = chrome_url;
  {
    FrameHostMsg_OpenURL msg(proxy->GetRoutingID(), params);
    IPC::IpcSecurityTestUtil::PwnMessageReceived(
        proxy->GetProcess()->GetChannel(), msg);
  }
  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
  EXPECT_EQ(GURL(kBlockedURL),
            child->current_frame_host()->GetLastCommittedURL());
}

class PostMessageIpcInterceptor : public BrowserMessageFilter {
 public:
  // Starts listening for IPC messages to |process|, intercepting
  // FrameHostMsg_RouteMessageEvent and storing once it comes.
  explicit PostMessageIpcInterceptor(RenderProcessHost* process)
      : BrowserMessageFilter(FrameMsgStart) {
    process->AddFilter(this);
  }

  // Waits for FrameMsg_PostMessage_Params (if it didn't come yet) and returns
  // message payload to the caller.
  void WaitForMessage(int32_t* out_routing_id,
                      FrameMsg_PostMessage_Params* out_params) {
    run_loop_.Run();
    *out_routing_id = intercepted_routing_id_;
    *out_params = intercepted_params_;
  }

 private:
  ~PostMessageIpcInterceptor() override = default;

  void OnRouteMessageEvent(const FrameMsg_PostMessage_Params& params) {
    intercepted_params_ = params;

    // UaF would have happened without the call below - the call ensures that
    // the data is still valid even once the original message is destroyed.
    intercepted_params_.message->data.EnsureDataIsOwned();
  }

  bool OnMessageReceived(const IPC::Message& message) override {
    // Only intercept one message.
    if (already_intercepted_)
      return false;

    // See if we got FrameHostMsg_RouteMessageEvent and if so unpack and store
    // its payload in OnRouteMessageEvent.
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(PostMessageIpcInterceptor, message)
      IPC_MESSAGE_HANDLER(FrameHostMsg_RouteMessageEvent, OnRouteMessageEvent)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()

    // If we got FrameHostMsg_RouteMessageEvent, then also store the routing ID
    // and signal to the main test thread that it can stop waiting.
    if (handled) {
      already_intercepted_ = true;
      intercepted_routing_id_ = message.routing_id();
      run_loop_.Quit();
    }

    return handled;
  }

  bool already_intercepted_ = false;
  int32_t intercepted_routing_id_;
  FrameMsg_PostMessage_Params intercepted_params_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(PostMessageIpcInterceptor);
};

// Test verifying that a compromised renderer can't lie about
// FrameMsg_PostMessage_Params::source_origin.  See also
// https://crbug.com/915721.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, PostMessageSourceOrigin) {
  // Explicitly isolating a.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("b.com");

  // Navigate to a page with an OOPIF.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));

  // Sanity check of test setup: main frame and subframe should be isolated.
  WebContents* web_contents = shell()->web_contents();
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  RenderFrameHost* subframe = web_contents->GetAllFrames()[1];
  EXPECT_NE(main_frame->GetProcess(), subframe->GetProcess());

  // Prepare to intercept FrameHostMsg_RouteMessageEvent IPC message that will
  // come from the subframe process.
  RenderProcessHost* subframe_process = subframe->GetProcess();
  auto ipc_interceptor =
      base::MakeRefCounted<PostMessageIpcInterceptor>(subframe_process);

  // Post a message from the subframe to the cross-site parent and intercept the
  // associated IPC message.
  EXPECT_TRUE(ExecJs(subframe, "parent.postMessage('blah', '*')"));
  int intercepted_routing_id;
  FrameMsg_PostMessage_Params intercepted_params;
  ipc_interceptor->WaitForMessage(&intercepted_routing_id, &intercepted_params);

  // Change the intercepted message to simulate a compromised subframe renderer
  // lying that the |source_origin| of the postMessage is the origin of the
  // parent (not of the subframe).
  url::Origin invalid_origin =
      web_contents->GetMainFrame()->GetLastCommittedOrigin();
  FrameMsg_PostMessage_Params evil_params = intercepted_params;
  evil_params.source_origin = base::UTF8ToUTF16(invalid_origin.Serialize());
  FrameHostMsg_RouteMessageEvent evil_msg(intercepted_routing_id, evil_params);

  // Inject the invalid IPC and verify that the renderer gets terminated.
  RenderProcessHostKillWaiter kill_waiter(subframe_process);
  IpcSecurityTestUtil::PwnMessageReceived(subframe_process->GetChannel(),
                                          evil_msg);
  EXPECT_EQ(bad_message::RFPH_POST_MESSAGE_INVALID_SOURCE_ORIGIN,
            kill_waiter.Wait());
}

class OpenUrlIpcInterceptor : public BrowserMessageFilter {
 public:
  // Starts listening for IPC messages to |process|, intercepting
  // FrameHostMsg_OpenURL IPC message and storing once it comes.
  explicit OpenUrlIpcInterceptor(RenderProcessHost* process)
      : BrowserMessageFilter(FrameMsgStart) {
    process->AddFilter(this);
  }

  // Waits for FrameHostMsg_OpenURL (if it didn't come yet) and returns
  // message payload to the caller.
  void WaitForMessage(int32_t* out_routing_id,
                      FrameHostMsg_OpenURL_Params* out_params) {
    run_loop_.Run();
    *out_routing_id = intercepted_routing_id_;
    *out_params = intercepted_params_;
  }

 private:
  ~OpenUrlIpcInterceptor() override = default;

  void OnOpenURL(const FrameHostMsg_OpenURL_Params& params) {
    intercepted_params_ = params;
  }

  bool OnMessageReceived(const IPC::Message& message) override {
    // Only intercept one message.
    if (already_intercepted_)
      return false;

    // See if we got FrameHostMsg_RouteMessageEvent and if so unpack and store
    // its payload in OnRouteMessageEvent.
    bool handled = true;
    IPC_BEGIN_MESSAGE_MAP(OpenUrlIpcInterceptor, message)
      IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()

    // If we got FrameHostMsg_RouteMessageEvent, then also store the routing ID
    // and signal to the main test thread that it can stop waiting.
    if (handled) {
      already_intercepted_ = true;
      intercepted_routing_id_ = message.routing_id();
      run_loop_.Quit();
    }

    return handled;
  }

  bool already_intercepted_ = false;
  int32_t intercepted_routing_id_;
  FrameHostMsg_OpenURL_Params intercepted_params_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(OpenUrlIpcInterceptor);
};

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       InvalidRemoteNavigationInitiator) {
  // Explicitly isolating a.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("a.com");

  // Navigate to a test page where the subframe is cross-site (and because of
  // IsolateOrigin call above in a separate process) from the main frame.
  GURL main_url(embedded_test_server()->GetURL(
      "a.com", "/cross_site_iframe_factory.html?a(b)"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  RenderFrameHost* main_frame = shell()->web_contents()->GetMainFrame();
  RenderProcessHost* main_process = main_frame->GetProcess();
  EXPECT_EQ(2u, shell()->web_contents()->GetAllFrames().size());
  RenderFrameHost* subframe = shell()->web_contents()->GetAllFrames()[1];
  RenderProcessHost* subframe_process = subframe->GetProcess();
  EXPECT_NE(main_process->GetID(), subframe_process->GetID());

  // Prepare to intercept FrameHostMsg_OpenURL IPC message that will come from
  // the main frame process.
  auto ipc_interceptor =
      base::MakeRefCounted<OpenUrlIpcInterceptor>(main_process);

  // Have the main frame request navigation in the "remote" subframe.  This will
  // result in FrameHostMsg_OpenURL IPC being sent to the RenderFrameProxyHost.
  EXPECT_TRUE(ExecJs(shell()->web_contents()->GetMainFrame(),
                     "window.frames[0].location = '/title1.html';"));
  int intercepted_routing_id;
  FrameHostMsg_OpenURL_Params intercepted_params;
  ipc_interceptor->WaitForMessage(&intercepted_routing_id, &intercepted_params);

  // Change the intercepted message to simulate a compromised subframe renderer
  // lying that the |initiator_origin| is the origin of the |subframe|.
  FrameHostMsg_OpenURL_Params evil_params = intercepted_params;
  evil_params.initiator_origin = subframe->GetLastCommittedOrigin();
  FrameHostMsg_OpenURL evil_msg(intercepted_routing_id, evil_params);

  // Inject the invalid IPC and verify that the renderer gets terminated.
  RenderProcessHostKillWaiter kill_waiter(main_process);
  IpcSecurityTestUtil::PwnMessageReceived(main_process->GetChannel(), evil_msg);
  EXPECT_EQ(bad_message::INVALID_INITIATOR_ORIGIN, kill_waiter.Wait());
}

class BeginNavigationInitiatorReplacer : public FrameHostInterceptor {
 public:
  BeginNavigationInitiatorReplacer(
      WebContents* web_contents,
      base::Optional<url::Origin> initiator_to_inject)
      : FrameHostInterceptor(web_contents),
        initiator_to_inject_(initiator_to_inject) {}

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      CommonNavigationParams* common_params,
      mojom::BeginNavigationParamsPtr* begin_params,
      blink::mojom::BlobURLTokenPtr* blob_url_token,
      mojom::NavigationClientAssociatedPtrInfo* navigation_client,
      blink::mojom::NavigationInitiatorPtr* navigation_initiator) override {
    if (is_activated_) {
      common_params->initiator_origin = initiator_to_inject_;
      is_activated_ = false;
    }

    return true;
  }

  void Activate() { is_activated_ = true; }

 private:
  base::Optional<url::Origin> initiator_to_inject_;
  bool is_activated_ = false;

  DISALLOW_COPY_AND_ASSIGN(BeginNavigationInitiatorReplacer);
};

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       InvalidBeginNavigationInitiator) {
  // Explicitly isolating a.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("a.com");

  // Prepare to intercept BeginNavigation mojo IPC.  This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  WebContents* web_contents = shell()->web_contents();
  BeginNavigationInitiatorReplacer injector(
      web_contents, url::Origin::Create(GURL("http://b.com")));

  // Navigate to a test page that will be locked to a.com.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(web_contents, main_url));

  // Start monitoring for renderer kills.
  RenderProcessHost* main_process = web_contents->GetMainFrame()->GetProcess();
  RenderProcessHostKillWaiter kill_waiter(main_process);

  // Have the main frame navigate and lie that the initiator origin is b.com.
  injector.Activate();
  // Don't expect a response for the script, as the process may be killed
  // before the script sends its completion message.
  ExecuteScriptAsync(web_contents, "window.location = '/title2.html';");

  // Verify that the renderer was terminated.
  EXPECT_EQ(bad_message::INVALID_INITIATOR_ORIGIN, kill_waiter.Wait());
}

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       MissingBeginNavigationInitiator) {
  // Prepare to intercept BeginNavigation mojo IPC.  This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  WebContents* web_contents = shell()->web_contents();
  BeginNavigationInitiatorReplacer injector(web_contents, base::nullopt);

  // Navigate to a test page.
  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(web_contents, main_url));

  // Start monitoring for renderer kills.
  RenderProcessHost* main_process = web_contents->GetMainFrame()->GetProcess();
  RenderProcessHostKillWaiter kill_waiter(main_process);

  // Have the main frame submit a BeginNavigation IPC with a missing initiator.
  injector.Activate();
  // Don't expect a response for the script, as the process may be killed
  // before the script sends its completion message.
  ExecuteScriptAsync(web_contents, "window.location = '/title2.html';");

  // Verify that the renderer was terminated.
  EXPECT_EQ(bad_message::RFHI_BEGIN_NAVIGATION_MISSING_INITIATOR_ORIGIN,
            kill_waiter.Wait());
}

namespace {

// An interceptor class that allows replacing the URL of the commit IPC from
// the renderer process to the browser process.
class DidCommitUrlReplacer : public DidCommitNavigationInterceptor {
 public:
  DidCommitUrlReplacer(WebContents* web_contents, const GURL& replacement_url)
      : DidCommitNavigationInterceptor(web_contents),
        replacement_url_(replacement_url) {}
  ~DidCommitUrlReplacer() override = default;

 protected:
  bool WillProcessDidCommitNavigation(
      RenderFrameHost* render_frame_host,
      NavigationRequest* navigation_request,
      ::FrameHostMsg_DidCommitProvisionalLoad_Params* params,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr* interface_params)
      override {
    params->url = replacement_url_;
    return true;
  }

 private:
  GURL replacement_url_;

  DISALLOW_COPY_AND_ASSIGN(DidCommitUrlReplacer);
};

}  // namespace

// Test which verifies that when an exploited renderer process sends a commit
// message with URL that the process is not allowed to commit.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, DidCommitInvalidURL) {
  // Explicitly isolating foo.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("foo.com");

  // Navigate to foo.com initially.
  GURL foo_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), foo_url));

  // Create the interceptor object which will replace the URL of the subsequent
  // navigation with bar.com based URL.
  GURL bar_url(embedded_test_server()->GetURL("bar.com", "/title3.html"));
  DidCommitUrlReplacer url_replacer(shell()->web_contents(), bar_url);

  // Navigate to another URL within foo.com, which would usually be committed
  // succsesfuly, but when the URL is modified it should result in the
  // termination of the renderer process.
  RenderProcessHostKillWaiter kill_waiter(
      shell()->web_contents()->GetMainFrame()->GetProcess());
  NavigateToURL(shell(),
                embedded_test_server()->GetURL("foo.com", "/title2.html"));
  EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait());
}

class BeginNavigationTransitionReplacer : public FrameHostInterceptor {
 public:
  BeginNavigationTransitionReplacer(WebContents* web_contents,
                                    ui::PageTransition transition_to_inject)
      : FrameHostInterceptor(web_contents),
        transition_to_inject_(transition_to_inject) {}

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      CommonNavigationParams* common_params,
      mojom::BeginNavigationParamsPtr* begin_params,
      blink::mojom::BlobURLTokenPtr* blob_url_token,
      mojom::NavigationClientAssociatedPtrInfo* navigation_client,
      blink::mojom::NavigationInitiatorPtr* navigation_initiator) override {
    if (is_activated_) {
      common_params->transition = transition_to_inject_;
      is_activated_ = false;
    }

    return true;
  }

  void Activate() { is_activated_ = true; }

 private:
  ui::PageTransition transition_to_inject_;
  bool is_activated_ = false;

  DISALLOW_COPY_AND_ASSIGN(BeginNavigationTransitionReplacer);
};

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, NonWebbyTransition) {
  const ui::PageTransition test_cases[] = {
      ui::PAGE_TRANSITION_TYPED,
      ui::PAGE_TRANSITION_AUTO_BOOKMARK,
      ui::PAGE_TRANSITION_GENERATED,
      ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
      ui::PAGE_TRANSITION_RELOAD,
      ui::PAGE_TRANSITION_KEYWORD,
      ui::PAGE_TRANSITION_KEYWORD_GENERATED};

  for (ui::PageTransition transition : test_cases) {
    // Prepare to intercept BeginNavigation mojo IPC.  This has to be done
    // before the test creates the RenderFrameHostImpl that is the target of the
    // IPC.
    WebContents* web_contents = shell()->web_contents();
    BeginNavigationTransitionReplacer injector(web_contents, transition);

    // Navigate to a test page.
    GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
    EXPECT_TRUE(NavigateToURL(web_contents, main_url));

    // Start monitoring for renderer kills.
    RenderProcessHost* main_process =
        web_contents->GetMainFrame()->GetProcess();
    RenderProcessHostKillWaiter kill_waiter(main_process);

    // Have the main frame submit a BeginNavigation IPC with a missing
    // initiator.
    injector.Activate();
    // Don't expect a response for the script, as the process may be killed
    // before the script sends its completion message.
    ExecuteScriptAsync(web_contents, "window.location = '/title2.html';");

    // Verify that the renderer was terminated.
    EXPECT_EQ(bad_message::RFHI_BEGIN_NAVIGATION_NON_WEBBY_TRANSITION,
              kill_waiter.Wait());
  }
}

}  // namespace content
