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

#include <stdint.h>

#include <optional>
#include <tuple>

#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "content/browser/attribution_reporting/attribution_manager.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/fenced_frame/fenced_frame.h"
#include "content/browser/private_aggregation/private_aggregation_manager.h"
#include "content/browser/renderer_host/navigator.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/renderer_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/file_chooser_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/features.h"
#include "content/common/frame.mojom.h"
#include "content/common/frame_messages.mojom.h"
#include "content/common/render_message_filter.mojom.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/navigation_handle.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/isolated_world_ids.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.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/fenced_frame_test_util.h"
#include "content/public/test/navigation_handle_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_renderer_host.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/test_content_browser_client.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_security_test_util.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/test_support/test_utils.h"
#include "net/base/features.h"
#include "net/base/filename_util.h"
#include "net/base/network_isolation_key.h"
#include "net/dns/mock_host_resolver.h"
#include "net/storage_access_api/status.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/trust_tokens.mojom.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/blob/blob_utils.h"
#include "third_party/blink/public/common/fenced_frame/fenced_frame_utils.h"
#include "third_party/blink/public/common/frame/fenced_frame_sandbox_flags.h"
#include "third_party/blink/public/common/navigation/navigation_policy.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"
#include "third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom.h"
#include "third_party/blink/public/mojom/frame/frame.mojom-test-utils.h"
#include "third_party/blink/public/mojom/frame/frame.mojom.h"
#include "third_party/blink/public/mojom/frame/remote_frame.mojom-test-utils.h"
#include "third_party/blink/public/mojom/loader/mixed_content.mojom.h"

using IPC::IpcSecurityTestUtil;
using ::testing::HasSubstr;
using ::testing::Optional;

namespace content {

namespace {

// 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,
                                             net::EmbeddedTestServer* server,
                                             int* target_routing_id) {
  GURL foo("http://foo.com/simple_page.html");

  if (IsIsolatedOriginRequiredToGuaranteeDedicatedProcess()) {
    // Isolate "bar.com" so we are guaranteed to get a different process
    // for navigations to this origin.
    IsolateOriginsForTesting(server, shell->web_contents(), {"bar.com"});
  }

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

  // Open another window, so we generate some more routing ids.
  ShellAddedObserver shell2_observer;
  EXPECT_TRUE(ExecJs(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()
                ->GetPrimaryMainFrame()
                ->GetProcess()
                ->GetDeprecatedID(),
            shell2->web_contents()
                ->GetPrimaryMainFrame()
                ->GetProcess()
                ->GetDeprecatedID());
  *target_routing_id = shell2->web_contents()
                           ->GetPrimaryMainFrame()
                           ->GetRenderViewHost()
                           ->GetRoutingID();
  EXPECT_NE(*target_routing_id, shell->web_contents()
                                    ->GetPrimaryMainFrame()
                                    ->GetRenderViewHost()
                                    ->GetRoutingID());

  // Now, simulate a link click coming from the renderer.
  GURL extension_url("http://bar.com/simple_page.html");
  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell->web_contents());
  TestNavigationManager navigation_manager(wc, extension_url);
  wc->GetPrimaryFrameTree().root()->navigator().RequestOpenURL(
      wc->GetPrimaryFrameTree().root()->current_frame_host(), extension_url,
      nullptr /* initiator_frame_token */,
      ChildProcessHost::kInvalidUniqueID /* initiator_process_id */,
      url::Origin::Create(foo), /* initiator_base_url= */ std::nullopt, nullptr,
      std::string(), Referrer(), WindowOpenDisposition::CURRENT_TAB,
      false /* should_replace_current_entry */, true /* user_gesture */,
      blink::mojom::TriggeringEventInfo::kFromTrustedEvent, std::string(),
      nullptr /* blob_url_loader_factory */, std::nullopt /* impression */,
      false /* has_rel_opener */);
  navigation_manager.WaitForSpeculativeRenderFrameHostCreation();

  // 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->GetPrimaryFrameTree()
                                      .root()
                                      ->render_manager()
                                      ->speculative_frame_host();

  EXPECT_TRUE(next_rfh);
  EXPECT_NE(shell->web_contents()
                ->GetPrimaryMainFrame()
                ->GetProcess()
                ->GetDeprecatedID(),
            next_rfh->GetProcess()->GetDeprecatedID());

  return next_rfh;
}

blink::mojom::OpenURLParamsPtr CreateOpenURLParams(const GURL& url) {
  auto params = blink::mojom::OpenURLParams::New();
  params->url = url;
  params->disposition = WindowOpenDisposition::CURRENT_TAB;
  params->should_replace_current_entry = false;
  params->user_gesture = true;
  return params;
}

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;
  browser_context->CreateMemoryBackedBlob(
      base::as_byte_span(contents), 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;
}

// 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, std::u16string(),
                                          std::vector<std::u16string>()));
    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,
                      scoped_refptr<FileSelectListener> listener,
                      const blink::mojom::FileChooserParams& params) override {
    listener_ = std::move(listener);
  }

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

 private:
  scoped_refptr<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();
  }

 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");
  EXPECT_TRUE(NavigateToURL(shell(), foo));
  EXPECT_EQ(u"OK", shell()->web_contents()->GetTitle());

  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetPrimaryMainFrame();
  blink::mojom::FileChooserParamsPtr params =
      blink::mojom::FileChooserParams::New();
  params->default_file_name = path;

  mojo::test::BadMessageObserver bad_message_observer;
  mojo::Remote<blink::mojom::FileChooser> chooser =
      FileChooserImpl::CreateBoundForTesting(
          static_cast<RenderFrameHostImpl*>(compromised_renderer));
  chooser->OpenFileChooser(
      std::move(params), blink::mojom::FileChooser::OpenFileChooserCallback());
  chooser.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");

  EXPECT_TRUE(NavigateToURL(shell(), foo));
  EXPECT_EQ(u"OK", shell()->web_contents()->GetTitle());
  EXPECT_TRUE(shell()
                  ->web_contents()
                  ->GetPrimaryMainFrame()
                  ->GetEnabledBindings()
                  .empty());

  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetPrimaryMainFrame();
  RenderProcessHostBadIpcMessageWaiter 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(), embedded_test_server(), &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/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 BUILDFLAG(IS_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) {
  EXPECT_TRUE(NavigateToURL(shell(), GURL("http://foo.com/simple_page.html")));
  RenderFrameHost* compromised_renderer =
      shell()->web_contents()->GetPrimaryMainFrame();
  auto delegate = std::make_unique<DelayedFileChooserDelegate>();
  shell()->web_contents()->SetDelegate(delegate.get());

  mojo::Remote<blink::mojom::FileChooser> chooser =
      FileChooserImpl::CreateBoundForTesting(
          static_cast<RenderFrameHostImpl*>(compromised_renderer));
  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 CorsExploitBrowserTest : public ContentBrowserTest {
 public:
  CorsExploitBrowserTest() = default;

  CorsExploitBrowserTest(const CorsExploitBrowserTest&) = delete;
  CorsExploitBrowserTest& operator=(const CorsExploitBrowserTest&) = delete;

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    SetupCrossSiteRedirector(embedded_test_server());
  }
};

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

  RenderProcessHostBadIpcMessageWaiter 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());
}

// Test that receiving a document.open() URL update with incorrect origin
// properly terminates the renderer process.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       MismatchedOriginOnDocumentOpenURLUpdate) {
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  // Simulate a document.open() URL update with incorrect origin.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(rfh->GetProcess());
  static_cast<mojom::FrameHost*>(rfh)->DidOpenDocumentInputStream(
      embedded_test_server()->GetURL("evil.com", "/title1.html"));

  // Ensure that the renderer process gets killed.
  EXPECT_EQ(AreAllSitesIsolatedForTesting()
                ? bad_message::RFH_CAN_COMMIT_URL_BLOCKED
                : bad_message::RFH_INVALID_ORIGIN_ON_COMMIT,
            kill_waiter.Wait());
}

// Test that same-document navigations cannot go cross-origin (even within the
// same site).
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       CrossOriginSameDocumentCommit) {
  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Do a same-document navigation to a cross-origin URL/Origin (which match
  // each other, unlike the MismatchedOriginOnCommit), using an interceptor that
  // replaces the origin and URL. This intentionally uses a cross-origin but
  // same-site destination, to avoid failing Site Isolation checks.
  GURL dest_url(embedded_test_server()->GetURL("bar.foo.com", "/title2.html"));
  PwnCommitIPC(shell()->web_contents(), start_url, dest_url,
               url::Origin::Create(dest_url));
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());
  // ExecJs will sometimes finish before the renderer gets killed, so we must
  // ignore the result.
  std::ignore = ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       "history.pushState({}, '', location.href);");
  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}

