blob: cd39f5f1575bf90d87c3d43fdbcee8faea3cc580 [file] [log] [blame]
// Copyright 2019 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/json/json_reader.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/net/profile_network_context_service.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/test/browser_test.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/test_extension_dir.h"
#include "net/dns/mock_host_resolver.h"
#include "net/ssl/client_cert_store.h"
#include "services/network/public/cpp/features.h"
#include "url/gurl.h"
namespace extensions {
namespace {
std::unique_ptr<net::ClientCertStore> CreateNullCertStore() {
return nullptr;
}
} // namespace
class BackgroundHeaderTest : public ExtensionBrowserTest {
public:
BackgroundHeaderTest()
: https_test_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
BackgroundHeaderTest(const BackgroundHeaderTest& other) = delete;
BackgroundHeaderTest& operator=(const BackgroundHeaderTest& other) = delete;
void SetUpCommandLine(base::CommandLine* command_line) override {
ExtensionBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
}
GURL GetSecFetchUrl(const std::string& hostname) {
if (hostname.empty())
return https_test_server_.GetURL("/echoheader?sec-fetch-site");
return https_test_server_.GetURL(hostname, "/echoheader?sec-fetch-site");
}
const base::FilePath GetTestDataFilePath() {
return base::FilePath(FILE_PATH_LITERAL("chrome/test/data"));
}
void SetUpOnMainThread() override {
ExtensionBrowserTest::SetUpOnMainThread();
host_resolver()->AddRule("*", "127.0.0.1");
https_test_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
https_test_server_.AddDefaultHandlers(GetTestDataFilePath());
ASSERT_TRUE(https_test_server_.Start());
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile())
->set_client_cert_store_factory_for_testing(
base::BindRepeating(&CreateNullCertStore));
}
std::string ExecuteFetch(const Extension* extension, const GURL& url) {
content::DOMMessageQueue message_queue;
browsertest_util::ExecuteScriptInBackgroundPageNoWait(
profile(), extension->id(),
content::JsReplace("executeFetch($1);", url));
std::string json;
EXPECT_TRUE(message_queue.WaitForMessage(&json));
base::Optional<base::Value> value =
base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS);
std::string result;
if (!value) {
ADD_FAILURE() << "Received invalid response: " << json;
return std::string();
}
EXPECT_TRUE(value->GetAsString(&result));
std::string trimmed_result;
base::TrimWhitespaceASCII(result, base::TRIM_ALL, &trimmed_result);
return trimmed_result;
}
const Extension* LoadFetchExtension(const std::string& host) {
ExtensionTestMessageListener listener("ready", false);
TestExtensionDir test_dir;
constexpr char kManifestTemplate[] = R"(
{
"name": "XHR Test",
"manifest_version": 2,
"version": "0.1",
"background": {"scripts": ["background.js"]},
"permissions": ["%s"]
})";
test_dir.WriteManifest(base::StringPrintf(kManifestTemplate, host.c_str()));
constexpr char kBackgroundScriptFile[] = R"(
function executeFetch(url) {
console.warn('Fetching: ' + url);
fetch(url)
.then(response => response.text())
.then(text => domAutomationController.send(text))
.catch(err => domAutomationController.send('ERROR: ' + err));
}
chrome.test.sendMessage('ready');)";
test_dir.WriteFile(FILE_PATH_LITERAL("background.js"),
kBackgroundScriptFile);
const Extension* extension = LoadExtension(test_dir.UnpackedPath());
EXPECT_TRUE(listener.WaitUntilSatisfied());
return extension;
}
private:
net::EmbeddedTestServer https_test_server_;
base::test::ScopedFeatureList feature_list_;
};
// Test the response headers of fetch a HTTPS request in extension background
// page.
IN_PROC_BROWSER_TEST_F(BackgroundHeaderTest, SecFetchSite) {
const Extension* extension = LoadFetchExtension("<all_urls>");
ASSERT_TRUE(extension);
EXPECT_EQ("none", ExecuteFetch(extension, GetSecFetchUrl("example.com")));
}
// Test the response headers of fetch a HTTPS request with non-privileged host
// in extension background page.
IN_PROC_BROWSER_TEST_F(BackgroundHeaderTest,
SecFetchSiteFromPermissionBlockedHost) {
const Extension* extension = LoadFetchExtension("*://example.com:*/*");
ASSERT_TRUE(extension);
EXPECT_EQ("cross-site",
ExecuteFetch(extension, GetSecFetchUrl("example2.com")));
}
} // namespace extensions