// Copyright 2018 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 "chrome/browser/extensions/extension_action_runner.h"

#include "base/bind.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/json/json_reader.h"
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/tabs/tabs_api.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/tab_helper.h"
#include "chrome/browser/metrics/subprocess_metrics_provider.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/network_service_util.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/common/extension_features.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/cross_origin_read_blocking.h"
#include "services/network/public/cpp/features.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace extensions {

using CORBAction = network::CrossOriginReadBlocking::Action;

class CrossOriginReadBlockingExtensionTest : public ExtensionBrowserTest {
 public:
  CrossOriginReadBlockingExtensionTest() = default;

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

    host_resolver()->AddRule("*", "127.0.0.1");
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
  }

 protected:
  content::WebContents* active_web_contents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  const Extension* InstallExtension(
      GURL resource_to_fetch_from_declarative_content_script = GURL()) {
    bool use_declarative_content_script =
        resource_to_fetch_from_declarative_content_script.is_valid();
    const char kContentScriptManifestEntry[] = R"(
          "content_scripts": [{
            "all_frames": true,
            "match_about_blank": true,
            "matches": ["*://*/*"],
            "js": ["content_script.js"]
          }],
    )";

    const char kManifestTemplate[] = R"(
        {
          "name": "CrossOriginReadBlockingTest - Extension",
          "version": "1.0",
          "manifest_version": 2,
          "permissions": ["tabs", "*://*/*"],
          %s
          "background": {"scripts": ["background_script.js"]}
        } )";
    dir_.WriteManifest(base::StringPrintf(
        kManifestTemplate,
        use_declarative_content_script ? kContentScriptManifestEntry : ""));

    dir_.WriteFile(FILE_PATH_LITERAL("background_script.js"), "");
    dir_.WriteFile(FILE_PATH_LITERAL("page.html"), "<body>Hello World!</body>");

    if (use_declarative_content_script) {
      dir_.WriteFile(
          FILE_PATH_LITERAL("content_script.js"),
          CreateFetchScript(resource_to_fetch_from_declarative_content_script));
    }
    extension_ = LoadExtension(dir_.UnpackedPath());
    return extension_;
  }

  const Extension* InstallApp() {
    const char kManifest[] = R"(
        {
          "name": "CrossOriginReadBlockingTest - App",
          "version": "1.0",
          "manifest_version": 2,
          "permissions": ["*://*/*", "webview"],
          "app": {
            "background": {
              "scripts": ["background_script.js"]
            }
          }
        } )";
    dir_.WriteManifest(kManifest);

    const char kBackgroungScript[] = R"(
        chrome.app.runtime.onLaunched.addListener(function() {
          chrome.app.window.create('page.html', {}, function () {});
        });
    )";
    dir_.WriteFile(FILE_PATH_LITERAL("background_script.js"),
                   kBackgroungScript);

    const char kPage[] = R"(
        <div id="webview-tag-container"></div>
    )";
    dir_.WriteFile(FILE_PATH_LITERAL("page.html"), kPage);

    extension_ = LoadExtension(dir_.UnpackedPath());
    return extension_;
  }

  bool RegisterServiceWorkerForExtension(
      const std::string& service_worker_script) {
    const char kServiceWorkerPath[] = "service_worker.js";
    dir_.WriteFile(base::FilePath::FromUTF8Unsafe(kServiceWorkerPath).value(),
                   service_worker_script);

    const char kRegistrationScript[] = R"(
        navigator.serviceWorker.register($1).then(function() {
          // Wait until the service worker is active.
          return navigator.serviceWorker.ready;
        }).then(function(r) {
          window.domAutomationController.send('SUCCESS');
        }).catch(function(err) {
          window.domAutomationController.send('ERROR: ' + err.message);
        }); )";
    std::string registration_script =
        content::JsReplace(kRegistrationScript, kServiceWorkerPath);

    std::string result = browsertest_util::ExecuteScriptInBackgroundPage(
        browser()->profile(), extension_->id(), registration_script);
    if (result != "SUCCESS") {
      ADD_FAILURE() << "Failed to register the service worker: " << result;
      return false;
    }
    return !::testing::Test::HasFailure();
  }

  // Injects (into |web_contents|) a content_script that performs a fetch of
  // |url|. Returns the body of the response.
  //
  // The method below uses "programmatic" (rather than "declarative") way to
  // inject a content script, but the behavior and permissions of the conecnt
  // script should be the same in both cases.  See also
  // https://developer.chrome.com/extensions/content_scripts#programmatic.
  std::string FetchViaContentScript(const GURL& url,
                                    content::WebContents* web_contents) {
    return FetchHelper(
        url, base::BindOnce(
                 &CrossOriginReadBlockingExtensionTest::ExecuteContentScript,
                 base::Unretained(this), base::Unretained(web_contents)));
  }

  // Performs a fetch of |url| from the background page of the test extension.
  // Returns the body of the response.
  std::string FetchViaBackgroundPage(const GURL& url) {
    return FetchHelper(
        url, base::BindOnce(
                 &browsertest_util::ExecuteScriptInBackgroundPageNoWait,
                 base::Unretained(browser()->profile()), extension_->id()));
  }

  // Performs a fetch of |url| from |web_contents| (directly, without going
  // through content scripts).  Returns the body of the response.
  std::string FetchViaWebContents(const GURL& url,
                                  content::WebContents* web_contents) {
    return FetchHelper(
        url, base::BindOnce(
                 &CrossOriginReadBlockingExtensionTest::ExecuteRegularScript,
                 base::Unretained(this), base::Unretained(web_contents)));
  }

  // Performs a fetch of |url| from a srcdoc subframe added to |parent_frame|
  // and executing a script via <script> tag.  Returns the body of the response.
  std::string FetchViaSrcDocFrame(GURL url,
                                  content::RenderFrameHost* parent_frame) {
    return FetchHelper(
        url, base::BindOnce(
                 &CrossOriginReadBlockingExtensionTest::ExecuteInSrcDocFrame,
                 base::Unretained(this), base::Unretained(parent_frame)));
  }

  std::string PopString(content::DOMMessageQueue* message_queue) {
    std::string json;
    EXPECT_TRUE(message_queue->WaitForMessage(&json));
    base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS);
    std::unique_ptr<base::Value> value = reader.ReadToValueDeprecated(json);
    std::string result;
    EXPECT_TRUE(value->GetAsString(&result));
    return result;
  }

  GURL GetExtensionResource(const std::string& relative_path) {
    return extension_->GetResourceURL(relative_path);
  }

  url::Origin GetExtensionOrigin() {
    return url::Origin::Create(extension_->url());
  }

  GURL GetTestPageUrl(const std::string& hostname) {
    // Using the page below avoids a network fetch of /favicon.ico which helps
    // avoid extra synchronization hassles in the tests.
    return embedded_test_server()->GetURL(
        hostname, "/favicon/title1_with_data_uri_icon.html");
  }

  const Extension* extension() { return extension_; }

  std::string CreateFetchScript(const GURL& resource) {
    const char kXhrScriptTemplate[] = R"(
      fetch($1)
        .then(response => response.text())
        .then(text => domAutomationController.send(text))
        .catch(err => domAutomationController.send('error: ' + err));
    )";
    return content::JsReplace(kXhrScriptTemplate, resource);
  }

  // Asks the test |extension_| to inject |content_script| into |web_contents|.
  //
  // This is an implementation of FetchCallback.
  // Returns true if the content script execution started succeessfully.
  bool ExecuteContentScript(content::WebContents* web_contents,
                            const std::string& content_script) {
    int tab_id = ExtensionTabUtil::GetTabId(web_contents);
    std::string background_script = content::JsReplace(
        "chrome.tabs.executeScript($1, { code: $2 });", tab_id, content_script);
    return browsertest_util::ExecuteScriptInBackgroundPageNoWait(
        browser()->profile(), extension_->id(), background_script);
  }

 private:
  // Executes |regular_script| in |web_contents|.
  //
  // This is an implementation of FetchCallback.
  // Returns true if the script execution started succeessfully.
  bool ExecuteRegularScript(content::WebContents* web_contents,
                            const std::string& regular_script) {
    content::ExecuteScriptAsync(web_contents, regular_script);

    // Report artificial success to meet FetchCallback's requirements.
    return true;
  }

  // Injects into |parent_frame| an "srcdoc" subframe that contains/executes
  // |script_to_run_in_subframe| via <script> tag.
  //
  // This function is useful to exercise a scenario when a <script> tag may
  // execute before the browser gets a chance to see the a frame/navigation
  // commit is happening.
  //
  // This is an implementation of FetchCallback.
  // Returns true if the script execution started succeessfully.
  bool ExecuteInSrcDocFrame(content::RenderFrameHost* parent_frame,
                            const std::string& script_to_run_in_subframe) {
    static int sequence_id = 0;
    sequence_id++;
    std::string filename =
        base::StringPrintf("srcdoc_script_%d.js", sequence_id);
    dir_.WriteFile(base::FilePath::FromUTF8Unsafe(filename).value(),
                   script_to_run_in_subframe);

    // Using <script src=...></script> instead of <script>...</script> to avoid
    // extensions CSP which forbids inline scripts.
    const char kScriptTemplate[] = R"(
        var subframe = document.createElement('iframe');
        subframe.srcdoc = '<script src=' + $1 + '></script>';
        document.body.appendChild(subframe); )";
    std::string subframe_injection_script =
        content::JsReplace(kScriptTemplate, filename);
    content::ExecuteScriptAsync(parent_frame, subframe_injection_script);

    // Report artificial success to meet FetchCallback's requirements.
    return true;
  }

  // FetchCallback represents a function that executes |fetch_script|.
  //
  // |fetch_script| will include calls to |domAutomationController.send| and
  // therefore instances of FetchCallback should not inject their own calls to
  // |domAutomationController.send| (e.g. this constraint rules out
  // browsertest_util::ExecuteScriptInBackgroundPage and/or
  // content::ExecuteScript).
  //
  // The function should return true if script execution started successfully.
  //
  // Currently used "implementations":
  // - CrossOriginReadBlockingExtensionTest::ExecuteContentScript(web_contents)
  // - CrossOriginReadBlockingExtensionTest::ExecuteRegularScript(web_contents)
  // - browsertest_util::ExecuteScriptInBackgroundPageNoWait(profile, ext_id)
  using FetchCallback =
      base::OnceCallback<bool(const std::string& fetch_script)>;

  // Returns response body of a fetch of |url| initiated via |fetch_callback|.
  std::string FetchHelper(const GURL& url, FetchCallback fetch_callback) {
    content::DOMMessageQueue message_queue;

    // Inject a content script that performs a cross-origin XHR to bar.com.
    EXPECT_TRUE(std::move(fetch_callback).Run(CreateFetchScript(url)));

    // Wait until the message comes back and extract result from the message.
    return PopString(&message_queue);
  }

  TestExtensionDir dir_;
  const Extension* extension_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(CrossOriginReadBlockingExtensionTest);
};

struct AllowlistingParam {
  AllowlistingParam(bool feature_enabled, bool test_extension_allowlisted)
      : feature_enabled(feature_enabled),
        test_extension_allowlisted(test_extension_allowlisted) {}

  bool feature_enabled;
  bool test_extension_allowlisted;
};

class CrossOriginReadBlockingExtensionAllowlistingTest
    : public CrossOriginReadBlockingExtensionTest,
      public ::testing::WithParamInterface<AllowlistingParam> {
 public:
  using Base = CrossOriginReadBlockingExtensionTest;

  CrossOriginReadBlockingExtensionAllowlistingTest() {}

  bool IsAllowlistFeatureEnabled() { return GetParam().feature_enabled; }
  bool IsExtensionAllowlisted() {
    return GetParam().test_extension_allowlisted;
  }

  const Extension* InstallExtension(
      GURL resource_to_fetch_from_declarative_content_script = GURL()) {
    const Extension* extension = Base::InstallExtension(
        resource_to_fetch_from_declarative_content_script);

    if (IsAllowlistFeatureEnabled()) {
      if (IsExtensionAllowlisted()) {
        scoped_feature_list_.InitAndEnableFeatureWithParameters(
            extensions_features::kBypassCorbOnlyForExtensionsAllowlist,
            {{extensions_features::kBypassCorbAllowlistParamName,
              extension->hashed_id().value()}});
      } else {
        scoped_feature_list_.InitAndEnableFeature(
            extensions_features::kBypassCorbOnlyForExtensionsAllowlist);
      }
    } else {
      scoped_feature_list_.InitAndDisableFeature(
          extensions_features::kBypassCorbOnlyForExtensionsAllowlist);
    }

    return extension;
  }

  bool AreContentScriptFetchesExpectedToBeBlocked() {
    return IsAllowlistFeatureEnabled() && !IsExtensionAllowlisted();
  }

  bool IsCorbExpectedToBeTurnedOffAltogether() {
    return (IsExtensionAllowlisted() || !IsAllowlistFeatureEnabled());
  }

  void VerifyFetchFromContentScriptWasBlocked(
      const base::HistogramTester& histograms) {
    // Make sure that histograms logged in other processes (e.g. in
    // NetworkService process) get synced.
    SubprocessMetricsProvider::MergeHistogramDeltasForTesting();

    histograms.ExpectBucketCount("SiteIsolation.XSD.Browser.Action",
                                 CORBAction::kResponseStarted, 1);
    histograms.ExpectBucketCount("SiteIsolation.XSD.Browser.Action",
                                 CORBAction::kBlockedWithoutSniffing, 1);
  }

  void VerifyFetchFromContentScriptWasAllowed(
      const base::HistogramTester& histograms,
      bool expecting_sniffing = false) {
    // Make sure that histograms logged in other processes (e.g. in
    // NetworkService process) get synced.
    SubprocessMetricsProvider::MergeHistogramDeltasForTesting();

    if (IsCorbExpectedToBeTurnedOffAltogether()) {
      EXPECT_EQ(0u,
                histograms.GetTotalCountsForPrefix("SiteIsolation.XSD.Browser")
                    .size());
      return;
    }

    histograms.ExpectBucketCount("SiteIsolation.XSD.Browser.Action",
                                 CORBAction::kResponseStarted, 1);
    histograms.ExpectBucketCount("SiteIsolation.XSD.Browser.Action",
                                 expecting_sniffing
                                     ? CORBAction::kAllowedAfterSniffing
                                     : CORBAction::kAllowedWithoutSniffing,
                                 1);
  }

  // Verifies results of fetching a CORB-eligible resource from a content
  // script.  Expectations differ depending on the following:
  // 1. Non-NetworkService: Fetches from content scripts should never be blocked
  // 2. NetworkService + allowlisted extension: Fetches from content scripts
  //                                            should not be blocked
  // 3. NetworkService + other extension: Fetches from content scripts should
  //                                      be blocked
  void VerifyFetchFromContentScript(const base::HistogramTester& histograms,
                                    const std::string& actual_fetch_result,
                                    const std::string& expected_fetch_result) {
    if (AreContentScriptFetchesExpectedToBeBlocked()) {
      // Verify the fetch was blocked.
      EXPECT_EQ(std::string(), actual_fetch_result);
      VerifyFetchFromContentScriptWasBlocked(histograms);
    } else {
      // Verify the fetch was allowed.
      EXPECT_EQ(expected_fetch_result, actual_fetch_result);
      VerifyFetchFromContentScriptWasAllowed(histograms);
    }
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(CrossOriginReadBlockingExtensionAllowlistingTest);
};

IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       FromDeclarativeContentScript_NoSniffXml) {
  // Load the test extension.
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
  ASSERT_TRUE(InstallExtension(cross_site_resource));

  // Test case #1: Declarative script injected after a browser-initiated
  // navigation of the main frame.
  {
    // Monitor CORB behavior + result of the fetch.
    base::HistogramTester histograms;
    content::DOMMessageQueue message_queue;

    // Navigate to a foo.com page - this should trigger execution of the
    // |content_script| declared in the extension manifest.
    GURL page_url = GetTestPageUrl("foo.com");
    ui_test_utils::NavigateToURL(browser(), page_url);
    EXPECT_EQ(page_url,
              active_web_contents()->GetMainFrame()->GetLastCommittedURL());
    EXPECT_EQ(url::Origin::Create(page_url),
              active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

    // Extract results of the fetch done in the declarative content script.
    std::string fetch_result = PopString(&message_queue);

    // Verify whether the fetch worked or not (expectations differ depending on
    // various factors - see the body of VerifyFetchFromContentScript).
    VerifyFetchFromContentScript(histograms, fetch_result,
                                 "nosniff.xml - body\n");
  }

  // Test case #2: Declarative script injected after a renderer-initiated
  // creation of an about:blank frame.
  {
    // Monitor CORB behavior + result of the fetch.
    base::HistogramTester histograms;
    content::DOMMessageQueue message_queue;

    // Inject an about:blank subframe - this should trigger execution of the
    // |content_script| declared in the extension manifest.
    const char kBlankSubframeInjectionScript[] = R"(
        var subframe = document.createElement('iframe');
        document.body.appendChild(subframe); )";
    content::ExecuteScriptAsync(active_web_contents(),
                                kBlankSubframeInjectionScript);

    // Extract results of the fetch done in the declarative content script.
    std::string fetch_result = PopString(&message_queue);

    // Verify whether the fetch worked or not (expectations differ depending on
    // various factors - see the body of VerifyFetchFromContentScript).
    VerifyFetchFromContentScript(histograms, fetch_result,
                                 "nosniff.xml - body\n");
  }
}

// Test that verifies the current, baked-in (but not necessarily desirable
// behavior) where an extension that has permission to inject a content script
// to any page can also XHR (without CORS!) any cross-origin resource.
// See also https://crbug.com/846346.
IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       FromProgrammaticContentScript_NoSniffXml) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a cross-origin XHR to bar.com.
  base::HistogramTester histograms;
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
  std::string fetch_result =
      FetchViaContentScript(cross_site_resource, active_web_contents());

  // Verify whether the fetch worked or not (expectations differ depending on
  // various factors - see the body of VerifyFetchFromContentScript).
  VerifyFetchFromContentScript(histograms, fetch_result,
                               "nosniff.xml - body\n");
}

// Tests that same-origin fetches (same-origin relative to the webpage the
// content script is injected into) are allowed.  See also
// https://crbug.com/918660.
IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       FromProgrammaticContentScript_SameOrigin) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a same-origin XHR to foo.com.
  base::HistogramTester histograms;
  GURL same_origin_resource(
      embedded_test_server()->GetURL("foo.com", "/nosniff.xml"));
  std::string fetch_result =
      FetchViaContentScript(same_origin_resource, active_web_contents());

  // Verify that no blocking occurred.
  EXPECT_THAT(fetch_result, ::testing::StartsWith("nosniff.xml - body"));
  VerifyFetchFromContentScriptWasAllowed(histograms,
                                         false /* expecting_sniffing */);
}