// Test that same-document navigations cannot go cross-origin from about:blank
// (even within the same site). Uses a subframe to inherit an existing origin.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       CrossOriginSameDocumentCommitFromAboutBlank) {
  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Create an about:blank iframe that inherits the origin.
  RenderFrameHost* subframe =
      CreateSubframe(static_cast<WebContentsImpl*>(shell()->web_contents()),
                     "child1", GURL(), false /* wait_for_navigation */);
  EXPECT_EQ(url::Origin::Create(start_url), subframe->GetLastCommittedOrigin());

  // Do a same-document navigation to another about:blank URL, but using a
  // different origin. This intentionally uses a cross-origin but same-site
  // origin to avoid triggering Site Isolation checks.
  GURL blank_url("about:blank#foo");
  GURL fake_url(embedded_test_server()->GetURL("bar.foo.com", "/"));
  PwnCommitIPC(shell()->web_contents(), blank_url, blank_url,
               url::Origin::Create(fake_url));
  RenderProcessHostBadIpcMessageWaiter kill_waiter(subframe->GetProcess());
  // ExecJs will sometimes finish before the renderer gets killed, so we must
  // ignore the result.
  std::ignore = ExecJs(subframe, "location.hash='foo';");
  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}

// Test that same-document navigations cannot go cross-origin (even within the
// same site), in the case that allow_universal_access_from_file_urls is enabled
// but the last committed origin is not a file URL.  See also
// RenderFrameHostManagerTest.EnsureUniversalAccessFromFileSchemeSucceeds for
// the intended case that file URLs are allowed to go cross-origin.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       CrossOriginSameDocumentCommitUniversalAccessNonFile) {
  auto prefs = shell()->web_contents()->GetOrCreateWebPreferences();
  prefs.allow_universal_access_from_file_urls = true;
  shell()->web_contents()->SetWebPreferences(prefs);

  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Do a same-document navigation to a cross-origin URL, using an interceptor
  // that replaces the URL but not the origin (to simulate the universal access
  // case, but for a non-file committed origin). This intentionally uses a
  // cross-origin but same-site destination, to avoid failing Site Isolation
  // checks.
  GURL dest_url(embedded_test_server()->GetURL("bar.foo.com", "/title2.html"));
  PwnCommitIPC(shell()->web_contents(), start_url, dest_url,
               url::Origin::Create(start_url));
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());
  // ExecJs will sometimes finish before the renderer gets killed, so we must
  // ignore the result.
  std::ignore = ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       "history.pushState({}, '', location.href);");
  EXPECT_EQ(bad_message::RFH_INVALID_ORIGIN_ON_COMMIT, kill_waiter.Wait());
}

// Test that receiving a commit with a URL with an invalid scheme properly
// terminates the renderer process. See https://crbug.com/324934416.
// TODO(crbug.com/40092527): This test can be removed once the browser
// stops using cross-document URLs computed by the renderer process.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, BadUrlSchemeOnCommit) {
  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

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

  // Navigate to a new URL, with an interceptor that replaces the URL with one
  // that has an illegal scheme. Note that most cross-document navigations where
  // the renderer's commit URL disagrees with the browser's expectation will
  // currently be caught by a DCHECK in debug builds, but this case still works
  // in release builds until the browser process becomes the authority for
  // cross-document URLs in https://crbug.com/888079. For now, we can test this
  // case and avoid the DCHECK by claiming to commit about:blank#blocked, which
  // is given an exception in RenderFrameHostImpl's CalculateLoadingURL.
  GURL url("about:blank#blocked");
  GURL bad_scheme_url("bar:com");
  PwnCommitIPC(shell()->web_contents(), url, bad_scheme_url,
               url::Origin::Create(url));

  RenderProcessHost* process = root->current_frame_host()->GetProcess();
  RenderProcessHostBadIpcMessageWaiter kill_waiter(process);

  // ExecJs will sometimes finish before the renderer gets killed, so we must
  // ignore the result.
  std::ignore = ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       "location.href = 'about:blank#blocked';");

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

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

// Test that receiving a same-document commit with a URL with an invalid scheme
// properly terminates the renderer process. See https://crbug.com/324934416.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       BadUrlSchemeOnSameDocumentCommit) {
  GURL start_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Do a same-document navigation to a URL with an incorrect scheme, but with
  // the expected origin, using an interceptor that replaces the URL.
  GURL dest_url("bar:com");
  PwnCommitIPC(shell()->web_contents(), start_url, dest_url,
               url::Origin::Create(start_url));
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());
  // ExecJs will sometimes finish before the renderer gets killed, so we must
  // ignore the result.
  std::ignore = ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       "history.pushState({}, '', location.href);");
  EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, 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(const ScopedInterfaceParamsReplacer&) = delete;
  ScopedInterfaceParamsReplacer& operator=(
      const ScopedInterfaceParamsReplacer&) = delete;

  ~ScopedInterfaceParamsReplacer() override = default;

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

    return true;
  }

 private:
  mojom::DidCommitProvisionalLoadInterfaceParamsPtr params_override_;
};

}  // 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/40519010): when all clients are converted to use
// BrowserInterfaceBroker, PendingReceiver<InterfaceProvider>-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()->GetPrimaryMainFrame());
  RenderProcessHostBadIpcMessageWaiter kill_waiter(frame->GetProcess());

  NavigationHandleObserver navigation_observer(shell()->web_contents(),
                                               non_same_document_url);
  ScopedInterfaceParamsReplacer replacer(shell()->web_contents(), nullptr);
  EXPECT_TRUE(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 behind and
  // leak NavigationRequests - see https://crbug.com/869193.
  EXPECT_FALSE(frame->HasPendingCommitNavigation());
  EXPECT_FALSE(navigation_observer.has_committed());
  EXPECT_TRUE(navigation_observer.is_error());
  EXPECT_TRUE(navigation_observer.last_committed_url().is_empty());
  EXPECT_EQ(net::OK, navigation_observer.net_error_code());
}

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

  RenderProcessHostBadIpcMessageWaiter 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_TRUE(base::WriteFile(file_path, file_content));

  // Simulate an OpenURL Mojo method asking to POST a file that the renderer
  // shouldn't have access to.
  auto params = CreateOpenURLParams(target_url);
  params->post_body = new network::ResourceRequestBody;
  params->post_body->AppendFileRange(file_path, 0, file_content.size(),
                                     base::Time());
  params->should_replace_current_entry = true;

  static_cast<mojom::FrameHost*>(root->current_frame_host())
      ->OpenURL(std::move(params));

  // Verify that the malicious navigation did not commit the navigation to
  // |target_url|.
  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());
}

// Forging a navigation commit after the initial empty document will result in a
// renderer kill, even if the URL used is about:blank.
// See https://crbug.com/766262 for an example advanced case that involves
// forging a frame's unique name.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       NonInitialAboutBlankRendererKill) {
  // Navigate normally.
  GURL url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), url));
  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  // Simulate an about:blank commit without a NavigationRequest. It will fail
  // because only initial commits are allowed to do this.
  auto params = mojom::DidCommitProvisionalLoadParams::New();
  params->did_create_new_entry = false;
  params->url = GURL("about:blank");
  params->referrer = blink::mojom::Referrer::New();
  params->transition = ui::PAGE_TRANSITION_LINK;
  params->should_update_history = false;
  params->method = "GET";
  params->page_state = blink::PageState::CreateFromURL(GURL("about:blank"));
  params->origin = url::Origin::Create(GURL("about:blank"));
  params->embedding_token = base::UnguessableToken::Create();
  RenderProcessHostBadIpcMessageWaiter kill_waiter(rfh->GetProcess());
  static_cast<mojom::FrameHost*>(rfh)->DidCommitProvisionalLoad(
      std::move(params),
      mojom::DidCommitProvisionalLoadInterfaceParams::New(
          mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>()
              .InitWithNewPipeAndPassReceiver()));

  // Verify that the malicious renderer got killed.
  EXPECT_EQ(bad_message::RFH_NO_MATCHING_NAVIGATION_REQUEST_ON_COMMIT,
            kill_waiter.Wait());
}

class SecurityExploitBrowserTestMojoBlobURLs
    : public SecurityExploitBrowserTest {
 public:
  SecurityExploitBrowserTestMojoBlobURLs() = default;

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

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

  // 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";

  base::RepeatingCallback<void(storage::BlobUrlRegistry*, mojo::ReceiverId)>
      blob_url_registry_intercept_hook;

  blob_url_registry_intercept_hook =
      base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
                          GURL("blob:" + target_origin + "/" + blob_path));
  storage::BlobUrlRegistry::SetURLStoreCreationHookForTesting(
      &blob_url_registry_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.
  content::RenderProcessHostBadMojoMessageWaiter crash_observer(
      rfh->GetProcess());

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

  // If the process is killed, this test passes.
  EXPECT_EQ(
      "Received bad user message: "
      "URL with invalid origin passed to BlobURLStore::Register",
      crash_observer.Wait());
}

