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

#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/blob_handle.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_isolation_policy.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "extensions/common/extension_urls.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "storage/browser/blob/blob_registry_impl.h"
#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom-test-utils.h"
#include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h"

// The goal of these tests is 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.
// This is similar to the security_exploit_browsertest.cc tests, but also
// includes chrome/ layer concepts such as extensions.
class ChromeSecurityExploitBrowserTest
    : public extensions::ExtensionBrowserTest {
 public:
  ChromeSecurityExploitBrowserTest() {}
  ~ChromeSecurityExploitBrowserTest() override {}

  void SetUpOnMainThread() override {
    extensions::ExtensionBrowserTest::SetUpOnMainThread();

    ASSERT_TRUE(embedded_test_server()->Start());
    host_resolver()->AddRule("*", "127.0.0.1");

    extension_ = LoadExtension(test_data_dir_.AppendASCII("simple_with_icon"));
  }

  const extensions::Extension* extension() { return extension_; }

  std::unique_ptr<content::BlobHandle> CreateMemoryBackedBlob(
      const std::string& contents,
      const std::string& content_type) {
    std::unique_ptr<content::BlobHandle> result;
    base::RunLoop loop;
    content::BrowserContext::CreateMemoryBackedBlob(
        profile(), base::as_bytes(base::make_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;
  }

 private:
  const extensions::Extension* extension_;

  DISALLOW_COPY_AND_ASSIGN(ChromeSecurityExploitBrowserTest);
};

// Subclass of ChromeSecurityExploitBrowserTest that uses --disable-web-security
// to simulate an exploited renderer.  Note that this also disables some browser
// process checks, so it's not ideal for all exploit tests.
class ChromeWebSecurityDisabledBrowserTest
    : public ChromeSecurityExploitBrowserTest {
 public:
  ChromeWebSecurityDisabledBrowserTest() {}
  ~ChromeWebSecurityDisabledBrowserTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ChromeSecurityExploitBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kDisableWebSecurity);
  }

  DISALLOW_COPY_AND_ASSIGN(ChromeWebSecurityDisabledBrowserTest);
};

// TODO(nasko): This test as written is incompatible with Site Isolation
// restrictions, which disallow the cross-origin pushState call.
// Find a different way to implement issuing the illegal request or just
// delete the test if we have coverage elsewhere. See https://crbug.com/929161.
IN_PROC_BROWSER_TEST_F(ChromeWebSecurityDisabledBrowserTest,
                       DISABLED_ChromeExtensionResources) {
  // Load a page that requests a chrome-extension:// image through XHR. We
  // expect this load to fail, as it is an illegal request.
  GURL foo = embedded_test_server()->GetURL("foo.com",
                                            "/chrome_extension_resource.html");

  content::DOMMessageQueue msg_queue;

  ui_test_utils::NavigateToURL(browser(), foo);

  std::string status;
  std::string expected_status("0");
  EXPECT_TRUE(msg_queue.WaitForMessage(&status));
  EXPECT_STREQ(status.c_str(), expected_status.c_str());
}

// Tests that a normal web process cannot send a commit for a Chrome Web Store
// URL.  See https://crbug.com/172119.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CommitWebStoreURLInWebProcess) {
  GURL foo = embedded_test_server()->GetURL("foo.com", "/title1.html");

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* rfh = web_contents->GetMainFrame();

  // This IPC should result in a kill because the Chrome Web Store is not
  // allowed to commit in |rfh->GetProcess()|.
  base::HistogramTester histograms;
  content::RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Modify an IPC for a commit of a blank URL, which would otherwise be allowed
  // to commit in any process.
  GURL blank_url = GURL(url::kAboutBlankURL);
  GURL webstore_url = extension_urls::GetWebstoreLaunchURL();
  content::PwnCommitIPC(web_contents, blank_url, webstore_url,
                        url::Origin::Create(GURL(webstore_url)));
  web_contents->GetController().LoadURL(
      blank_url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());

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

// Tests that a non-extension process cannot send a commit of a blank URL with
// an extension origin.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CommitExtensionOriginInWebProcess) {
  GURL foo = embedded_test_server()->GetURL("foo.com", "/title1.html");

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* rfh = web_contents->GetMainFrame();

  // This IPC should result in a kill because |ext_origin| is not allowed to
  // commit in |rfh->GetProcess()|.
  base::HistogramTester histograms;
  content::RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Modify an IPC for a commit of a blank URL, which would otherwise be allowed
  // to commit in any process.
  GURL blank_url = GURL(url::kAboutBlankURL);
  std::string ext_origin = "chrome-extension://" + extension()->id();
  content::PwnCommitIPC(web_contents, blank_url, blank_url,
                        url::Origin::Create(GURL(ext_origin)));
  web_contents->GetController().LoadURL(
      blank_url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());

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

