// 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 "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 couldn’t be accessed\n"
      "It may have been moved, edited, 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 couldn’t be accessed\n"
      "It may have been moved, edited, 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());
}