// 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));
  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

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

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

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

  // 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())
                            ->GetPrimaryFrameTree()
                            .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())
                            ->GetPrimaryFrameTree()
                            .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.
  SiteInstanceImpl* a_com_instance =
      root->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* proxy =
      child->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(a_com_instance->group());
  EXPECT_TRUE(proxy);

  TestNavigationObserver observer(shell()->web_contents());
  static_cast<mojom::FrameHost*>(proxy->frame_tree_node()->current_frame_host())
      ->OpenURL(CreateOpenURLParams(GURL("file:///")));
  observer.Wait();

  // 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_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->current_frame_host()
              ->browsing_context_state()
              ->GetRenderFrameProxyHost(a_com_instance->group());
  EXPECT_TRUE(proxy);

  TestNavigationObserver observer_2(shell()->web_contents());
  GURL chrome_url(std::string(kChromeUIScheme) + "://" +
                  std::string(kChromeUIGpuHost));
  static_cast<mojom::FrameHost*>(proxy->frame_tree_node()->current_frame_host())
      ->OpenURL(CreateOpenURLParams(chrome_url));
  observer_2.Wait();
  EXPECT_EQ(GURL(kBlockedURL),
            child->current_frame_host()->GetLastCommittedURL());
}

class RemoteFrameHostInterceptor
    : public blink::mojom::RemoteFrameHostInterceptorForTesting {
 public:
  explicit RemoteFrameHostInterceptor(
      RenderFrameProxyHost* render_frame_proxy_host,
      const url::Origin& evil_origin)
      : evil_origin_(evil_origin),
        swapped_impl_(
            render_frame_proxy_host->frame_host_receiver_for_testing(),
            this) {}

  ~RemoteFrameHostInterceptor() override = default;

  RemoteFrameHost* GetForwardingInterface() override {
    return swapped_impl_.old_impl();
  }

  void RouteMessageEvent(
      const std::optional<blink::LocalFrameToken>& source_frame_token,
      const url::Origin& source_origin,
      const std::u16string& target_origin,
      blink::TransferableMessage message) override {
    // Forward the message to the actual RFPH replacing |source_origin| with the
    // "evil origin".
    GetForwardingInterface()->RouteMessageEvent(
        std::move(source_frame_token), evil_origin_, std::move(target_origin),
        std::move(message));
  }

  void OpenURL(blink::mojom::OpenURLParamsPtr params) override {
    intercepted_params_ = std::move(params);
  }

  blink::mojom::OpenURLParamsPtr GetInterceptedParams() {
    return std::move(intercepted_params_);
  }

 private:
  url::Origin evil_origin_;
  blink::mojom::OpenURLParamsPtr intercepted_params_;
  mojo::test::ScopedSwapImplForTesting<blink::mojom::RemoteFrameHost>
      swapped_impl_;
};

// Test verifying that a compromised renderer can't lie about the source_origin
// passed along with the RouteMessageEvent() mojo message.  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->GetPrimaryMainFrame();
  RenderFrameHost* subframe = ChildFrameAt(main_frame, 0);
  EXPECT_NE(main_frame->GetProcess(), subframe->GetProcess());

  // We need to get ahold of the RenderFrameProxyHost representing the main
  // frame for the subframe's process, to install the mojo interceptor.
  FrameTreeNode* main_frame_node =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  FrameTreeNode* subframe_node = main_frame_node->child_at(0);
  SiteInstanceImpl* b_com_instance =
      subframe_node->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* main_frame_proxy_host =
      main_frame_node->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(b_com_instance->group());

  // Prepare to intercept the RouteMessageEvent IPC message that will come
  // from the subframe process.
  url::Origin evil_source_origin =
      web_contents->GetPrimaryMainFrame()->GetLastCommittedOrigin();
  RemoteFrameHostInterceptor mojo_interceptor(main_frame_proxy_host,
                                              evil_source_origin);

  // Post a message from the subframe to the cross-site parent and intercept the
  // associated IPC message, changing it to simulate a compromised subframe
  // renderer lying that the |source_origin| of the postMessage is the origin of
  // the parent (not of the subframe).
  RenderProcessHostBadIpcMessageWaiter kill_waiter(subframe->GetProcess());
  EXPECT_TRUE(ExecJs(subframe, "parent.postMessage('blah', '*')"));
  EXPECT_EQ(bad_message::RFPH_POST_MESSAGE_INVALID_SOURCE_ORIGIN,
            kill_waiter.Wait());
}

// Test verifying that a compromised renderer can't lie about the source_origin
// passed along with the RouteMessageEvent() mojo message.  Similar to the test
// above, but exercises a scenario where the source origin is opaque and the
// precursor needs to be validated. This provides coverage for messages sent
// from sandboxed frames; see https://crbug.com/40606810 and
// https://crbug.com/325410297.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       PostMessageOpaqueSourceOrigin) {
  // This test requires opaque origin enforcements to be turned on; otherwise,
  // there would be no renderer kill to check for.
  if (!base::FeatureList::IsEnabled(
          features::kAdditionalOpaqueOriginEnforcements)) {
    GTEST_SKIP();
  }

  // Explicitly isolating b.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("b.com");

  GURL main_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), main_url));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* root = web_contents->GetPrimaryFrameTree().root();
  RenderFrameHostImpl* main_frame = root->current_frame_host();

  // Create cross-site sandboxed child frame.
  GURL child_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  {
    std::string js_str = base::StringPrintf(
        "var frame = document.createElement('iframe'); "
        "frame.sandbox = 'allow-scripts'; "
        "frame.src = '%s'; "
        "document.body.appendChild(frame);",
        child_url.spec().c_str());
    EXPECT_TRUE(ExecJs(main_frame, js_str));
    ASSERT_TRUE(WaitForLoadStop(web_contents));
  }

  // Sanity check of test setup: main frame and subframe should be in separate
  // processes, and subframe should be sandboxed.
  FrameTreeNode* subframe_node = root->child_at(0);
  RenderFrameHostImpl* subframe = subframe_node->current_frame_host();
  EXPECT_NE(main_frame->GetProcess(), subframe->GetProcess());
  EXPECT_TRUE(subframe->GetSiteInstance()->GetSiteInfo().is_sandboxed());

  // Retrieve the RenderFrameProxyHost representing the main frame for the
  // subframe's process.
  RenderFrameProxyHost* main_frame_proxy_host =
      main_frame->browsing_context_state()->GetRenderFrameProxyHost(
          subframe->GetSiteInstance()->group());

  // Prepare to intercept the RouteMessageEvent IPC message that will come from
  // the subframe process. Set the fake source origin to an opaque origin with
  // a.com as the precursor.
  url::Origin precursor_origin = main_frame->GetLastCommittedOrigin();
  url::Origin evil_source_origin = precursor_origin.DeriveNewOpaqueOrigin();
  EXPECT_TRUE(evil_source_origin.opaque());
  EXPECT_EQ("a.com",
            evil_source_origin.GetTupleOrPrecursorTupleIfOpaque().host());

  RemoteFrameHostInterceptor mojo_interceptor(main_frame_proxy_host,
                                              evil_source_origin);

  // Post a message from the subframe to the cross-site parent and intercept the
  // associated IPC message, changing it to simulate a compromised subframe
  // renderer lying that the |source_origin| of the postMessage has an incorrect
  // precursor of a.com, rather than b.com. This should result in a renderer
  // kill.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(subframe->GetProcess());
  EXPECT_TRUE(ExecJs(subframe, "parent.postMessage('blah', '*')"));
  EXPECT_EQ(bad_message::RFPH_POST_MESSAGE_INVALID_SOURCE_ORIGIN,
            kill_waiter.Wait());
}

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));
  RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());
  RenderProcessHost* main_process = main_frame->GetProcess();
  RenderFrameHost* subframe = ChildFrameAt(main_frame, 0);
  ASSERT_TRUE(subframe);
  RenderProcessHost* subframe_process = subframe->GetProcess();
  EXPECT_NE(main_process->GetDeprecatedID(),
            subframe_process->GetDeprecatedID());

  // Prepare to intercept OpenURL Mojo message that will come from
  // the main frame.
  FrameTreeNode* main_frame_node =
      static_cast<WebContentsImpl*>(shell()->web_contents())
          ->GetPrimaryFrameTree()
          .root();
  FrameTreeNode* child_node = main_frame_node->child_at(0);
  SiteInstanceImpl* a_com_instance =
      main_frame_node->current_frame_host()->GetSiteInstance();
  RenderFrameProxyHost* proxy =
      child_node->current_frame_host()
          ->browsing_context_state()
          ->GetRenderFrameProxyHost(a_com_instance->group());
  RenderProcessHostBadIpcMessageWaiter kill_waiter(main_process);
  {
    RemoteFrameHostInterceptor interceptor(proxy, url::Origin());

    // Have the main frame request navigation in the "remote" subframe.  This
    // will result in OpenURL Mojo message being sent to the
    // RenderFrameProxyHost.
    EXPECT_TRUE(ExecJs(shell()->web_contents()->GetPrimaryMainFrame(),
                       "window.frames[0].location = '/title1.html';"));

    // Change the intercepted message to simulate a compromised subframe
    // renderer lying that the |initiator_origin| is the origin of the
    // |subframe|.
    auto evil_params = interceptor.GetInterceptedParams();
    evil_params->initiator_origin = subframe->GetLastCommittedOrigin();

    // Inject the invalid IPC and verify that the renderer gets terminated.
    static_cast<mojom::FrameHost*>(main_frame)->OpenURL(std::move(evil_params));
  }

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

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

  BeginNavigationInitiatorReplacer(const BeginNavigationInitiatorReplacer&) =
      delete;
  BeginNavigationInitiatorReplacer& operator=(
      const BeginNavigationInitiatorReplacer&) = delete;

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      blink::mojom::CommonNavigationParamsPtr* common_params,
      blink::mojom::BeginNavigationParamsPtr* begin_params,
      mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token,
      mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client)
      override {
    if (is_activated_) {
      (*common_params)->initiator_origin = initiator_to_inject_;
      is_activated_ = false;
    }

    return true;
  }

  void Activate() { is_activated_ = true; }

 private:
  std::optional<url::Origin> initiator_to_inject_;
  bool is_activated_ = false;
};

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       InvalidBeginNavigationInitiator) {
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());

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

  // 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 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->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostBadIpcMessageWaiter 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());
}

