Commit dbdec091 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

PlzDedicatedWorker: Fix site-for-cookies.

When kPlzDedicatedWorker was enabled, requests for worker scripts made
in cross-origin iframes would incorrectly include same-site cookies.
This CL makes those requests use the site-for-cookies of the referring
frame instead.

If cross-site dedicated workers were supported, more work would be
needed to handle them correctly, but it doesn't look like that's the
case.

Bug: 1046435
Change-Id: I3dd90fd7d46af7f9cee840730a824b053cf137f1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2040067
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Cr-Commit-Position: refs/heads/master@{#741105}
parent 86a40c4a
...@@ -199,6 +199,7 @@ void DedicatedWorkerHost::StartScriptLoad( ...@@ -199,6 +199,7 @@ void DedicatedWorkerHost::StartScriptLoad(
WorkerScriptFetchInitiator::Start( WorkerScriptFetchInitiator::Start(
worker_process_host_->GetID(), script_url, creator_render_frame_host, worker_process_host_->GetID(), script_url, creator_render_frame_host,
nearest_ancestor_render_frame_host->ComputeSiteForCookies(),
request_initiator_origin, network_isolation_key_, credentials_mode, request_initiator_origin, network_isolation_key_, credentials_mode,
std::move(outside_fetch_client_settings_object), std::move(outside_fetch_client_settings_object),
blink::mojom::ResourceType::kWorker, blink::mojom::ResourceType::kWorker,
......
...@@ -309,9 +309,14 @@ SharedWorkerHost* SharedWorkerServiceImpl::CreateWorker( ...@@ -309,9 +309,14 @@ SharedWorkerHost* SharedWorkerServiceImpl::CreateWorker(
// Cloning before std::move() so that the object can be used in two functions. // Cloning before std::move() so that the object can be used in two functions.
auto cloned_outside_fetch_client_settings_object = auto cloned_outside_fetch_client_settings_object =
outside_fetch_client_settings_object.Clone(); outside_fetch_client_settings_object.Clone();
// TODO(mmenke): The site-for-cookies and NetworkIsolationKey arguments leak
// data across NetworkIsolationKeys and allow same-site cookies to be sent in
// cross-site contexts. Fix this.
WorkerScriptFetchInitiator::Start( WorkerScriptFetchInitiator::Start(
worker_process_host->GetID(), host->instance().url(), worker_process_host->GetID(), host->instance().url(),
creator_render_frame_host, host->instance().constructor_origin(), creator_render_frame_host,
net::SiteForCookies::FromUrl(host->instance().url()),
host->instance().constructor_origin(),
net::NetworkIsolationKey(origin, origin), credentials_mode, net::NetworkIsolationKey(origin, origin), credentials_mode,
std::move(outside_fetch_client_settings_object), std::move(outside_fetch_client_settings_object),
blink::mojom::ResourceType::kSharedWorker, service_worker_context_, blink::mojom::ResourceType::kSharedWorker, service_worker_context_,
......
...@@ -8,22 +8,27 @@ ...@@ -8,22 +8,27 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/system/sys_info.h" #include "base/system/sys_info.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h" #include "base/test/test_timeouts.h"
#include "base/thread_annotations.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/client_certificate_delegate.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h" #include "content/public/common/content_paths.h"
#include "content/public/test/browser_test_utils.h" #include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h" #include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "content/public/test/url_loader_interceptor.h" #include "content/public/test/url_loader_interceptor.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
...@@ -31,17 +36,30 @@ ...@@ -31,17 +36,30 @@
#include "content/test/content_browser_test_utils_internal.h" #include "content/test/content_browser_test_utils_internal.h"
#include "net/base/escape.h" #include "net/base/escape.h"
#include "net/base/filename_util.h" #include "net/base/filename_util.h"
#include "net/cookies/canonical_cookie.h"
#include "net/dns/mock_host_resolver.h" #include "net/dns/mock_host_resolver.h"
#include "net/ssl/ssl_server_config.h" #include "net/ssl/ssl_server_config.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/spawned_test_server/spawned_test_server.h" #include "net/test/spawned_test_server/spawned_test_server.h"
#include "net/test/test_data_directory.h" #include "net/test/test_data_directory.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "third_party/blink/public/common/features.h"
#include "url/gurl.h" #include "url/gurl.h"
namespace content { namespace content {
namespace { namespace {
const char kSameSiteCookie[] = "same-site-cookie=same-site-cookie-value";
// Used by both the embedded test server when a header specified by
// "/echoheader" is missing, and by the test fixture when there's no cookie
// present.
const char kNoCookie[] = "None";
bool SupportsSharedWorker() { bool SupportsSharedWorker() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// SharedWorkers are not enabled on Android. https://crbug.com/154571 // SharedWorkers are not enabled on Android. https://crbug.com/154571
...@@ -56,16 +74,33 @@ bool SupportsSharedWorker() { ...@@ -56,16 +74,33 @@ bool SupportsSharedWorker() {
} // namespace } // namespace
class WorkerTest : public ContentBrowserTest { // These tests are parameterized on whether kPlzDedicatedWorker is enabled.
class WorkerTest : public ContentBrowserTest,
public testing::WithParamInterface<bool> {
public: public:
WorkerTest() : select_certificate_count_(0) {} WorkerTest() : select_certificate_count_(0) {
if (GetParam()) {
feature_list_.InitAndEnableFeature(blink::features::kPlzDedicatedWorker);
} else {
feature_list_.InitAndDisableFeature(blink::features::kPlzDedicatedWorker);
}
}
void SetUpOnMainThread() override { void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1"); host_resolver()->AddRule("*", "127.0.0.1");
ShellContentBrowserClient::Get()->set_select_client_certificate_callback( ShellContentBrowserClient::Get()->set_select_client_certificate_callback(
base::BindOnce(&WorkerTest::OnSelectClientCertificate, base::BindOnce(&WorkerTest::OnSelectClientCertificate,
base::Unretained(this))); base::Unretained(this)));
ASSERT_TRUE(embedded_test_server()->Start()); ssl_server_.AddDefaultHandlers(GetTestDataFilePath());
ssl_server_.RegisterRequestHandler(base::BindRepeating(
&WorkerTest::MonitorRequestCookies, base::Unretained(this)));
ssl_server_.SetSSLConfig(
net::test_server::EmbeddedTestServer::CERT_TEST_NAMES);
ASSERT_TRUE(ssl_server_.Start());
}
void TearDownOnMainThread() override {
EXPECT_TRUE(ssl_server_.ShutdownAndWaitUntilComplete());
} }
int select_certificate_count() const { return select_certificate_count_; } int select_certificate_count() const { return select_certificate_count_; }
...@@ -80,7 +115,7 @@ class WorkerTest : public ContentBrowserTest { ...@@ -80,7 +115,7 @@ class WorkerTest : public ContentBrowserTest {
GURL GetTestURL(const std::string& test_case, const std::string& query) { GURL GetTestURL(const std::string& test_case, const std::string& query) {
std::string url_string = "/workers/" + test_case + "?" + query; std::string url_string = "/workers/" + test_case + "?" + query;
return embedded_test_server()->GetURL(url_string); return ssl_server_.GetURL("a.test", url_string);
} }
void RunTest(Shell* window, const GURL& url, bool expect_failure = false) { void RunTest(Shell* window, const GURL& url, bool expect_failure = false) {
...@@ -112,21 +147,106 @@ class WorkerTest : public ContentBrowserTest { ...@@ -112,21 +147,106 @@ class WorkerTest : public ContentBrowserTest {
runner->Run(); runner->Run();
} }
void SetSameSiteCookie(const std::string& host) {
StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
shell()->web_contents()->GetBrowserContext());
mojo::Remote<network::mojom::CookieManager> cookie_manager;
partition->GetNetworkContext()->GetCookieManager(
cookie_manager.BindNewPipeAndPassReceiver());
net::CookieOptions options;
options.set_same_site_cookie_context(
net::CookieOptions::SameSiteCookieContext::SAME_SITE_LAX);
std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create(
ssl_server_.GetURL(host, "/"),
std::string(kSameSiteCookie) + "; SameSite=Lax; Secure",
base::Time::Now(), base::nullopt /* server_time */);
base::RunLoop run_loop;
cookie_manager->SetCanonicalCookie(
*cookie, "https" /* source_scheme */, options,
base::BindLambdaForTesting(
[&](net::CanonicalCookie::CookieInclusionStatus set_cookie_result) {
EXPECT_TRUE(set_cookie_result.IsInclude());
run_loop.Quit();
}));
run_loop.Run();
}
// Returns the cookie received with the request for the specified path. If the
// path was requested but no cookie was received, return kNoCookie.
std::string GetReceivedCookie(const std::string& path) {
base::AutoLock auto_lock(path_cookie_map_lock_);
if (path_cookie_map_.find(path) == path_cookie_map_.end())
return "path not requested";
return path_cookie_map_[path];
}
void ClearReceivedCookies() {
base::AutoLock auto_lock(path_cookie_map_lock_);
path_cookie_map_.clear();
}
net::test_server::EmbeddedTestServer* ssl_server() { return &ssl_server_; }
private: private:
void OnSelectClientCertificate() { select_certificate_count_++; } void OnSelectClientCertificate() { select_certificate_count_++; }
std::unique_ptr<net::test_server::HttpResponse> MonitorRequestCookies(
const net::test_server::HttpRequest& request) {
// Ignore every host but "a.test", to help catch cases of sending requests
// to the wrong host.
auto host_header = request.headers.find("Host");
if (host_header == request.headers.end() ||
!base::StartsWith(host_header->second,
"a.test:", base::CompareCase::SENSITIVE)) {
return nullptr;
}
base::AutoLock auto_lock(path_cookie_map_lock_);
if (path_cookie_map_.find(request.relative_url) != path_cookie_map_.end()) {
path_cookie_map_[request.relative_url] = "path requested multiple times";
return nullptr;
}
auto cookie_header = request.headers.find("Cookie");
if (cookie_header == request.headers.end()) {
path_cookie_map_[request.relative_url] = kNoCookie;
return nullptr;
}
path_cookie_map_[request.relative_url] = cookie_header->second;
return nullptr;
}
// Mapping of paths requested from "a.test" to cookies they were requested
// with. Paths may only be requested once without clearing the map.
std::map<std::string, std::string> path_cookie_map_
GUARDED_BY(path_cookie_map_lock_);
// Lock that must be held while modifying |path_cookie_map_|, as it's used on
// both the test server's thread and the UI thread.
base::Lock path_cookie_map_lock_;
// The cookie tests require an SSL server, since SameSite None cookies can
// only be set on secure origins. Most other tests use this, too, to keep
// things simpler, though they could use an HTTP server instead.
net::test_server::EmbeddedTestServer ssl_server_{
net::test_server::EmbeddedTestServer::TYPE_HTTPS};
int select_certificate_count_; int select_certificate_count_;
base::test::ScopedFeatureList feature_list_;
}; };
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorker) { INSTANTIATE_TEST_SUITE_P(All, WorkerTest, testing::ValuesIn({false, true}));
IN_PROC_BROWSER_TEST_P(WorkerTest, SingleWorker) {
RunTest(GetTestURL("single_worker.html", std::string())); RunTest(GetTestURL("single_worker.html", std::string()));
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleWorkerFromFile) { IN_PROC_BROWSER_TEST_P(WorkerTest, SingleWorkerFromFile) {
RunTest(GetTestFileURL("single_worker.html")); RunTest(GetTestFileURL("single_worker.html"));
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, HttpPageCantCreateFileWorker) { IN_PROC_BROWSER_TEST_P(WorkerTest, HttpPageCantCreateFileWorker) {
GURL url = GetTestURL( GURL url = GetTestURL(
"single_worker.html", "single_worker.html",
"workerUrl=" + net::EscapeQueryParamValue( "workerUrl=" + net::EscapeQueryParamValue(
...@@ -134,11 +254,11 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, HttpPageCantCreateFileWorker) { ...@@ -134,11 +254,11 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, HttpPageCantCreateFileWorker) {
RunTest(url, /*expect_failure=*/true); RunTest(url, /*expect_failure=*/true);
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleWorkers) { IN_PROC_BROWSER_TEST_P(WorkerTest, MultipleWorkers) {
RunTest(GetTestURL("multi_worker.html", std::string())); RunTest(GetTestURL("multi_worker.html", std::string()));
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, SingleSharedWorker) { IN_PROC_BROWSER_TEST_P(WorkerTest, SingleSharedWorker) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
...@@ -146,7 +266,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SingleSharedWorker) { ...@@ -146,7 +266,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SingleSharedWorker) {
} }
// http://crbug.com/96435 // http://crbug.com/96435
IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleSharedWorkers) { IN_PROC_BROWSER_TEST_P(WorkerTest, MultipleSharedWorkers) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
...@@ -155,28 +275,28 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleSharedWorkers) { ...@@ -155,28 +275,28 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, MultipleSharedWorkers) {
// Incognito windows should not share workers with non-incognito windows // Incognito windows should not share workers with non-incognito windows
// http://crbug.com/30021 // http://crbug.com/30021
IN_PROC_BROWSER_TEST_F(WorkerTest, IncognitoSharedWorkers) { IN_PROC_BROWSER_TEST_P(WorkerTest, IncognitoSharedWorkers) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
// Load a non-incognito tab and have it create a shared worker // Load a non-incognito tab and have it create a shared worker
RunTest(embedded_test_server()->GetURL("/workers/incognito_worker.html")); RunTest(ssl_server()->GetURL("a.test", "/workers/incognito_worker.html"));
// Incognito worker should not share with non-incognito // Incognito worker should not share with non-incognito
RunTest(CreateOffTheRecordBrowser(), RunTest(CreateOffTheRecordBrowser(),
embedded_test_server()->GetURL("/workers/incognito_worker.html")); ssl_server()->GetURL("a.test", "/workers/incognito_worker.html"));
} }
// Make sure that auth dialog is displayed from worker context. // Make sure that auth dialog is displayed from worker context.
// http://crbug.com/33344 // http://crbug.com/33344
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerHttpAuth) { IN_PROC_BROWSER_TEST_P(WorkerTest, WorkerHttpAuth) {
GURL url = embedded_test_server()->GetURL("/workers/worker_auth.html"); GURL url = ssl_server()->GetURL("a.test", "/workers/worker_auth.html");
NavigateAndWaitForAuth(url); NavigateAndWaitForAuth(url);
} }
// Tests that TLS client auth prompts for normal workers's importScripts. // Tests that TLS client auth prompts for normal workers's importScripts.
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthImportScripts) { IN_PROC_BROWSER_TEST_P(WorkerTest, WorkerTlsClientAuthImportScripts) {
// Launch HTTPS server. // Launch HTTPS server.
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath()); https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
...@@ -194,7 +314,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthImportScripts) { ...@@ -194,7 +314,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthImportScripts) {
} }
// Tests that TLS client auth prompts for normal workers's fetch() call. // Tests that TLS client auth prompts for normal workers's fetch() call.
IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthFetch) { IN_PROC_BROWSER_TEST_P(WorkerTest, WorkerTlsClientAuthFetch) {
// Launch HTTPS server. // Launch HTTPS server.
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath()); https_server.ServeFilesFromSourceDirectory(GetTestDataFilePath());
...@@ -213,7 +333,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthFetch) { ...@@ -213,7 +333,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WorkerTlsClientAuthFetch) {
// Tests that TLS client auth does not prompt for a shared worker; shared // Tests that TLS client auth does not prompt for a shared worker; shared
// workers are not associated with a WebContents. // workers are not associated with a WebContents.
IN_PROC_BROWSER_TEST_F(WorkerTest, SharedWorkerTlsClientAuthImportScripts) { IN_PROC_BROWSER_TEST_P(WorkerTest, SharedWorkerTlsClientAuthImportScripts) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
...@@ -233,7 +353,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SharedWorkerTlsClientAuthImportScripts) { ...@@ -233,7 +353,7 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, SharedWorkerTlsClientAuthImportScripts) {
EXPECT_EQ(0, select_certificate_count()); EXPECT_EQ(0, select_certificate_count());
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, WebSocketSharedWorker) { IN_PROC_BROWSER_TEST_P(WorkerTest, WebSocketSharedWorker) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
...@@ -257,14 +377,14 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WebSocketSharedWorker) { ...@@ -257,14 +377,14 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, WebSocketSharedWorker) {
EXPECT_EQ(expected_title, final_title); EXPECT_EQ(expected_title, final_title);
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, PassMessagePortToSharedWorker) { IN_PROC_BROWSER_TEST_P(WorkerTest, PassMessagePortToSharedWorker) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
RunTest(GetTestURL("pass_messageport_to_sharedworker.html", "")); RunTest(GetTestURL("pass_messageport_to_sharedworker.html", ""));
} }
IN_PROC_BROWSER_TEST_F(WorkerTest, IN_PROC_BROWSER_TEST_P(WorkerTest,
PassMessagePortToSharedWorkerDontWaitForConnect) { PassMessagePortToSharedWorkerDontWaitForConnect) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
...@@ -274,18 +394,18 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, ...@@ -274,18 +394,18 @@ IN_PROC_BROWSER_TEST_F(WorkerTest,
} }
// Tests the value of |request_initiator| for shared worker resources. // Tests the value of |request_initiator| for shared worker resources.
IN_PROC_BROWSER_TEST_F(WorkerTest, VerifyInitiatorSharedWorker) { IN_PROC_BROWSER_TEST_P(WorkerTest, VerifyInitiatorSharedWorker) {
if (!SupportsSharedWorker()) if (!SupportsSharedWorker())
return; return;
const GURL start_url(embedded_test_server()->GetURL("/frame_tree/top.html")); const GURL start_url(ssl_server()->GetURL("a.test", "/frame_tree/top.html"));
EXPECT_TRUE(NavigateToURL(shell(), start_url)); EXPECT_TRUE(NavigateToURL(shell(), start_url));
// To make things tricky about |top_frame_origin|, this test navigates to // To make things tricky about |top_frame_origin|, this test navigates to
// a page on |embedded_test_server()| which has a cross-origin iframe that // a page on |ssl_server()| which has a cross-origin iframe that registers the
// registers the worker. // worker.
std::string cross_site_domain("cross-site.com"); std::string cross_site_domain("b.test");
const GURL test_url(embedded_test_server()->GetURL( const GURL test_url(ssl_server()->GetURL(
cross_site_domain, "/workers/simple_shared_worker.html")); cross_site_domain, "/workers/simple_shared_worker.html"));
// There are three requests to test: // There are three requests to test:
...@@ -293,11 +413,11 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, VerifyInitiatorSharedWorker) { ...@@ -293,11 +413,11 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, VerifyInitiatorSharedWorker) {
// 2) importScripts("empty.js") from the worker // 2) importScripts("empty.js") from the worker
// 3) fetch("empty.html") from the worker // 3) fetch("empty.html") from the worker
const GURL worker_url( const GURL worker_url(
embedded_test_server()->GetURL(cross_site_domain, "/workers/worker.js")); ssl_server()->GetURL(cross_site_domain, "/workers/worker.js"));
const GURL script_url( const GURL script_url(
embedded_test_server()->GetURL(cross_site_domain, "/workers/empty.js")); ssl_server()->GetURL(cross_site_domain, "/workers/empty.js"));
const GURL resource_url( const GURL resource_url(
embedded_test_server()->GetURL(cross_site_domain, "/workers/empty.html")); ssl_server()->GetURL(cross_site_domain, "/workers/empty.html"));
std::set<GURL> expected_request_urls = {worker_url, script_url, resource_url}; std::set<GURL> expected_request_urls = {worker_url, script_url, resource_url};
const url::Origin expected_origin = const url::Origin expected_origin =
...@@ -325,4 +445,128 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, VerifyInitiatorSharedWorker) { ...@@ -325,4 +445,128 @@ IN_PROC_BROWSER_TEST_F(WorkerTest, VerifyInitiatorSharedWorker) {
waiter.Run(); waiter.Run();
} }
// Test that an "a.test" worker sends "a.test" SameSite cookies, both when
// requesting the worker script and when fetching other resources.
IN_PROC_BROWSER_TEST_P(WorkerTest, WorkerSameSiteCookies1) {
SetSameSiteCookie("a.test");
ASSERT_TRUE(NavigateToURL(
shell(),
ssl_server()->GetURL(
"a.test",
"/workers/create_worker.html?worker_url=fetch_from_worker.js")));
EXPECT_EQ(kSameSiteCookie,
EvalJs(shell()->web_contents(),
"worker.postMessage({url: '/echoheader?Cookie'}); "
"waitForMessage();"));
EXPECT_EQ(kSameSiteCookie,
GetReceivedCookie(
"/workers/create_worker.html?worker_url=fetch_from_worker.js"));
EXPECT_EQ(kSameSiteCookie,
GetReceivedCookie("/workers/fetch_from_worker.js"));
EXPECT_EQ(kSameSiteCookie, GetReceivedCookie("/echoheader?Cookie"));
}
// Test that a "b.test" worker does not send "a.test" SameSite cookies when
// fetching resources.
IN_PROC_BROWSER_TEST_P(WorkerTest, WorkerSameSiteCookies2) {
SetSameSiteCookie("a.test");
ASSERT_TRUE(NavigateToURL(
shell(),
ssl_server()->GetURL(
"b.test",
"/workers/create_worker.html?worker_url=fetch_from_worker.js")));
EXPECT_EQ(kNoCookie,
EvalJs(shell()->web_contents(),
JsReplace("worker.postMessage({url: $1}); waitForMessage();",
ssl_server()
->GetURL("a.test", "/echoheader?Cookie")
.spec()
.c_str())));
EXPECT_EQ(kNoCookie, GetReceivedCookie("/echoheader?Cookie"));
}
// Test that an "a.test" iframe in a "b.test" frame does not send same-site
// cookies when requesting an "a.test" worker or when that worker requests
// "a.test" resources.
IN_PROC_BROWSER_TEST_P(WorkerTest,
CrossOriginIframeWorkerDoesNotSendSameSiteCookies1) {
SetSameSiteCookie("a.test");
ASSERT_TRUE(NavigateToURL(
shell(), ssl_server()->GetURL("b.test", "/workers/frame_factory.html")));
content::TestNavigationObserver navigation_observer(
shell()->web_contents(), /*number_of_navigations*/ 1);
const char kSubframeName[] = "foo";
EvalJsResult result = EvalJs(
shell()->web_contents()->GetMainFrame(),
JsReplace(
"createFrame($1, $2)",
ssl_server()
->GetURL(
"a.test",
"/workers/create_worker.html?worker_url=fetch_from_worker.js")
.spec()
.c_str(),
kSubframeName));
ASSERT_TRUE(result.error.empty());
navigation_observer.Wait();
RenderFrameHost* subframe_rfh = FrameMatchingPredicate(
shell()->web_contents(),
base::BindRepeating(&FrameMatchesName, kSubframeName));
ASSERT_TRUE(subframe_rfh);
EXPECT_EQ(kNoCookie,
EvalJs(subframe_rfh,
"worker.postMessage({url: '/echoheader?Cookie'}); "
"waitForMessage();"));
EXPECT_EQ(kNoCookie,
GetReceivedCookie(
"/workers/create_worker.html?worker_url=fetch_from_worker.js"));
EXPECT_EQ(kNoCookie, GetReceivedCookie("/workers/fetch_from_worker.js"));
EXPECT_EQ(kNoCookie, GetReceivedCookie("/echoheader?Cookie"));
}
// Test that an "b.test" iframe in a "a.test" frame does not send same-site
// cookies when its "b.test" worker requests "a.test" resources.
IN_PROC_BROWSER_TEST_P(WorkerTest,
CrossOriginIframeWorkerDoesNotSendSameSiteCookies2) {
SetSameSiteCookie("a.test");
ASSERT_TRUE(NavigateToURL(
shell(), ssl_server()->GetURL("a.test", "/workers/frame_factory.html")));
content::TestNavigationObserver navigation_observer(
shell()->web_contents(), /*number_of_navigations*/ 1);
const char kSubframeName[] = "foo";
EvalJsResult result = EvalJs(
shell()->web_contents()->GetMainFrame(),
JsReplace(
"createFrame($1, $2)",
ssl_server()
->GetURL(
"b.test",
"/workers/create_worker.html?worker_url=fetch_from_worker.js")
.spec()
.c_str(),
kSubframeName));
ASSERT_TRUE(result.error.empty());
navigation_observer.Wait();
RenderFrameHost* subframe_rfh = FrameMatchingPredicate(
shell()->web_contents(),
base::BindRepeating(&FrameMatchesName, kSubframeName));
ASSERT_TRUE(subframe_rfh);
EXPECT_EQ(kNoCookie,
EvalJs(subframe_rfh,
JsReplace("worker.postMessage({url: $1}); waitForMessage();",
ssl_server()
->GetURL("a.test", "/echoheader?Cookie")
.spec()
.c_str())));
EXPECT_EQ(kNoCookie, GetReceivedCookie("/echoheader?Cookie"));
}
} // namespace content } // namespace content
...@@ -60,6 +60,7 @@ void WorkerScriptFetchInitiator::Start( ...@@ -60,6 +60,7 @@ void WorkerScriptFetchInitiator::Start(
int worker_process_id, int worker_process_id,
const GURL& script_url, const GURL& script_url,
RenderFrameHost* creator_render_frame_host, RenderFrameHost* creator_render_frame_host,
const net::SiteForCookies& site_for_cookies,
const url::Origin& request_initiator, const url::Origin& request_initiator,
const net::NetworkIsolationKey& trusted_network_isolation_key, const net::NetworkIsolationKey& trusted_network_isolation_key,
network::mojom::CredentialsMode credentials_mode, network::mojom::CredentialsMode credentials_mode,
...@@ -122,7 +123,7 @@ void WorkerScriptFetchInitiator::Start( ...@@ -122,7 +123,7 @@ void WorkerScriptFetchInitiator::Start(
resource_request = std::make_unique<network::ResourceRequest>(); resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url = script_url; resource_request->url = script_url;
resource_request->site_for_cookies = net::SiteForCookies::FromUrl(script_url); resource_request->site_for_cookies = site_for_cookies;
resource_request->request_initiator = request_initiator; resource_request->request_initiator = request_initiator;
resource_request->referrer = sanitized_referrer.url, resource_request->referrer = sanitized_referrer.url,
resource_request->referrer_policy = Referrer::ReferrerPolicyForUrlRequest( resource_request->referrer_policy = Referrer::ReferrerPolicyForUrlRequest(
......
...@@ -26,6 +26,10 @@ namespace blink { ...@@ -26,6 +26,10 @@ namespace blink {
class PendingURLLoaderFactoryBundle; class PendingURLLoaderFactoryBundle;
} // namespace blink } // namespace blink
namespace net {
class SiteForCookies;
} // namespace net
namespace network { namespace network {
class SharedURLLoaderFactory; class SharedURLLoaderFactory;
} // namespace network } // namespace network
...@@ -61,6 +65,7 @@ class WorkerScriptFetchInitiator { ...@@ -61,6 +65,7 @@ class WorkerScriptFetchInitiator {
int worker_process_id, int worker_process_id,
const GURL& script_url, const GURL& script_url,
RenderFrameHost* creator_render_frame_host, RenderFrameHost* creator_render_frame_host,
const net::SiteForCookies& site_for_cookies,
const url::Origin& request_initiator, const url::Origin& request_initiator,
const net::NetworkIsolationKey& trusted_network_isolation_key, const net::NetworkIsolationKey& trusted_network_isolation_key,
network::mojom::CredentialsMode credentials_mode, network::mojom::CredentialsMode credentials_mode,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment