// 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/guid.h"
#include "base/macros.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/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_provisional_load_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 = RESOURCE_TYPE_XHR;
  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_;
};

}  // 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) {
    ChildProcessSecurityPolicyImpl::GetInstance()->AddIsolatedOrigins(
        {url::Origin::Create(embedded_test_server()->GetURL(hostname, "/"))});

    // Force a BrowsingInstance swap by navigating cross-site (the newly
    // isolated origin only affects *future* BrowsingInstances).
    std::string cross_site_hostname = base::GenerateGUID() + ".com";
    EXPECT_TRUE(NavigateToURL(
        shell(),
        embedded_test_server()->GetURL(cross_site_hostname, "/title1.html")));
  }
};

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.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       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
}

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 DidCommitProvisionalLoadInterceptor {
 public:
  ScopedInterfaceParamsReplacer(
      WebContents* web_contents,
      mojom::DidCommitProvisionalLoadInterfaceParamsPtr params_override)
      : DidCommitProvisionalLoadInterceptor(web_contents),
        params_override_(std::move(params_override)) {}
  ~ScopedInterfaceParamsReplacer() override = default;

 protected:
  bool WillDispatchDidCommitProvisionalLoad(
      RenderFrameHost* render_frame_host,
      ::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());
}

}  // namespace content