// Tests that a non-extension process cannot send a commit of an extension URL.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CommitExtensionURLInWebProcess) {
  GURL foo = embedded_test_server()->GetURL("foo.com", "/title1.html");

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* rfh = web_contents->GetMainFrame();

  // This IPC should result in a kill because extension URLs are not allowed to
  // commit in |rfh->GetProcess()|.
  base::HistogramTester histograms;
  content::RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Modify an IPC for a commit of a blank URL, which would otherwise be allowed
  // to commit in any process.
  GURL blank_url = GURL(url::kAboutBlankURL);
  std::string ext_origin = "chrome-extension://" + extension()->id();
  content::PwnCommitIPC(web_contents, blank_url, GURL(ext_origin),
                        url::Origin::Create(GURL(ext_origin)));
  web_contents->GetController().LoadURL(
      blank_url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());

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

// Tests that a non-extension process cannot send a commit of an extension
// filesystem URL.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CommitExtensionFilesystemURLInWebProcess) {
  GURL foo = embedded_test_server()->GetURL("foo.com", "/title1.html");

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::RenderFrameHost* rfh = web_contents->GetMainFrame();

  // This IPC should result in a kill because extension filesystem URLs are not
  // allowed to commit in |rfh->GetProcess()|.
  base::HistogramTester histograms;
  content::RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

  // Modify an IPC for a commit of a blank URL, which would otherwise be allowed
  // to commit in any process.
  GURL blank_url = GURL(url::kAboutBlankURL);
  std::string ext_origin = "chrome-extension://" + extension()->id();
  content::PwnCommitIPC(web_contents, blank_url,
                        GURL("filesystem:" + ext_origin + "/foo"),
                        url::Origin::Create(GURL(ext_origin)));
  web_contents->GetController().LoadURL(
      blank_url, content::Referrer(), ui::PAGE_TRANSITION_LINK, std::string());

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

// chrome://xyz should not be able to create a "filesystem:chrome://abc"
// resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CreateFilesystemURLInOtherChromeUIOrigin) {
  ui_test_utils::NavigateToURL(browser(), GURL("chrome://version"));

  content::RenderFrameHost* rfh =
      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

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

  std::string payload = "<p>Hello world!</p>";
  std::string payload_type = "text/html";

  // Target an extension.
  std::string target_origin = "chrome://downloads";

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

  // Note: a well-behaved renderer would always send the following message here,
  // 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.
  //
  // IPC::IpcSecurityTestUtil::PwnMessageReceived(
  //     rfh->GetProcess()->GetChannel(),
  //     FileSystemHostMsg_OpenFileSystem(22, GURL(target_origin),
  //                                      storage::kFileSystemTypeTemporary));

  GURL target_url =
      GURL("filesystem:" + target_origin + "/temporary/exploit.html");

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

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

  // Now navigate to |target_url| in a new tab. It should not contain |payload|.
  AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED);
  EXPECT_FALSE(content::WaitForLoadStop(
      browser()->tab_strip_model()->GetWebContentsAt(0)));
  rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

  // If the attack is unsuccessful, the navigation ends up in an error
  // page.
  if (content::SiteIsolationPolicy::IsErrorPageIsolationEnabled(
          !rfh->GetParent())) {
    EXPECT_EQ(GURL(content::kUnreachableWebDataURL),
              rfh->GetSiteInstance()->GetSiteURL());
  } else {
    EXPECT_EQ(GURL(target_origin), rfh->GetSiteInstance()->GetSiteURL());
  }
  std::string body;
  std::string script = R"(
    var textContent = document.body.innerText.replace(/\n+/g, '\n');
    window.domAutomationController.send(textContent);
  )";

  EXPECT_TRUE(content::ExecuteScriptAndExtractString(rfh, script, &body));
  EXPECT_EQ(
      "Your file was not found\n"
      "It may have been moved or deleted.\n"
      "ERR_FILE_NOT_FOUND",
      body);
}