// Similar to the test above, but ensure that initiator origins are validated
// even for opaque origins.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       InvalidBeginNavigationOpaqueInitiator) {
  // This test requires opaque origin enforcements to be turned on; otherwise,
  // there would be no renderer kill to check for.
  if (!base::FeatureList::IsEnabled(
          features::kAdditionalOpaqueOriginEnforcements)) {
    GTEST_SKIP();
  }

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

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

  // Explicitly isolating b.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("b.com");

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

  // Add a cross-site sandboxed child frame at b.com.
  FrameTreeNode* root = web_contents->GetPrimaryFrameTree().root();
  RenderFrameHostImpl* main_frame = root->current_frame_host();
  GURL child_url(embedded_test_server()->GetURL("b.com", "/title1.html"));
  {
    std::string js_str = base::StringPrintf(
        "var frame = document.createElement('iframe'); "
        "frame.sandbox = 'allow-scripts'; "
        "frame.src = '%s'; "
        "document.body.appendChild(frame);",
        child_url.spec().c_str());
    EXPECT_TRUE(ExecJs(main_frame, js_str));
    ASSERT_TRUE(WaitForLoadStop(web_contents));
  }

  // Sanity check of test setup: main frame and subframe should be in separate
  // processes, and subframe should be sandboxed.
  FrameTreeNode* subframe_node = root->child_at(0);
  RenderFrameHostImpl* subframe = subframe_node->current_frame_host();
  EXPECT_NE(main_frame->GetProcess(), subframe->GetProcess());
  EXPECT_TRUE(subframe->GetSiteInstance()->GetSiteInfo().is_sandboxed());

  // Start monitoring for renderer kills.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(subframe->GetProcess());

  // Have the sandboxed subframe navigate and lie that the initiator origin is
  // an opaque origin with the precursor of evil.com instead of 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(subframe, "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, std::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->GetPrimaryMainFrame()->GetProcess();
  RenderProcessHostBadIpcMessageWaiter 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(const DidCommitUrlReplacer&) = delete;
  DidCommitUrlReplacer& operator=(const DidCommitUrlReplacer&) = delete;

  ~DidCommitUrlReplacer() override = default;

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

 private:
  GURL replacement_url_;
};

}  // 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");

  RenderFrameDeletedObserver initial_frame_deleted_observer(
      shell()->web_contents()->GetPrimaryMainFrame());

  // Test assumes the initial RenderFrameHost to be deleted. Disable
  // back-forward cache to ensure that it doesn't get preserved in the cache.
  DisableBackForwardCacheForTesting(shell()->web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

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

  // Wait for the RenderFrameHost which was current before the navigation to
  // foo.com to be deleted. This is necessary, since on a slow system the
  // UnloadACK event can arrive after the DidCommitUrlReplacer instance below
  // is created. The replacer code has checks to ensure that all frames being
  // deleted it has seen being created, which with delayed UnloadACK is
  // violated.
  initial_frame_deleted_observer.WaitUntilDeleted();

  // 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
  // successfully, but when the URL is modified it should result in the
  // termination of the renderer process.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());
  EXPECT_FALSE(NavigateToURL(
      shell(), embedded_test_server()->GetURL("foo.com", "/title2.html")));
  EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait());
}

// 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,
                       DISABLED_DidCommitInvalidURLWithOpaqueOrigin) {
  // Explicitly isolating foo.com helps ensure that this test is applicable on
  // platforms without site-per-process.
  IsolateOrigin("foo.com");

  RenderFrameDeletedObserver initial_frame_deleted_observer(
      shell()->web_contents()->GetPrimaryMainFrame());

  // Test assumes the initial RenderFrameHost to be deleted. Disable
  // back-forward cache to ensure that it doesn't get preserved in the cache.
  DisableBackForwardCacheForTesting(shell()->web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

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

  // Wait for the RenderFrameHost which was current before the navigation to
  // foo.com to be deleted. This is necessary, since on a slow system the
  // UnloadACK event can arrive after the DidCommitUrlReplacer instance below
  // is created. The replacer code has checks to ensure that all frames being
  // deleted it has seen being created, which with delayed UnloadACK is
  // violated.
  initial_frame_deleted_observer.WaitUntilDeleted();

  // 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 the subframe to a data URL, which would usually be committed
  // successfully in the same process as foo.com, but when the URL is modified
  // it should result in the termination of the renderer process.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());

  // Using BeginNavigateIframeToURL is necessary here, since the process
  // termination will result in DidFinishNavigation notification with the
  // navigation not in "committed" state. NavigateIframeToURL waits for the
  // navigation to complete and ignores non-committed navigations, therefore
  // it will wait indefinitely.
  GURL data_url(R"(data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E)");
  EXPECT_TRUE(BeginNavigateIframeToURL(shell()->web_contents(), "test_iframe",
                                       data_url));
  EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait());
}

// Test which verifies that a WebUI process cannot send a commit message with
// URL for a web document.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       WebUIProcessDidCommitWebURL) {
  // Navigate to a WebUI document.
  GURL webui_url(GetWebUIURL(kChromeUIGpuHost));
  EXPECT_TRUE(NavigateToURL(shell(), webui_url));

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

  // Navigate to another URL within the WebUI, which would usually be committed
  // successfully, but when the URL is modified it should result in the
  // termination of the renderer process.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      shell()->web_contents()->GetPrimaryMainFrame()->GetProcess());
  GURL second_webui_url(webui_url.Resolve("/foo"));
  EXPECT_FALSE(NavigateToURL(shell(), second_webui_url));
  EXPECT_EQ(bad_message::RFH_CAN_COMMIT_URL_BLOCKED, kill_waiter.Wait());
}

// Test that verifies that if a RenderFrameHost is incorrectly given WebUI
// bindings the browser process crashes due to CHECK enforcements.
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       AllowBindingsForNonWebUIProcess) {
  // Navigate to a web URL.
  GURL initial_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));

  // Grant WebUI bindings to the frame to simulate a bug in the code that
  // incorrectly does it and verify the browser process crashes.
  EXPECT_NOTREACHED_DEATH(
      shell()->web_contents()->GetPrimaryMainFrame()->AllowBindings(
          BindingsPolicySet({BindingsPolicyValue::kWebUi})));
}

