// 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/command_line.h"
#include "base/macros.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_utils.h"
#include "extensions/common/extension_urls.h"
#include "mojo/public/cpp/bindings/strong_associated_binding.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/features.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(), contents.c_str(), contents.length(), content_type,
        base::BindOnce(
            [](std::unique_ptr<content::BlobHandle>* out_blob,
               base::OnceClosure done,
               std::unique_ptr<content::BlobHandle> blob) {
              *out_blob = std::move(blob);
              std::move(done).Run();
            },
            &result, loop.QuitClosure()));
    loop.Run();
    EXPECT_TRUE(result);
    return result;
  }

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

IN_PROC_BROWSER_TEST_F(ChromeWebSecurityDisabledBrowserTest,
                       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 "blob:chrome://abc" resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CreateBlobInOtherChromeUIOrigin) {
  ui_test_utils::NavigateToURL(browser(), GURL("chrome://version"));

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

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

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

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

  content::PwnMessageHelper::RegisterBlobURL(
      rfh->GetProcess(), GURL("blob:" + target_origin + "/" + blob_path),
      blob_id);

  // If the process is killed, this test passes.
  crash_observer.Wait();
  histograms.ExpectUniqueSample("Stability.BadMessageTerminated.Content", 139,
                                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);
  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 "blob:chrome-extension://" resource.
IN_PROC_BROWSER_TEST_F(ChromeSecurityExploitBrowserTest,
                       CreateBlobInExtensionOrigin) {
  ui_test_utils::NavigateToURL(
      browser(),
      embedded_test_server()->GetURL("a.root-servers.net", "/title1.html"));

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

  // All these are attacker controlled values.
  std::string blob_type = "text/html";
  std::string blob_contents = "<script>chrome.extensions</script>";
  std::string blob_path = "5881f76e-10d2-410d-8c61-ef210502acfd";

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

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

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

  content::PwnMessageHelper::RegisterBlobURL(
      rfh->GetProcess(), GURL("blob:" + target_origin + "/" + blob_path),
      blob_id);

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

// 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);
  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:
  explicit BlobURLStoreInterceptor(GURL target_url) : target_url_(target_url) {}

  void Intercept(
      mojo::StrongAssociatedBindingPtr<blink::mojom::BlobURLStore> binding) {
    url_store_ = binding->SwapImplForTesting(this);
  }

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

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

 private:
  blink::mojom::BlobURLStore* url_store_;
  GURL target_url_;
};

}  // namespace

class ChromeSecurityExploitBrowserTestMojoBlobURLs
    : public ChromeSecurityExploitBrowserTest {
 public:
  ChromeSecurityExploitBrowserTestMojoBlobURLs() {
    scoped_feature_list_.InitAndEnableFeature(blink::features::kMojoBlobURLs);
  }

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

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

// 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";
  BlobURLStoreInterceptor interceptor(
      GURL("blob:" + target_origin + "/" + blob_path));
  auto intercept_hook = base::BindRepeating(&BlobURLStoreInterceptor::Intercept,
                                            base::Unretained(&interceptor));
  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();

  base::HistogramTester histograms;
  content::RenderProcessHostWatcher crash_observer(
      rfh->GetProcess(),
      content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);

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

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