// Extension isolation prevents a normal renderer process from being able to
// create a "filesystem:chrome-extension://sdgkjaghsdg/temporary/" resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CreateFilesystemURLInExtensionOrigin) {
  GURL page_url =
      embedded_test_server()->GetURL("a.root-servers.net", "/title1.html");
  ui_test_utils::NavigateToURL(browser(), page_url);

  content::RenderFrameHost* rfh =
      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

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

  // JS code that the attacker would like to run in an extension process.
  std::string payload = "<html><body>pwned.</body></html>";
  std::string payload_type = "text/html";

  // Target an extension.
  std::string target_origin = "chrome-extension://" + extension()->id();

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

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

  GURL target_url =
      GURL("filesystem:" + target_origin + "/temporary/exploit.html");

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

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

  // Now navigate to |target_url| in a new tab. It should not contain |payload|.
  AddTabAtIndex(0, target_url, ui::PAGE_TRANSITION_TYPED);
  EXPECT_FALSE(content::WaitForLoadStop(
      browser()->tab_strip_model()->GetWebContentsAt(0)));
  rfh = browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

  // If the attack is unsuccessful, the navigation ends up in an error
  // page.
  if (content::SiteIsolationPolicy::IsErrorPageIsolationEnabled(
          !rfh->GetParent())) {
    EXPECT_EQ(GURL(content::kUnreachableWebDataURL),
              rfh->GetSiteInstance()->GetSiteURL());
  } else {
    EXPECT_EQ(GURL(target_origin), rfh->GetSiteInstance()->GetSiteURL());
  }
  std::string body;
  std::string script = R"(
    var textContent = document.body.innerText.replace(/\n+/g, '\n');
    window.domAutomationController.send(textContent);
  )";

  EXPECT_TRUE(content::ExecuteScriptAndExtractString(rfh, script, &body));
  EXPECT_EQ(
      "Your file was not found\n"
      "It may have been moved or deleted.\n"
      "ERR_FILE_NOT_FOUND",
      body);
}

namespace {

class BlobURLStoreInterceptor
    : public blink::mojom::BlobURLStoreInterceptorForTesting {
 public:
  static void Intercept(
      GURL target_url,
      mojo::SelfOwnedAssociatedReceiverRef<blink::mojom::BlobURLStore>
          receiver) {
    auto interceptor =
        base::WrapUnique(new BlobURLStoreInterceptor(target_url));
    auto* raw_interceptor = interceptor.get();
    auto impl = receiver->SwapImplForTesting(std::move(interceptor));
    raw_interceptor->url_store_ = std::move(impl);
  }

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

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

 private:
  explicit BlobURLStoreInterceptor(GURL target_url) : target_url_(target_url) {}

  std::unique_ptr<blink::mojom::BlobURLStore> url_store_;
  GURL target_url_;
};

}  // namespace

class ChromeSecurityExploitBrowserTestMojoBlobURLs
    : public ChromeSecurityExploitBrowserTest {
 public:
  ChromeSecurityExploitBrowserTestMojoBlobURLs() = default;

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

// Extension isolation prevents a normal renderer process from being able to
// create a "blob:chrome-extension://" resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTestMojoBlobURLs,
                       CreateBlobInExtensionOrigin) {
  // Target an extension.
  std::string target_origin = "chrome-extension://" + extension()->id();
  std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";
  auto intercept_hook =
      base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
                          GURL("blob:" + target_origin + "/" + blob_path));
  storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(&intercept_hook);

  ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("a.root-servers.net", "/title1.html"));

  content::RenderFrameHost* rfh =
      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

  content::RenderProcessHostBadMojoMessageWaiter crash_observer(
      rfh->GetProcess());

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

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

// chrome://xyz should not be able to create a "blob:chrome://abc" resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTestMojoBlobURLs,
                       CreateBlobInOtherChromeUIOrigin) {
  ui_test_utils::NavigateToURL(browser(), GURL("chrome://version"));

  // All these are attacker controlled values.
  std::string blob_type = "text/html";
  std::string blob_contents = "<p>Hello world!</p>";
  std::string blob_path = "f7dfbeb5-8e41-4c4a-8486-a52fed33c4c0";

  // Target an extension.
  std::string target_origin = "chrome://downloads";

  auto intercept_hook =
      base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
                          GURL("blob:" + target_origin + "/" + blob_path));
  storage::BlobRegistryImpl::SetURLStoreCreationHookForTesting(&intercept_hook);

  content::RenderFrameHost* rfh =
      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame();

  content::RenderProcessHostBadMojoMessageWaiter crash_observer(
      rfh->GetProcess());

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

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