// Tests that a web page cannot bind to a WebUI interface if a WebUI page is the
// currently committed RenderFrameHost in the tab (https://crbug.com/1225929).
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest, BindToWebUIFromWebViaMojo) {
  // Navigate to a non-privileged web page, and simulate a renderer compromise
  // by granting MojoJS.
  GURL web_url(embedded_test_server()->GetURL("a.com", "/title1.html"));
  TestNavigationManager navigation(shell()->web_contents(), web_url);
  shell()->LoadURL(web_url);
  EXPECT_TRUE(navigation.WaitForResponse());
  RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());
  main_frame->GetFrameBindingsControl()->EnableMojoJsBindings(nullptr);
  ASSERT_TRUE(navigation.WaitForNavigationFinished());

  // Open a popup so that the process won't exit on its own when leaving.
  OpenBlankWindow(static_cast<WebContentsImpl*>(shell()->web_contents()));

  // When the page unloads (after the cross-process navigation to an actual
  // WebUI page below), try to bind to a WebUI interface from the web
  // RenderFrameHost. Ensure the unload timer and bfcache are disabled so that
  // the handler has a chance to run.
  // This test uses `pagehide` rather than `unload` since they occur at the
  // same timing but `unload` is being deprecated.
  main_frame->DisableUnloadTimerForTesting();
  DisableBackForwardCacheForTesting(shell()->web_contents(),
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);
  ASSERT_TRUE(ExecJs(main_frame, R"(
        // Intentionally leak pipe as a global so it doesn't get GCed.
        newMessagePipe = Mojo.createMessagePipe();
        onpagehide = function () {
          Mojo.bindInterface('mojom.ProcessInternalsHandler',
                             newMessagePipe.handle0);
        };
      )"));

  // Now navigate to a WebUI page and expect the previous renderer process to be
  // killed when asking to bind to the WebUI interface.
  GURL webui_url(
      GetWebUIURL(kChromeUIProcessInternalsHost).Resolve("#general"));
  RenderProcessHostBadIpcMessageWaiter kill_waiter(main_frame->GetProcess());
  EXPECT_TRUE(NavigateToURL(shell(), webui_url));

  // Verify that the previous renderer was terminated.
  EXPECT_EQ(bad_message::RFH_INVALID_WEB_UI_CONTROLLER, 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) {}

  BeginNavigationTransitionReplacer(const BeginNavigationTransitionReplacer&) =
      delete;
  BeginNavigationTransitionReplacer& operator=(
      const BeginNavigationTransitionReplacer&) = delete;

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      blink::mojom::CommonNavigationParamsPtr* common_params,
      blink::mojom::BeginNavigationParamsPtr* begin_params,
      mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token,
      mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client)
      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;
};

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->GetPrimaryMainFrame()->GetProcess();
    RenderProcessHostBadIpcMessageWaiter 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());
  }
}

class SecurityExploitViaDisabledWebSecurityTest
    : public SecurityExploitBrowserTest {
 public:
  SecurityExploitViaDisabledWebSecurityTest() {
    // To get around BlockedSchemeNavigationThrottle. Other attempts at getting
    // around it don't work, i.e.:
    // -if the request is made in a child frame then the frame is torn down
    // immediately on process killing so the navigation doesn't complete
    // -if it's classified as same document, then a DCHECK in
    // NavigationRequest::CreateRendererInitiated fires
    feature_list_.InitAndEnableFeature(
        features::kAllowContentInitiatedDataUrlNavigations);
  }

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    // Simulate a compromised renderer, otherwise the cross-origin request to
    // file: is blocked.
    command_line->AppendSwitch(switches::kDisableWebSecurity);
    SecurityExploitBrowserTest::SetUpCommandLine(command_line);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Test to verify that an exploited renderer process trying to specify a
// non-empty URL for base_url_for_data_url on navigation is correctly
// terminated.
IN_PROC_BROWSER_TEST_F(SecurityExploitViaDisabledWebSecurityTest,
                       ValidateBaseUrlForDataUrl) {
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  GURL data_url("data:text/html,foo");
  base::FilePath file_path = GetTestFilePath("", "simple_page.html");
  GURL file_url = net::FilePathToFileURL(file_path);

  // Setup a BeginNavigate IPC with non-empty base_url_for_data_url.
  blink::mojom::CommonNavigationParamsPtr common_params =
      blink::mojom::CommonNavigationParams::New(
          data_url, url::Origin::Create(data_url),
          /* initiator_base_url= */ std::nullopt, blink::mojom::Referrer::New(),
          ui::PAGE_TRANSITION_LINK,
          blink::mojom::NavigationType::DIFFERENT_DOCUMENT,
          blink::NavigationDownloadPolicy(),
          false /* should_replace_current_entry */,
          file_url, /* base_url_for_data_url */
          base::TimeTicks::Now() /* navigation_start */, "GET",
          nullptr /* post_data */, network::mojom::SourceLocation::New(),
          false /* started_from_context_menu */, false /* has_user_gesture */,
          false /* text_fragment_token */,
          network::mojom::CSPDisposition::CHECK,
          std::vector<int>() /* initiator_origin_trial_features */,
          std::string() /* href_translate */,
          false /* is_history_navigation_in_new_child_frame */,
          base::TimeTicks() /* input_start */,
          network::mojom::RequestDestination::kDocument);
  blink::mojom::BeginNavigationParamsPtr begin_params =
      blink::mojom::BeginNavigationParams::New(
          std::nullopt /* initiator_frame_token */, std::string() /* headers */,
          net::LOAD_NORMAL, false /* skip_service_worker */,
          blink::mojom::RequestContextType::LOCATION,
          blink::mojom::MixedContentContextType::kBlockable,
          false /* is_form_submission */,
          false /* was_initiated_by_link_click */,
          blink::mojom::ForceHistoryPush::kNo, GURL() /* searchable_form_url */,
          std::string() /* searchable_form_encoding */,
          GURL() /* client_side_redirect_url */,
          std::nullopt /* devtools_initiator_info */,
          nullptr /* trust_token_params */, std::nullopt /* impression */,
          base::TimeTicks() /* renderer_before_unload_start */,
          base::TimeTicks() /* renderer_before_unload_end */,
          blink::mojom::NavigationInitiatorActivationAndAdStatus::
              kDidNotStartWithTransientActivation,
          false /* is_container_initiated */,
          net::StorageAccessApiStatus::kNone, false /* has_rel_opener */);

  // Receiving the invalid IPC message should lead to renderer process
  // termination.
  RenderProcessHostBadIpcMessageWaiter process_kill_waiter(rfh->GetProcess());

  mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client;
  auto navigation_client_receiver =
      navigation_client.InitWithNewEndpointAndPassReceiver();
  rfh->frame_host_receiver_for_testing().impl()->BeginNavigation(
      std::move(common_params), std::move(begin_params), mojo::NullRemote(),
      std::move(navigation_client), mojo::NullRemote(), mojo::NullReceiver());
  EXPECT_EQ(bad_message::RFH_BASE_URL_FOR_DATA_URL_SPECIFIED,
            process_kill_waiter.Wait());

  EXPECT_FALSE(ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(
      rfh->GetProcess()->GetDeprecatedID(), file_path));

  // Reload the page to create another renderer process.
  TestNavigationObserver tab_observer(shell()->web_contents(), 1);
  shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false);
  tab_observer.Wait();

  // Make an XHR request to check if the page has access.
  std::string script = base::StringPrintf(
      "var xhr = new XMLHttpRequest()\n"
      "xhr.open('GET', '%s', false);\n"
      "try { xhr.send(); } catch (e) {}\n"
      "xhr.responseText;",
      file_url.spec().c_str());
  std::string result = EvalJs(shell()->web_contents(), script).ExtractString();
  EXPECT_TRUE(result.empty());
}

// Test to verify that an exploited renderer process trying to specify a
// empty URL for initiator_base_url on navigation is correctly terminated.
IN_PROC_BROWSER_TEST_F(SecurityExploitViaDisabledWebSecurityTest,
                       ValidateInitiatorBaseUrlNotEmpty) {
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  GURL url("about:blank");

  // Setup a BeginNavigate IPC with empty, but not nullopt, initiator_base_url.
  blink::mojom::CommonNavigationParamsPtr common_params =
      blink::mojom::CommonNavigationParams::New(
          url, url::Origin::Create(start_url),
          /* initiator_base_url= */ GURL(), blink::mojom::Referrer::New(),
          ui::PAGE_TRANSITION_LINK,
          blink::mojom::NavigationType::DIFFERENT_DOCUMENT,
          blink::NavigationDownloadPolicy(),
          false /* should_replace_current_entry */,
          GURL(), /* base_url_for_data_url */
          base::TimeTicks::Now() /* navigation_start */, "GET",
          nullptr /* post_data */, network::mojom::SourceLocation::New(),
          false /* started_from_context_menu */, false /* has_user_gesture */,
          false /* text_fragment_token */,
          network::mojom::CSPDisposition::CHECK,
          std::vector<int>() /* initiator_origin_trial_features */,
          std::string() /* href_translate */,
          false /* is_history_navigation_in_new_child_frame */,
          base::TimeTicks() /* input_start */,
          network::mojom::RequestDestination::kDocument);
  blink::mojom::BeginNavigationParamsPtr begin_params =
      blink::mojom::BeginNavigationParams::New(
          std::nullopt /* initiator_frame_token */, std::string() /* headers */,
          net::LOAD_NORMAL, false /* skip_service_worker */,
          blink::mojom::RequestContextType::LOCATION,
          blink::mojom::MixedContentContextType::kBlockable,
          false /* is_form_submission */,
          false /* was_initiated_by_link_click */,
          blink::mojom::ForceHistoryPush::kNo, GURL() /* searchable_form_url */,
          std::string() /* searchable_form_encoding */,
          GURL() /* client_side_redirect_url */,
          std::nullopt /* devtools_initiator_info */,
          nullptr /* trust_token_params */, std::nullopt /* impression */,
          base::TimeTicks() /* renderer_before_unload_start */,
          base::TimeTicks() /* renderer_before_unload_end */,
          blink::mojom::NavigationInitiatorActivationAndAdStatus::
              kDidNotStartWithTransientActivation,
          false /* is_container_initiated */,
          net::StorageAccessApiStatus::kNone, false /* has_rel_opener */);

  // Receiving the invalid IPC message should lead to renderer process
  // termination.
  RenderProcessHostBadIpcMessageWaiter process_kill_waiter(rfh->GetProcess());

  mojo::PendingAssociatedRemote<mojom::NavigationClient> navigation_client;
  auto navigation_client_receiver =
      navigation_client.InitWithNewEndpointAndPassReceiver();
  rfh->frame_host_receiver_for_testing().impl()->BeginNavigation(
      std::move(common_params), std::move(begin_params), mojo::NullRemote(),
      std::move(navigation_client), mojo::NullRemote(), mojo::NullReceiver());
  EXPECT_EQ(bad_message::RFH_INITIATOR_BASE_URL_IS_EMPTY,
            process_kill_waiter.Wait());
}

