blob: f30a152c168ab5c80a1114bc6da0fef67b3b4d37 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/functional/callback_helpers.h"
#include "base/path_service.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/features.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
namespace {
class CookieStoreSameSiteTest : public InProcessBrowserTest,
public ::testing::WithParamInterface<bool> {
protected:
CookieStoreSameSiteTest()
: https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {}
CookieStoreSameSiteTest(const CookieStoreSameSiteTest&) = delete;
CookieStoreSameSiteTest& operator=(const CookieStoreSameSiteTest&) = delete;
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
base::FilePath path;
base::PathService::Get(content::DIR_TEST_DATA, &path);
https_server_.ServeFilesFromDirectory(path);
https_server_.AddDefaultHandlers(GetChromeTestDataDir());
https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
ASSERT_TRUE(https_server_.Start());
// If SameSite access semantics is "legacy", add content settings to allow
// legacy access for all sites.
if (!HasNonLegacySameSiteAccessSemantics()) {
browser()
->profile()
->GetDefaultStoragePartition()
->GetNetworkContext()
->GetCookieManager(
cookie_manager_remote_.BindNewPipeAndPassReceiver());
cookie_manager_remote_->SetContentSettings(
ContentSettingsType::LEGACY_COOKIE_ACCESS,
{ContentSettingPatternSource(
ContentSettingsPattern::Wildcard(),
ContentSettingsPattern::Wildcard(),
base::Value(ContentSetting::CONTENT_SETTING_ALLOW),
content_settings::ProviderType::kNone, false /* incognito */)},
base::NullCallback());
cookie_manager_remote_.FlushForTesting();
}
}
void NavigateToPageWithFrame(const std::string& host) {
GURL main_url(https_server_.GetURL(host, "/iframe.html"));
ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
}
content::RenderFrameHost* GetFrame() {
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
}
std::string GetCookieSameSite(const std::string& cookie_name) {
std::string script = base::StringPrintf(R"(
(async () => {
const cookie = await cookieStore.get('%s');
return cookie ? cookie.sameSite : '';
}) ();
)",
cookie_name.c_str());
return content::EvalJs(GetFrame(), script).ExtractString();
}
protected:
bool HasNonLegacySameSiteAccessSemantics() { return GetParam(); }
mojo::Remote<network::mojom::CookieManager> cookie_manager_remote_;
net::test_server::EmbeddedTestServer https_server_;
};
IN_PROC_BROWSER_TEST_P(CookieStoreSameSiteTest,
CookieStoreUsesEffectiveSameSiteForUnspecifiedCookies) {
NavigateToPageWithFrame("a.test");
// Create unspecified sameSite cookie with document.cookie because CookieStore
// doesn't allow unspecified sameSite.
EXPECT_TRUE(content::ExecJs(GetFrame(),
"document.cookie='unspecified-cookie=value'"));
std::string sameSite = GetCookieSameSite("unspecified-cookie");
if (HasNonLegacySameSiteAccessSemantics()) {
EXPECT_EQ("lax", sameSite);
} else {
EXPECT_EQ("none", sameSite);
}
}
IN_PROC_BROWSER_TEST_P(CookieStoreSameSiteTest,
CookieStoreSameSiteDefaultsToStrict) {
NavigateToPageWithFrame("a.test");
// Create cookie with CookieStore with no sameSite.
EXPECT_TRUE(content::ExecJs(GetFrame(),
"cookieStore.set('default-cookie', 'value')"));
EXPECT_EQ("strict", GetCookieSameSite("default-cookie"));
}
IN_PROC_BROWSER_TEST_P(CookieStoreSameSiteTest,
CookieStoreUsesSpecifiedSameSite) {
NavigateToPageWithFrame("a.test");
// Create cookie with CookieStore with none sameSite. CookieStore defaults to
// Secure when written from a secure web origin, therefore allows for sameSite
// none.
EXPECT_TRUE(content::ExecJs(GetFrame(),
"cookieStore.set({name: 'none-cookie', value: "
"'value', sameSite: 'none'})"));
EXPECT_EQ("none", GetCookieSameSite("none-cookie"));
}
INSTANTIATE_TEST_SUITE_P(All, CookieStoreSameSiteTest, ::testing::Bool());
} // namespace