// 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/features.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() {
    feature_list_.InitAndEnableFeature(network::features::kPrivateStateTokens);
  }

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

// 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(
      blink::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(
      blink::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(
      blink::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