// Tests what happens when a web renderer asks to begin navigating to a file
// url.
IN_PROC_BROWSER_TEST_F(SecurityExploitViaDisabledWebSecurityTest,
                       WebToFileNavigation) {
  // Navigate to a web page.
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Have the webpage attempt to open a window with a file URL.
  //
  // Note that such attempt would normally be blocked in the renderer ("Not
  // allowed to load local resource: file:///..."), but the test here simulates
  // a compromised renderer by using --disable-web-security cmdline flag.
  GURL file_url = GetTestUrl("", "simple_page.html");
  WebContentsAddedObserver new_window_observer;
  TestNavigationObserver nav_observer(nullptr);
  nav_observer.StartWatchingNewWebContents();
  ASSERT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("window.open($1, '_blank')", file_url)));
  WebContents* new_window = new_window_observer.GetWebContents();
  nav_observer.WaitForNavigationFinished();

  // Verify that the navigation got blocked.
  EXPECT_TRUE(nav_observer.last_navigation_succeeded());
  EXPECT_EQ(GURL(kBlockedURL), nav_observer.last_navigation_url());
  EXPECT_EQ(GURL(kBlockedURL),
            new_window->GetPrimaryMainFrame()->GetLastCommittedURL());
  EXPECT_EQ(
      shell()->web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
      new_window->GetPrimaryMainFrame()->GetLastCommittedOrigin());
  EXPECT_EQ(shell()->web_contents()->GetPrimaryMainFrame()->GetProcess(),
            new_window->GetPrimaryMainFrame()->GetProcess());

  // Even though the navigation is blocked, we expect the opener relationship to
  // be established between the 2 windows.
  EXPECT_EQ(true, ExecJs(new_window, "!!window.opener"));
}

// Tests what happens when a web renderer asks to begin navigating to a
// view-source url.
IN_PROC_BROWSER_TEST_F(SecurityExploitViaDisabledWebSecurityTest,
                       WebToViewSourceNavigation) {
  // Navigate to a web page.
  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  // Have the webpage attempt to open a window with a view-source URL.
  //
  // Note that such attempt would normally be blocked in the renderer ("Not
  // allowed to load local resource: view-source:///..."), but the test here
  // simulates a compromised renderer by using --disable-web-security flag.
  base::FilePath file_path = GetTestFilePath("", "simple_page.html");
  GURL view_source_url =
      GURL(std::string(kViewSourceScheme) + ":" + start_url.spec());
  WebContentsAddedObserver new_window_observer;
  TestNavigationObserver nav_observer(nullptr);
  nav_observer.StartWatchingNewWebContents();
  ASSERT_TRUE(ExecJs(shell()->web_contents(),
                     JsReplace("window.open($1, '_blank')", view_source_url)));
  WebContents* new_window = new_window_observer.GetWebContents();
  nav_observer.WaitForNavigationFinished();

  // Verify that the navigation got blocked.
  EXPECT_TRUE(nav_observer.last_navigation_succeeded());
  EXPECT_EQ(GURL(kBlockedURL), nav_observer.last_navigation_url());
  EXPECT_EQ(GURL(kBlockedURL),
            new_window->GetPrimaryMainFrame()->GetLastCommittedURL());
  EXPECT_EQ(
      shell()->web_contents()->GetPrimaryMainFrame()->GetLastCommittedOrigin(),
      new_window->GetPrimaryMainFrame()->GetLastCommittedOrigin());
  EXPECT_EQ(shell()->web_contents()->GetPrimaryMainFrame()->GetProcess(),
            new_window->GetPrimaryMainFrame()->GetProcess());

  // Even though the navigation is blocked, we expect the opener relationship to
  // be established between the 2 windows.
  EXPECT_EQ(true, ExecJs(new_window, "!!window.opener"));
}

class BeginNavigationTrustTokenParamsReplacer : public FrameHostInterceptor {
 public:
  BeginNavigationTrustTokenParamsReplacer(
      WebContents* web_contents,
      network::mojom::TrustTokenParamsPtr params_to_inject)
      : FrameHostInterceptor(web_contents),
        params_to_inject_(std::move(params_to_inject)) {}

  BeginNavigationTrustTokenParamsReplacer(
      const BeginNavigationTrustTokenParamsReplacer&) = delete;
  BeginNavigationTrustTokenParamsReplacer& operator=(
      const BeginNavigationTrustTokenParamsReplacer&) = delete;

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      blink::mojom::CommonNavigationParamsPtr* common_params,
      blink::mojom::BeginNavigationParamsPtr* begin_params,
      mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token,
      mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client)
      override {
    if (is_activated_) {
      (*begin_params)->trust_token_params = params_to_inject_.Clone();
      is_activated_ = false;
    }

    return true;
  }

  void Activate() { is_activated_ = true; }

 private:
  network::mojom::TrustTokenParamsPtr params_to_inject_;
  bool is_activated_ = false;
};

class SecurityExploitBrowserTestWithTrustTokensEnabled
    : public SecurityExploitBrowserTest {
 public:
  SecurityExploitBrowserTestWithTrustTokensEnabled() = default;
};