// Test that responses that would have been allowed by CORB anyway are not
// reported to LogInitiatorSchemeBypassingDocumentBlocking.
IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       FromProgrammaticContentScript_AllowedTextResource) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a cross-origin XHR to bar.com.
  //
  // StartsWith (rather than equality) is used in the verification step to
  // account for \n VS \r\n difference on Windows.
  base::HistogramTester histograms;
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/save_page/text.txt"));
  std::string fetch_result =
      FetchViaContentScript(cross_site_resource, active_web_contents());

  // Verify that no blocking occurred.
  EXPECT_THAT(fetch_result,
              ::testing::StartsWith(
                  "text-object.txt: ae52dd09-9746-4b7e-86a6-6ada5e2680c2"));
  VerifyFetchFromContentScriptWasAllowed(histograms,
                                         true /* expecting_sniffing */);
}

// Test that responses are blocked by CORB, but have empty response body are not
// reported to LogInitiatorSchemeBypassingDocumentBlocking.
IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       FromProgrammaticContentScript_EmptyAndBlocked) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a cross-origin XHR to bar.com.
  base::HistogramTester histograms;
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/nosniff.empty"));
  EXPECT_EQ(std::string(),
            FetchViaContentScript(cross_site_resource, active_web_contents()));

  // Verify whether blocking occurred or not.
  if (AreContentScriptFetchesExpectedToBeBlocked())
    VerifyFetchFromContentScriptWasBlocked(histograms);
  else
    VerifyFetchFromContentScriptWasAllowed(histograms);
}

// Test that LogInitiatorSchemeBypassingDocumentBlocking exits early for
// requests that aren't from content scripts.
IN_PROC_BROWSER_TEST_F(CrossOriginReadBlockingExtensionTest,
                       FromBackgroundPage_NoSniffXml) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Performs a cross-origin XHR from the background page.
  base::HistogramTester histograms;
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
  std::string fetch_result = FetchViaBackgroundPage(cross_site_resource);

  // Verify that no blocking occurred.
  EXPECT_EQ("nosniff.xml - body\n", fetch_result);
}