// Test that the browser correctly reports a bad message when a child frame
// attempts to navigate with a Private State Tokens redemption operation
// associated with the navigation, but its parent lacks the
// private-state-token-redemption Permissions Policy feature.
IN_PROC_BROWSER_TEST_F(
    SecurityExploitBrowserTestWithTrustTokensEnabled,
    BrowserForbidsTrustTokenRedemptionWithoutPermissionsPolicy) {
  WebContents* web_contents = shell()->web_contents();

  // Prepare to intercept BeginNavigation mojo IPC. This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  auto params = network::mojom::TrustTokenParams::New();
  params->operation = network::mojom::TrustTokenOperationType::kRedemption;
  BeginNavigationTrustTokenParamsReplacer replacer(web_contents,
                                                   std::move(params));

  GURL start_url(embedded_test_server()->GetURL(
      "/page-with-trust-token-permissions-policy-disabled.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHost* parent = web_contents->GetPrimaryMainFrame();
  ASSERT_FALSE(parent->IsFeatureEnabled(
      network::mojom::PermissionsPolicyFeature::kTrustTokenRedemption));

  replacer.Activate();

  RenderFrameHost* child = static_cast<WebContentsImpl*>(web_contents)
                               ->GetPrimaryFrameTree()
                               .root()
                               ->child_at(0)
                               ->current_frame_host();
  ExecuteScriptAsync(child, JsReplace("location = $1", "/title2.html"));

  RenderProcessHostBadMojoMessageWaiter kill_waiter(child->GetProcess());
  EXPECT_THAT(kill_waiter.Wait(),
              Optional(HasSubstr("Permissions Policy feature is absent")));
}

// Test that the browser correctly reports a bad message when a child frame
// attempts to navigate with a Private State Tokens signing operation associated
// with the navigation, but its parent lacks the private-state-token-redemption
// (sic) Permissions Policy feature.
IN_PROC_BROWSER_TEST_F(
    SecurityExploitBrowserTestWithTrustTokensEnabled,
    BrowserForbidsTrustTokenSigningWithoutPermissionsPolicy) {
  WebContents* web_contents = shell()->web_contents();

  // Prepare to intercept BeginNavigation mojo IPC. This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  auto params = network::mojom::TrustTokenParams::New();
  params->operation = network::mojom::TrustTokenOperationType::kSigning;
  BeginNavigationTrustTokenParamsReplacer replacer(web_contents,
                                                   std::move(params));

  GURL start_url(embedded_test_server()->GetURL(
      "/page-with-trust-token-permissions-policy-disabled.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHost* parent = web_contents->GetPrimaryMainFrame();
  ASSERT_FALSE(parent->IsFeatureEnabled(
      network::mojom::PermissionsPolicyFeature::kTrustTokenRedemption));

  replacer.Activate();

  RenderFrameHost* child = static_cast<WebContentsImpl*>(web_contents)
                               ->GetPrimaryFrameTree()
                               .root()
                               ->child_at(0)
                               ->current_frame_host();
  ExecuteScriptAsync(child, JsReplace("location = $1", "/title2.html"));

  RenderProcessHostBadMojoMessageWaiter kill_waiter(child->GetProcess());
  EXPECT_THAT(kill_waiter.Wait(),
              Optional(HasSubstr("Permissions Policy feature is absent")));
}

// Test that the browser correctly reports a bad message when a child frame
// attempts to navigate with a Private State Tokens issue operation
// associated with the navigation, but its parent lacks the
// private-state-token-issuance Permissions Policy feature.
IN_PROC_BROWSER_TEST_F(
    SecurityExploitBrowserTestWithTrustTokensEnabled,
    BrowserForbidsTrustTokenIssuanceWithoutPermissionsPolicy) {
  WebContents* web_contents = shell()->web_contents();

  // Prepare to intercept BeginNavigation mojo IPC. This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  auto params = network::mojom::TrustTokenParams::New();
  params->operation = network::mojom::TrustTokenOperationType::kIssuance;
  BeginNavigationTrustTokenParamsReplacer replacer(web_contents,
                                                   std::move(params));

  GURL start_url(embedded_test_server()->GetURL(
      "/page-with-trust-token-permissions-policy-disabled.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHost* parent = web_contents->GetPrimaryMainFrame();
  ASSERT_FALSE(parent->IsFeatureEnabled(
      network::mojom::PermissionsPolicyFeature::kPrivateStateTokenIssuance));

  replacer.Activate();

  RenderFrameHost* child = static_cast<WebContentsImpl*>(web_contents)
                               ->GetPrimaryFrameTree()
                               .root()
                               ->child_at(0)
                               ->current_frame_host();
  ExecuteScriptAsync(child, JsReplace("location = $1", "/title2.html"));

  RenderProcessHostBadMojoMessageWaiter kill_waiter(child->GetProcess());
  EXPECT_THAT(kill_waiter.Wait(),
              Optional(HasSubstr("Permissions Policy feature is absent")));
}

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestWithTrustTokensEnabled,
                       BrowserForbidsTrustTokenParamsOnMainFrameNav) {
  WebContents* web_contents = shell()->web_contents();

  // Prepare to intercept BeginNavigation mojo IPC. This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  BeginNavigationTrustTokenParamsReplacer replacer(
      web_contents, network::mojom::TrustTokenParams::New());

  GURL start_url(embedded_test_server()->GetURL("/title1.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  replacer.Activate();

  RenderFrameHost* compromised_renderer = web_contents->GetPrimaryMainFrame();
  ExecuteScriptAsync(compromised_renderer,
                     JsReplace("location = $1", "/title2.html"));

  RenderProcessHostBadMojoMessageWaiter kill_waiter(
      compromised_renderer->GetProcess());
  EXPECT_THAT(
      kill_waiter.Wait(),
      Optional(HasSubstr("Private State Token params in main frame nav")));
}

class FencedFrameSecurityExploitBrowserTestWithTrustTokensEnabled
    : public SecurityExploitBrowserTestWithTrustTokensEnabled {
 protected:
  FencedFrameSecurityExploitBrowserTestWithTrustTokensEnabled() = default;

  WebContentsImpl* web_contents() {
    return static_cast<WebContentsImpl*>(shell()->web_contents());
  }

  RenderFrameHostImpl* primary_main_frame_host() {
    return web_contents()->GetPrimaryMainFrame();
  }

  test::FencedFrameTestHelper& fenced_frame_test_helper() {
    return fenced_frame_test_helper_;
  }

 private:
  test::FencedFrameTestHelper fenced_frame_test_helper_;
};

class FencedFrameBeginNavigationTrustTokenParamsReplacer
    : public BeginNavigationTrustTokenParamsReplacer {
 public:
  FencedFrameBeginNavigationTrustTokenParamsReplacer(
      WebContents* web_contents,
      network::mojom::TrustTokenParamsPtr params_to_inject)
      : BeginNavigationTrustTokenParamsReplacer(web_contents,
                                                std::move(params_to_inject)) {}

  FencedFrameBeginNavigationTrustTokenParamsReplacer(
      const FencedFrameBeginNavigationTrustTokenParamsReplacer&) = delete;
  FencedFrameBeginNavigationTrustTokenParamsReplacer& operator=(
      const FencedFrameBeginNavigationTrustTokenParamsReplacer&) = delete;

  bool WillDispatchBeginNavigation(
      RenderFrameHost* render_frame_host,
      blink::mojom::CommonNavigationParamsPtr* common_params,
      blink::mojom::BeginNavigationParamsPtr* begin_params,
      mojo::PendingRemote<blink::mojom::BlobURLToken>* blob_url_token,
      mojo::PendingAssociatedRemote<mojom::NavigationClient>* navigation_client)
      override {
    if (render_frame_host->IsFencedFrameRoot()) {
      BeginNavigationTrustTokenParamsReplacer::WillDispatchBeginNavigation(
          render_frame_host, common_params, begin_params, blob_url_token,
          navigation_client);
    }
    return true;
  }
};

IN_PROC_BROWSER_TEST_F(
    FencedFrameSecurityExploitBrowserTestWithTrustTokensEnabled,
    BrowserForbidsTrustTokenParamsOnFencedFrameNav) {
  WebContents* web_contents = shell()->web_contents();

  // Prepare to intercept BeginNavigation mojo IPC. This has to be done before
  // the test creates the RenderFrameHostImpl that is the target of the IPC.
  FencedFrameBeginNavigationTrustTokenParamsReplacer replacer(
      web_contents, network::mojom::TrustTokenParams::New());
  GURL start_url(embedded_test_server()->GetURL("/empty.html"));
  EXPECT_TRUE(NavigateToURL(shell(), start_url));

  RenderFrameHostImplWrapper primary_rfh(primary_main_frame_host());
  RenderFrameHostImplWrapper inner_fenced_frame_rfh(
      fenced_frame_test_helper().CreateFencedFrame(
          primary_rfh.get(),
          embedded_test_server()->GetURL("/fenced_frames/empty.html")));

  RenderFrameHost* compromised_renderer = inner_fenced_frame_rfh.get();
  RenderProcessHostBadMojoMessageWaiter kill_waiter(
      compromised_renderer->GetProcess());
  replacer.Activate();

  std::ignore = ExecJs(
      compromised_renderer,
      JsReplace("location.href=$1",
                embedded_test_server()->GetURL("/fenced_frames/title1.html")));

  std::optional<std::string> result = kill_waiter.Wait();
  EXPECT_THAT(result,
              Optional(HasSubstr("Private State Token params in fenced frame "
                                 "nav")));
}

class SecurityExploitTestFencedFramesDisabled
    : public SecurityExploitBrowserTest {
 public:
  SecurityExploitTestFencedFramesDisabled() {
    feature_list_.InitAndDisableFeature(blink::features::kFencedFrames);
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

// Ensure that we kill the renderer process if we try to create a
// fenced-frame when the blink::features::kFencedFrames feature is not enabled.
IN_PROC_BROWSER_TEST_F(SecurityExploitTestFencedFramesDisabled,
                       CreateFencedFrameWhenFeatureDisabled) {
  GURL foo("http://foo.com/simple_page.html");
  EXPECT_TRUE(NavigateToURL(shell(), foo));
  EXPECT_EQ(u"OK", shell()->web_contents()->GetTitle());
  EXPECT_FALSE(blink::features::IsFencedFramesEnabled());

  RenderFrameHostImpl* compromised_rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  mojo::PendingAssociatedRemote<blink::mojom::FencedFrameOwnerHost> remote;
  mojo::PendingAssociatedReceiver<blink::mojom::FencedFrameOwnerHost> receiver;
  receiver = remote.InitWithNewEndpointAndPassReceiver();

  auto remote_frame_interfaces =
      blink::mojom::RemoteFrameInterfacesFromRenderer::New();
  remote_frame_interfaces->frame_host_receiver =
      mojo::AssociatedRemote<blink::mojom::RemoteFrameHost>()
          .BindNewEndpointAndPassDedicatedReceiver();
  mojo::AssociatedRemote<blink::mojom::RemoteFrame> frame;
  std::ignore = frame.BindNewEndpointAndPassDedicatedReceiver();
  remote_frame_interfaces->frame = frame.Unbind();

  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      compromised_rfh->GetProcess());
  static_cast<blink::mojom::LocalFrameHost*>(compromised_rfh)
      ->CreateFencedFrame(
          std::move(receiver), std::move(remote_frame_interfaces),
          blink::RemoteFrameToken(), base::UnguessableToken::Create());
  EXPECT_EQ(bad_message::RFH_FENCED_FRAME_MOJO_WHEN_DISABLED,
            kill_waiter.Wait());
}

// Ensure that we kill the renderer process if we try to do a top-level
// navigation using the special _unfencedTop IPC path when we are not inside
// a fenced frame. (Test from an iframe instead.)
IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTest,
                       UnfencedTopFromOutsideFencedFrame) {
  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())
                            ->GetPrimaryFrameTree()
                            .root();
  RenderFrameHostImpl* compromised_rfh =
      root->child_at(0)->current_frame_host();

  RenderProcessHostBadIpcMessageWaiter kill_waiter(
      compromised_rfh->GetProcess());

  GURL url("http://foo.com/simple_page.html");
  auto params = CreateOpenURLParams(url);
  params->is_unfenced_top_navigation = true;
  static_cast<mojom::FrameHost*>(compromised_rfh)->OpenURL(std::move(params));

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

class SecurityExploitBrowserTestFencedFrames
    : public SecurityExploitBrowserTest {
 public:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    https_server()->StartAcceptingConnections();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    https_server()->AddDefaultHandlers(GetTestDataFilePath());
    https_server()->ServeFilesFromSourceDirectory(GetTestDataFilePath());
    https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
    SetupCrossSiteRedirector(https_server());

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

  test::FencedFrameTestHelper& fenced_frame_test_helper() {
    return fenced_frame_test_helper_;
  }

  net::EmbeddedTestServer* https_server() { return &https_server_; }

 private:
  test::FencedFrameTestHelper fenced_frame_test_helper_{};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
};

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestFencedFrames,
                       NavigateFencedFrameToInvalidURL) {
  GURL main_frame_url(https_server()->GetURL("a.test", "/simple_page.html"));
  std::vector<GURL> invalid_urls = {
      GURL("http://example.com"),
      GURL("http://example.com?<\n=block"),
      GURL("about:srcdoc"),
      GURL("data:text/html,<p>foo"),
      GURL("blob:https://example.com/a9400bf5-aaa8-4166-86e4-492c50f4ca2b"),
      GURL("file://folder"),
      GURL("javascript:console.log('foo');"),
      GetWebUIURL(kChromeUIHistogramHost),
      GURL(blink::kChromeUIHangURL)};

  for (const GURL& invalid_url : invalid_urls) {
    EXPECT_FALSE(blink::IsValidFencedFrameURL(invalid_url));
    EXPECT_TRUE(blink::features::IsFencedFramesEnabled());
    EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
    EXPECT_EQ(u"OK", shell()->web_contents()->GetTitle());

    RenderFrameHostImpl* compromised_rfh = static_cast<RenderFrameHostImpl*>(
        shell()->web_contents()->GetPrimaryMainFrame());

    mojo::AssociatedRemote<blink::mojom::FencedFrameOwnerHost> remote;
    mojo::PendingAssociatedReceiver<blink::mojom::FencedFrameOwnerHost>
        pending_receiver = remote.BindNewEndpointAndPassReceiver();

    auto remote_frame_interfaces =
        blink::mojom::RemoteFrameInterfacesFromRenderer::New();
    remote_frame_interfaces->frame_host_receiver =
        mojo::AssociatedRemote<blink::mojom::RemoteFrameHost>()
            .BindNewEndpointAndPassDedicatedReceiver();
    mojo::AssociatedRemote<blink::mojom::RemoteFrame> frame;
    std::ignore = frame.BindNewEndpointAndPassDedicatedReceiver();
    remote_frame_interfaces->frame = frame.Unbind();

    RenderProcessHostBadIpcMessageWaiter kill_waiter(
        compromised_rfh->GetProcess());
    static_cast<blink::mojom::LocalFrameHost*>(compromised_rfh)
        ->CreateFencedFrame(
            std::move(pending_receiver), std::move(remote_frame_interfaces),
            blink::RemoteFrameToken(), base::UnguessableToken::Create());
    EXPECT_EQ(compromised_rfh->GetFencedFrames().size(), 1u);

    FencedFrame* fenced_frame = compromised_rfh->GetFencedFrames()[0];
    static_cast<blink::mojom::FencedFrameOwnerHost*>(fenced_frame)
        ->Navigate(invalid_url, base::TimeTicks(),
                   /*embedder_shared_storage_context=*/std::nullopt);
    EXPECT_EQ(bad_message::FF_NAVIGATION_INVALID_URL, kill_waiter.Wait());
  }
}

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestFencedFrames,
                       ChangeFencedFrameSandboxFlags) {
  GURL main_frame_url(https_server()->GetURL("a.test", "/simple_page.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
  RenderFrameHostImpl* root_rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  const GURL fenced_frame_url =
      https_server()->GetURL("a.test", "/fenced_frames/sandbox_flags.html");
  constexpr char kAddFencedFrameScript[] = R"({
      const fenced_frame = document.createElement('fencedframe');
      fenced_frame.config = new FencedFrameConfig($1);
      document.body.appendChild(fenced_frame);
    })";
  EXPECT_TRUE(
      ExecJs(root_rfh, JsReplace(kAddFencedFrameScript, fenced_frame_url)));

  RenderFrameHostImpl* fenced_rfh = nullptr;
  RenderFrameHostImpl* parent_rfh = nullptr;

  std::vector<FencedFrame*> fenced_frames = root_rfh->GetFencedFrames();
  EXPECT_EQ(fenced_frames.size(), 1u);
  FencedFrame* new_fenced_frame = fenced_frames.back();
  fenced_rfh = new_fenced_frame->GetInnerRoot();
  parent_rfh = fenced_rfh;

  RenderProcessHostBadIpcMessageWaiter kill_waiter(fenced_rfh->GetProcess());

  blink::FramePolicy first_policy =
      fenced_rfh->frame_tree_node()->pending_frame_policy();

  first_policy.sandbox_flags = blink::kFencedFrameMandatoryUnsandboxedFlags;
  static_cast<blink::mojom::LocalFrameHost*>(parent_rfh)
      ->DidChangeFramePolicy(std::move(fenced_rfh->GetFrameToken()),
                             std::move(first_policy));

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

IN_PROC_BROWSER_TEST_F(SecurityExploitBrowserTestFencedFrames,
                       PullFocusAcrossFencedBoundary) {
  base::HistogramTester histogram_tester;
  GURL main_frame_url(https_server()->GetURL("a.test", "/simple_page.html"));

  EXPECT_TRUE(NavigateToURL(shell(), main_frame_url));
  RenderFrameHostImpl* root_rfh = static_cast<RenderFrameHostImpl*>(
      shell()->web_contents()->GetPrimaryMainFrame());

  const GURL fenced_frame_url =
      https_server()->GetURL("a.test", "/fenced_frames/button.html");
  constexpr char kAddFencedFrameScript[] = R"({
      const fenced_frame = document.createElement('fencedframe');
      fenced_frame.config = new FencedFrameConfig($1);
      document.body.appendChild(fenced_frame);
    })";
  EXPECT_TRUE(
      ExecJs(root_rfh, JsReplace(kAddFencedFrameScript, fenced_frame_url)));

  RenderFrameHostImpl* fenced_rfh = nullptr;

  std::vector<FencedFrame*> fenced_frames = root_rfh->GetFencedFrames();
  EXPECT_EQ(fenced_frames.size(), 1u);
  FencedFrame* new_fenced_frame = fenced_frames.back();
  fenced_rfh = new_fenced_frame->GetInnerRoot();

  root_rfh->DidFocusFrame();
  root_rfh->GetRenderWidgetHost()->ResetLostFocus();

  // The fenced frame should not be allowed to focus because it won't have
  // user activation, and the RenderWidgetHost won't have recently lost focus.
  RenderProcessHostBadIpcMessageWaiter kill_waiter(fenced_rfh->GetProcess());
  fenced_rfh->DidFocusFrame();
  EXPECT_EQ(bad_message::RFH_FOCUS_ACROSS_FENCED_BOUNDARY, kill_waiter.Wait());
}
}  // namespace content