// Test that requests from a extension page hosted in a foreground tab use
// relaxed CORB processing.
IN_PROC_BROWSER_TEST_F(CrossOriginReadBlockingExtensionTest,
                       FromForegroundPage_NoSniffXml) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate a tab to an extension page.
  ui_test_utils::NavigateToURL(browser(), GetExtensionResource("page.html"));
  ASSERT_EQ(GetExtensionOrigin(),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Test case #1: Fetch from a chrome-extension://... main frame.
  {
    // Perform a cross-origin XHR from the foreground extension page.
    base::HistogramTester histograms;
    GURL cross_site_resource(
        embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
    std::string fetch_result =
        FetchViaWebContents(cross_site_resource, active_web_contents());

    // Verify that no blocking occurred.
    EXPECT_EQ("nosniff.xml - body\n", fetch_result);
  }

  // Test case #2: Fetch from an about:srcdoc subframe of a
  // chrome-extension://... frame.
  {
    // Perform a cross-origin XHR from the foreground extension page.
    base::HistogramTester histograms;
    GURL cross_site_resource(
        embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
    std::string fetch_result = FetchViaSrcDocFrame(
        cross_site_resource, active_web_contents()->GetMainFrame());

    // Verify that no blocking occurred.
    EXPECT_EQ("nosniff.xml - body\n", fetch_result);
  }
}

// Test that requests from an extension's service worker to the network use
// relaxed CORB processing (both in the case of requests that 1) are initiated
// by the service worker and/or 2) are ignored by the service worker and fall
// back to the network).
IN_PROC_BROWSER_TEST_F(CrossOriginReadBlockingExtensionTest,
                       FromServiceWorker_NoSniffXml) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Register the service worker which injects "SERVICE WORKER INTERCEPT: "
  // prefix to the body of each response.
  const char kServiceWorkerScript[] = R"(
      self.addEventListener('fetch', function(event) {
          // Intercept all http requests to bar.com and inject
          // 'SERVICE WORKER INTERCEPT:' prefix.
          if (event.request.url.startsWith('http://bar.com')) {
            event.respondWith(
                // By using the 'fetch' call below, the service worker initiates
                // a network request that will go through the URLLoaderFactory
                // created via CreateFactoryBundle called / posted indirectly
                // from EmbeddedWorkerInstance::StartTask::Start.
                fetch(event.request)
                    .then(response => response.text())
                    .then(text => new Response(
                        'SERVICE WORKER INTERCEPT: >>>' + text + '<<<')));
          }

          // Let the request go directly to the network in all the other cases,
          // like:
          // - loading the extension resources like page.html (avoiding going
          //   through the service worker is required for correctness of test
          //   setup),
          // - handling the cross-origin fetch to other.com in test case #2.
          // Note that these requests will use the URLLoaderFactory owned by
          // ServiceWorkerSubresourceLoader which can be different to the
          // network loader factory owned by the ServiceWorker thread (which is
          // used for fetch intiated by the service worker above).
      }); )";
  ASSERT_TRUE(RegisterServiceWorkerForExtension(kServiceWorkerScript));

  // Navigate a tab to an extension page.
  ui_test_utils::NavigateToURL(browser(), GetExtensionResource("page.html"));
  ASSERT_EQ(GetExtensionOrigin(),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Verify that the service worker controls the fetches.
  bool is_controlled_by_service_worker = false;
  ASSERT_TRUE(ExecuteScriptAndExtractBool(
      active_web_contents(),
      "domAutomationController.send(!!navigator.serviceWorker.controller)",
      &is_controlled_by_service_worker));
  ASSERT_TRUE(is_controlled_by_service_worker);

  // Test case #1: Network fetch initiated by the service worker.
  //
  // This covers URLLoaderFactory owned by the ServiceWorker thread and created
  // created via CreateFactoryBundle called / posted indirectly from
  // EmbeddedWorkerInstance::StartTask::Start.
  {
    // Perform a cross-origin XHR from the foreground extension page.
    // This should be intercepted by the service worker installed above.
    base::HistogramTester histograms;
    GURL cross_site_resource_intercepted_by_service_worker(
        embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
    std::string fetch_result =
        FetchViaWebContents(cross_site_resource_intercepted_by_service_worker,
                            active_web_contents());

    // Verify that no blocking occurred (and that the response really did go
    // through the service worker).
    EXPECT_EQ("SERVICE WORKER INTERCEPT: >>>nosniff.xml - body\n<<<",
              fetch_result);
  }

  // Test case #2: Network fetch used as a fallback when service worker ignores
  // the 'fetch' event.
  //
  // This covers URLLoaderFactory owned by the ServiceWorkerSubresourceLoader,
  // which can be different to the network loader factory owned by the
  // ServiceWorker thread (which is used in test case #1).
  {
    // Perform a cross-origin XHR from the foreground extension page.
    // This should be intercepted by the service worker installed above.
    base::HistogramTester histograms;
    GURL cross_site_resource_ignored_by_service_worker(
        embedded_test_server()->GetURL("other.com", "/nosniff.xml"));
    std::string fetch_result = FetchViaWebContents(
        cross_site_resource_ignored_by_service_worker, active_web_contents());

    // Verify that no blocking occurred.
    EXPECT_EQ("nosniff.xml - body\n", fetch_result);
  }
}

class ReadyToCommitWaiter : public content::WebContentsObserver {
 public:
  explicit ReadyToCommitWaiter(content::WebContents* web_contents)
      : content::WebContentsObserver(web_contents) {}

  ~ReadyToCommitWaiter() override {}

  void Wait() { run_loop_.Run(); }

  void ReadyToCommitNavigation(
      content::NavigationHandle* navigation_handle) override {
    run_loop_.Quit();
  }

 private:
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(ReadyToCommitWaiter);
};

IN_PROC_BROWSER_TEST_F(CrossOriginReadBlockingExtensionTest,
                       ProgrammaticContentScriptVsWebUI) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Try to inject a content script just as we are about to commit a WebUI page.
  // This will cause ExecuteCodeInTabFunction::CanExecuteScriptOnPage to execute
  // while RenderFrameHost::GetLastCommittedOrigin() still corresponds to the
  // old page.
  {
    // Initiate navigating a new, blank tab (this avoids process swaps which
    // would otherwise occur when navigating to a WebUI pages from either the
    // NTP or from a web page).  This simulates choosing "Settings" from the
    // main menu.
    GURL web_ui_url("chrome://settings");
    NavigateParams nav_params(
        browser(), web_ui_url,
        ui::PageTransitionFromInt(ui::PAGE_TRANSITION_GENERATED));
    nav_params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
    content::WebContentsAddedObserver new_web_contents_observer;
    Navigate(&nav_params);

    // Capture the new WebContents.
    content::WebContents* new_web_contents =
        new_web_contents_observer.GetWebContents();
    ReadyToCommitWaiter ready_to_commit_waiter(new_web_contents);
    content::TestNavigationObserver navigation_observer(new_web_contents, 1);

    // Repro of https://crbug.com/894766 requires that no cross-process swap
    // takes place - this is what happens when navigating an initial/blank tab.

    // Wait until ReadyToCommit happens.
    //
    // For the repro to happen, content script injection needs to run
    // 1) after RenderFrameHostImpl::CommitNavigation
    //    (which runs in the same revolution of the message pump as
    //    WebContentsObserver::ReadyToCommitNavigation)
    // 2) before RenderFrameHostImpl::DidCommitProvisionalLoad
    //    (task posted from ReadyToCommitNavigation above should execute
    //     before any IPC responses that come after PostTask call).
    ready_to_commit_waiter.Wait();
    DCHECK_NE(web_ui_url,
              active_web_contents()->GetMainFrame()->GetLastCommittedURL());

    // Inject the content script (simulating chrome.tabs.executeScript, but
    // using TabsExecuteScriptFunction directly to ensure the right timing).
    int tab_id = ExtensionTabUtil::GetTabId(active_web_contents());
    const char kArgsTemplate[] = R"(
        [%d, {"code": "
            var p = document.createElement('p');
            p.innerText = 'content script injection succeeded unexpectedly';
            p.id = 'content-script-injection-result';
            document.body.appendChild(p);
        "}] )";
    std::string args = base::StringPrintf(kArgsTemplate, tab_id);
    auto function = base::MakeRefCounted<TabsExecuteScriptFunction>();
    function->set_extension(extension());
    std::string actual_error =
        extension_function_test_utils::RunFunctionAndReturnError(
            function.get(), args, browser());
    std::string expected_error =
        "Cannot access contents of url \"chrome://settings/\". "
        "Extension manifest must request permission to access this host.";
    EXPECT_EQ(expected_error, actual_error);

    // Wait until the navigation completes.
    navigation_observer.Wait();
    EXPECT_EQ(web_ui_url,
              active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  }

  // Check if the injection above succeeded (it shouldn't have, because of
  // renderer-side checks).
  const char kInjectionVerificationScript[] = R"(
      domAutomationController.send(
          !!document.getElementById('content-script-injection-result')); )";
  bool has_content_script_run = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(active_web_contents(),
                                                   kInjectionVerificationScript,
                                                   &has_content_script_run));
  EXPECT_FALSE(has_content_script_run);

  // Try to fetch a WebUI resource (i.e. verify that the unsucessful content
  // script injection above didn't clobber the WebUI-specific URLLoaderFactory).
  const char kScript[] = R"(
      var img = document.createElement('img');
      img.src = 'chrome://resources/images/arrow_down.svg';
      img.onload = () => domAutomationController.send('LOADED');
      img.onerror = e => domAutomationController.send('ERROR: ' + e);
  )";
  std::string result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(active_web_contents(),
                                                     kScript, &result));
  EXPECT_EQ("LOADED", result);
}

IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       ProgrammaticContentScriptVsAppCache) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Set up http server serving files from content/test/data (which conveniently
  // already contains appcache-related test files, unlike chrome/test/data).
  net::EmbeddedTestServer content_test_data_server;
  content_test_data_server.AddDefaultHandlers(
      base::FilePath(FILE_PATH_LITERAL("content/test/data")));
  ASSERT_TRUE(content_test_data_server.Start());

  // Load the main page twice. The second navigation should have AppCache
  // initialized for the page.
  GURL main_url = content_test_data_server.GetURL(
      "/appcache/simple_page_with_manifest.html");
  ui_test_utils::NavigateToURL(browser(), main_url);
  base::string16 expected_title = base::ASCIIToUTF16("AppCache updated");
  content::TitleWatcher title_watcher(active_web_contents(), expected_title);
  EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
  ui_test_utils::NavigateToURL(browser(), main_url);

  // Turn off the server and sanity check that the resource is still available.
  const char kScriptTemplate[] = R"(
      new Promise(function (resolve, reject) {
          var img = document.createElement('img');
          img.src = '/appcache/' + $1;
          img.onload = _ => resolve('IMG LOADED');
          img.onerror = reject;
      })
  )";
  ASSERT_TRUE(content_test_data_server.ShutdownAndWaitUntilComplete());
  EXPECT_EQ("IMG LOADED",
            content::EvalJs(active_web_contents(),
                            content::JsReplace(kScriptTemplate, "logo.png")));

  // Inject a content script and verify that this doesn't negatively impact
  // AppCache (i.e. verify that
  // RenderFrameHostImpl::MarkInitiatorsAsRequiringSeparateURLLoaderFactory
  // does not clobber the default URLLoaderFactory).
  {
    SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
    base::HistogramTester histograms;
    GURL cross_site_resource(
        embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
    std::string fetch_result =
        FetchViaContentScript(cross_site_resource, active_web_contents());

    // Verify whether the fetch worked or not (expectations differ depending on
    // various factors - see the body of VerifyFetchFromContentScript).
    VerifyFetchFromContentScript(histograms, fetch_result,
                                 "nosniff.xml - body\n");
  }
  // Using a different image, to bypass renderer-side caching.
  EXPECT_EQ("IMG LOADED",
            content::EvalJs(active_web_contents(),
                            content::JsReplace(kScriptTemplate, "logo2.png")));

  // Crash the network service and wait for things to come back up.  This (and
  // the remaining part of the test) only makes sense if 1) the network service
  // is enabled and running in a separate process and 2) the frame has at least
  // one network-bound URLLoaderFactory (i.e. the test extension is
  // allowlisted).
  if (!content::IsOutOfProcessNetworkService() || !IsExtensionAllowlisted())
    return;
  SimulateNetworkServiceCrash();
  active_web_contents()
      ->GetMainFrame()
      ->FlushNetworkAndNavigationInterfacesForTesting();

  // Make sure that both requests still work - the code should have recovered
  // from the crash by 1) refreshing the URLLoaderFactory for the content script
  // and 2) without cloberring the default factory for the AppCache.
  {
    SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
    base::HistogramTester histograms;
    GURL cross_site_resource(
        embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
    std::string fetch_result =
        FetchViaContentScript(cross_site_resource, active_web_contents());

    // Verify whether the fetch worked or not (expectations differ depending on
    // various factors - see the body of VerifyFetchFromContentScript).
    VerifyFetchFromContentScript(histograms, fetch_result,
                                 "nosniff.xml - body\n");
  }
  // Using a different image, to bypass renderer-side caching.
  EXPECT_EQ("IMG LOADED",
            content::EvalJs(active_web_contents(),
                            content::JsReplace(kScriptTemplate, "logo3.png")));
}

IN_PROC_BROWSER_TEST_F(CrossOriginReadBlockingExtensionTest,
                       WebViewContentScript) {
  // Load the test app.
  const Extension* app = InstallApp();
  ASSERT_TRUE(app);

  // Launch the test app and grab its WebContents.
  content::WebContents* app_contents = nullptr;
  {
    content::WebContentsAddedObserver new_contents_observer;
    OpenApplication(AppLaunchParams(browser()->profile(), app->id(),
                                    LaunchContainer::kLaunchContainerNone,
                                    WindowOpenDisposition::NEW_WINDOW,
                                    extensions::AppLaunchSource::kSourceTest));
    app_contents = new_contents_observer.GetWebContents();
  }
  ASSERT_TRUE(content::WaitForLoadStop(app_contents));

  // Inject a <webview> script and declare desire to inject
  // cross-origin-fetching content scripts into the guest.
  const char kWebViewInjectionScriptTemplate[] = R"(
      document.querySelector('#webview-tag-container').innerHTML =
          '<webview style="width: 100px; height: 100px;"></webview>';
      var webview = document.querySelector('webview');
      webview.addContentScripts([{
          name: 'rule',
          matches: ['*://*/*'],
          js: { code: $1 },
          run_at: 'document_start'}]);
  )";
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/nosniff.xml"));
  std::string web_view_injection_script = content::JsReplace(
      kWebViewInjectionScriptTemplate, CreateFetchScript(cross_site_resource));
  ASSERT_TRUE(ExecuteScript(app_contents, web_view_injection_script));

  // Navigate <webview>, which should trigger content script execution.
  GURL guest_url(embedded_test_server()->GetURL("foo.com", "/title1.html"));
  const char kWebViewNavigationScriptTemplate[] = R"(
      var webview = document.querySelector('webview');
      webview.src = $1;
  )";
  std::string web_view_navigation_script =
      content::JsReplace(kWebViewNavigationScriptTemplate, guest_url);
  {
    content::DOMMessageQueue queue;
    base::HistogramTester histograms;
    content::ExecuteScriptAsync(app_contents, web_view_navigation_script);
    std::string fetch_result = PopString(&queue);

    // Verify that no CORB blocking occurred.
    EXPECT_EQ("nosniff.xml - body\n", fetch_result);
  }
}

IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       OriginHeaderInCrossOriginGetRequest) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a cross-origin GET XHR to bar.com.
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/echoall"));
  const char* kScriptTemplate = R"(
      fetch($1, {method: 'GET', mode:'cors'})
          .then(response => response.text())
          .then(text => domAutomationController.send(text))
          .catch(err => domAutomationController.send('ERROR: ' + err));
  )";
  content::DOMMessageQueue message_queue;
  ExecuteContentScript(
      active_web_contents(),
      content::JsReplace(kScriptTemplate, cross_site_resource));
  std::string fetch_result = PopString(&message_queue);

  // Verify if the fetch was blocked + what the Origin header was.
  if (AreContentScriptFetchesExpectedToBeBlocked()) {
    // TODO(lukasza): https://crbug.com/953315: No CORB blocking should occur
    // for the CORS-mode request - the test expectations should be the same,
    // regardless of AreContentScriptFetchesExpectedToBeBlocked.
    EXPECT_EQ("", fetch_result);
  } else if (IsExtensionAllowlisted()) {
    // Legacy behavior - no Origin: header is present in GET CORS requests from
    // content scripts based on the extension permissions.
    EXPECT_THAT(fetch_result, ::testing::Not(::testing::HasSubstr("Origin:")));
  } else {
    // TODO(lukasza): https://crbug.com/920638: Non-allowlisted extension
    // should use the website's origin in the CORS request.
    // TODO: EXPECT_THAT(fetch_result,
    //                   ::testing::HasSubstr("Origin: http://foo.com"));
    EXPECT_THAT(fetch_result, ::testing::Not(::testing::HasSubstr("Origin:")));
  }

  // Regression test against https://crbug.com/944704.
  EXPECT_THAT(fetch_result,
              ::testing::Not(::testing::HasSubstr("Origin: chrome-extension")));
}

IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       OriginHeaderInCrossOriginPostRequest) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a cross-origin POST XHR to bar.com.
  GURL cross_site_resource(
      embedded_test_server()->GetURL("bar.com", "/echoall"));
  const char* kScriptTemplate = R"(
      fetch($1, {method: 'POST', mode:'cors'})
          .then(response => response.text())
          .then(text => domAutomationController.send(text))
          .catch(err => domAutomationController.send('ERROR: ' + err));
  )";
  content::DOMMessageQueue message_queue;
  ExecuteContentScript(
      active_web_contents(),
      content::JsReplace(kScriptTemplate, cross_site_resource));
  std::string fetch_result = PopString(&message_queue);

  // Verify if the fetch was blocked + what the Origin header was.
  if (AreContentScriptFetchesExpectedToBeBlocked()) {
    // TODO(lukasza): https://crbug.com/953315: No CORB blocking should occur
    // for the CORS-mode request - the test expectations should be the same,
    // regardless of AreContentScriptFetchesExpectedToBeBlocked.
    EXPECT_EQ("", fetch_result);
  } else {
    EXPECT_THAT(fetch_result, ::testing::HasSubstr("Origin: http://foo.com"));
  }

  // Regression test against https://crbug.com/944704.
  EXPECT_THAT(fetch_result,
              ::testing::Not(::testing::HasSubstr("Origin: chrome-extension")));
}

IN_PROC_BROWSER_TEST_P(CrossOriginReadBlockingExtensionAllowlistingTest,
                       OriginHeaderInSameOriginPostRequest) {
  // Load the test extension.
  ASSERT_TRUE(InstallExtension());

  // Navigate to a foo.com page.
  GURL page_url = GetTestPageUrl("foo.com");
  ui_test_utils::NavigateToURL(browser(), page_url);
  ASSERT_EQ(page_url,
            active_web_contents()->GetMainFrame()->GetLastCommittedURL());
  ASSERT_EQ(url::Origin::Create(page_url),
            active_web_contents()->GetMainFrame()->GetLastCommittedOrigin());

  // Inject a content script that performs a same-origin POST XHR to foo.com.
  GURL same_origin_resource(
      embedded_test_server()->GetURL("foo.com", "/echoall"));
  const char* kScriptTemplate = R"(
      fetch($1, {method: 'POST', mode:'cors'})
          .then(response => response.text())
          .then(text => domAutomationController.send(text))
          .catch(err => domAutomationController.send('ERROR: ' + err));
  )";
  content::DOMMessageQueue message_queue;
  ExecuteContentScript(
      active_web_contents(),
      content::JsReplace(kScriptTemplate, same_origin_resource));
  std::string fetch_result = PopString(&message_queue);

  // Verify the Origin header.
  //
  // According to the Fetch spec, POST should always set the Origin header (even
  // for same-origin requests).
  EXPECT_THAT(fetch_result, ::testing::HasSubstr("Origin: http://foo.com"));

  // Regression test against https://crbug.com/944704.
  EXPECT_THAT(fetch_result,
              ::testing::Not(::testing::HasSubstr("Origin: chrome-extension")));
}

INSTANTIATE_TEST_SUITE_P(AllowlistingDisabled,
                         CrossOriginReadBlockingExtensionAllowlistingTest,
                         ::testing::Values(AllowlistingParam(false, false)));
INSTANTIATE_TEST_SUITE_P(Allowlisted,
                         CrossOriginReadBlockingExtensionAllowlistingTest,
                         ::testing::Values(AllowlistingParam(true, true)));
INSTANTIATE_TEST_SUITE_P(NotAllowlisted,
                         CrossOriginReadBlockingExtensionAllowlistingTest,
                         ::testing::Values(AllowlistingParam(true, false)));

}  // namespace extensions
