blob: 5855d0f2efcbb3c15a5ebc17aff768d759df75e2 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/tpcd/support/validity_service.h"
#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tpcd/support/top_level_trial_service.h"
#include "chrome/browser/tpcd/support/top_level_trial_service_factory.h"
#include "chrome/browser/tpcd/support/tpcd_support_service.h"
#include "chrome/browser/tpcd/support/tpcd_support_service_factory.h"
#include "chrome/browser/tpcd/support/trial_test_utils.h"
#include "chrome/test/base/chrome_test_utils.h"
#include "chrome/test/base/platform_browser_test.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/features.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/tracking_protection_prefs.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/url_loader_interceptor.h"
#include "net/base/features.h"
#include "net/cookies/cookie_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
using content::URLLoaderInterceptor;
using content::WebContents;
namespace tpcd::trial {
class ValidityServiceBrowserTestBase : public PlatformBrowserTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII("origin-trial-public-key",
kTestTokenPublicKey);
command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
}
void SetUp() override {
features_.InitWithFeaturesAndParameters(
{{net::features::kTpcdTrialSettings, {}},
{content_settings::features::kTrackingProtection3pcd, {}}},
{});
PlatformBrowserTest::SetUp();
}
void SetUpOnMainThread() override {
ASSERT_TRUE(embedded_test_server()->Start());
host_resolver()->AddRule("*", "127.0.0.1");
https_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
https_server_->AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("chrome/test/data/")));
ASSERT_TRUE(https_server_->Start());
// We use a URLLoaderInterceptor in tests that actually use an origin trial
// token, rather than the EmbeddedTestServer, since the origin trial token
// in the response is associated with a fixed origin, whereas
// EmbeddedTestServer serves content on a random port.
url_loader_interceptor_ =
std::make_unique<URLLoaderInterceptor>(base::BindLambdaForTesting(
[this](URLLoaderInterceptor::RequestParams* params) {
return OnRequest(params);
}));
GetPrefs()->SetBoolean(prefs::kTrackingProtection3pcdEnabled, true);
}
void TearDownOnMainThread() override {
https_server_.reset();
url_loader_interceptor_.reset();
PlatformBrowserTest::TearDownOnMainThread();
}
protected:
content::WebContents* GetActiveWebContents() {
return chrome_test_utils::GetActiveWebContents(this);
}
Profile* GetProfile() {
return Profile::FromBrowserContext(
GetActiveWebContents()->GetBrowserContext());
}
PrefService* GetPrefs() {
return user_prefs::UserPrefs::Get(
GetActiveWebContents()->GetBrowserContext());
}
TopLevelTrialService* GetTopLevelTrialService() {
return TopLevelTrialServiceFactory::GetForProfile(GetProfile());
}
TpcdTrialService* GetTpcdTrialService() {
return TpcdTrialServiceFactory::GetForProfile(GetProfile());
}
ValidityService* GetValidityService() {
return ValidityService::FromWebContents(GetActiveWebContents());
}
content::RenderFrameHost* GetIFrame() {
content::WebContents* web_contents = GetActiveWebContents();
return ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0);
}
[[nodiscard]] bool NavigateIFrameAndWaitForCookieAccess(GURL iframe_url) {
content::WebContents* web_contents = GetActiveWebContents();
URLCookieAccessObserver observer(web_contents, iframe_url,
CookieOperation::kChange);
const std::string kIframeId = "test"; // defined in iframe_blank.html
bool success =
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url);
if (success) {
observer.Wait();
}
return success;
}
void NavigateToPageWithIFrame(const std::string& iframe_host,
const std::string& embedding_host) {
content::WebContents* web_contents = GetActiveWebContents();
// Navigate the top-level page to |embedding_site|.
GURL embedding_site =
https_server_->GetURL(embedding_host, "/iframe_blank.html");
ASSERT_TRUE(content::NavigateToURL(web_contents, embedding_site));
// Open an |iframe_host| iframe.
GURL iframe_url = https_server_->GetURL(iframe_host, "/title1.html");
const std::string kIframeId = "test"; // defined in iframe_blank.html
ASSERT_TRUE(
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url));
}
// Most other cookie-related content settings compare their primary patterns'
// against embedded/requesting sites and their secondary patterns'
// against top-level sites. This convenience function helps avoid confusion
// since |TOP_LEVEL_TPCD_TRIAL| content settings only use a primary pattern
// which is compared against top-level sites.
ContentSettingChangeObserver CreateTopLevelTrialSettingsObserver(GURL url) {
return ContentSettingChangeObserver(
GetProfile(), url, GURL(), ContentSettingsType::TOP_LEVEL_TPCD_TRIAL);
}
// Creates a |TPCD_TRIAL| content setting allowing
// |embedded_url| to access third-party cookies under |top_level_url|
// without actually providing an origin trial token and enabling the
// associated origin trial.
void CreateAndVerifyThirdPartyTrialGrant(const GURL& embedded_url,
const GURL& top_level_url,
bool match_subdomains) {
// Create the content setting.
ContentSettingChangeObserver setting_observer(
GetActiveWebContents()->GetBrowserContext(), embedded_url,
top_level_url, ContentSettingsType::TPCD_TRIAL);
GetTpcdTrialService()->Update3pcdTrialSettingsForTesting(
OriginTrialStatusChangeDetails(url::Origin::Create(embedded_url),
top_level_url.spec(), match_subdomains,
/*enabled=*/true,
/*source_id=*/std::nullopt));
setting_observer.Wait();
// Verify that a |TPCD_TRIAL| content setting now allows |embedded_url|
// access to cookies as a third-party when embedded by |top_level_url|.
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
ASSERT_EQ(settings->GetCookieSetting(embedded_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
ASSERT_EQ(settings->GetThirdPartyCookieAllowMechanism(
embedded_url, net::SiteForCookies::FromUrl(top_level_url),
top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowBy3PCD);
}
// Creates a |TOP_LEVEL_TPCD_TRIAL| content setting allowing sites embedded
// under |top_level_url| to access third-party cookies without actually
// providing an origin trial token and enabling the associated origin trial.
void CreateAndVerifyFirstPartyTrialGrant(const GURL& top_level_url,
bool match_subdomains) {
// Create the content setting.
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(top_level_url);
GetTopLevelTrialService()->UpdateTopLevelTrialSettingsForTesting(
url::Origin::Create(top_level_url), match_subdomains, /*enabled=*/true);
setting_observer.Wait();
// Verify that a |TOP_LEVEL_TPCD_TRIAL| content setting now allows all sites
// access to cookies as a third-party when embedded by |top_level_url|.
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
ASSERT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
ASSERT_EQ(settings->GetThirdPartyCookieAllowMechanism(
GURL(), net::SiteForCookies(), top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowByTopLevel3PCD);
}
virtual bool OnRequest(content::URLLoaderInterceptor::RequestParams* params) {
return false;
}
base::test::ScopedFeatureList features_;
std::unique_ptr<net::EmbeddedTestServer> https_server_;
std::unique_ptr<URLLoaderInterceptor> url_loader_interceptor_;
const GURL kTrialEnabledSite{base::StrCat({"https://", kTrialEnabledDomain})};
const GURL kTrialEnabledSiteSubdomain{
base::StrCat({"https://", kTrialEnabledSubdomain})};
};
class ValidityService3pTrialBrowserTest
: public ValidityServiceBrowserTestBase {
void SetUp() override {
features_.InitWithFeaturesAndParameters(
{{net::features::kTpcdTrialSettings, {}},
{content_settings::features::kTrackingProtection3pcd, {}}},
{});
PlatformBrowserTest::SetUp();
}
bool OnRequest(
content::URLLoaderInterceptor::RequestParams* params) override {
std::string host = params->url_request.url.host();
std::string path = params->url_request.url.path().substr(1);
if (host != kTrialEnabledDomain || path != kTrialEnabledIframePath) {
return false;
}
URLLoaderInterceptor::WriteResponse(
base::StrCat({"HTTP/1.1 200 OK\n", "Content-type: text/html\n",
"Origin-Trial: ", kTrialToken, "\n", "\n"}),
"", params->client.get());
return true;
}
};
IN_PROC_BROWSER_TEST_F(ValidityService3pTrialBrowserTest,
RemovesInvalidSettingOnJsCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame(kTrialEnabledSite.host(), "a.test");
// Create a |TPCD_TRIAL| setting for |iframe_url| under |top_level_url|
// without actually enabling the "Tpcd" trial.
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
CreateAndVerifyThirdPartyTrialGrant(iframe_url, top_level_url,
/*match_subdomains=*/false);
// Access cookies via javascript in the iframe, which should cause the setting
// to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify |iframe_url| no longer has third-party cookie access when
// embedded by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService3pTrialBrowserTest,
RemoveInvalidSubdomainMatchingSettingOnJsCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame(kTrialEnabledSiteSubdomain.host(), "a.test");
// Create a subdomain-matching |TPCD_TRIAL| setting for |grant_url|
// (which |iframe_url| is a subdomain of) under |top_level_url| without
// actually enabling the "Tpcd" trial.
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
GURL grant_url = GURL(base::StrCat(
{"https://", kTrialEnabledSite.host(), ":", iframe_url.port()}));
CreateAndVerifyThirdPartyTrialGrant(grant_url, top_level_url,
/*match_subdomains=*/true);
// Access cookies via javascript in the iframe, which should cause the setting
// to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify |iframe_url| and |grant_url| no longer have
// third-party cookie access when embedded by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(grant_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService3pTrialBrowserTest,
RemoveInvalidSettingOnNavigationCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
// Navigate the top-level page to |top_level_url|.
GURL top_level_url = https_server_->GetURL("a.test", "/iframe_blank.html");
ASSERT_TRUE(content::NavigateToURL(web_contents, top_level_url));
// Create a |TPCD_TRIAL| setting for |iframe_url| under |top_level_url|
// without actually enabling the "Tpcd" trial.
GURL iframe_url = https_server_->GetURL(
kTrialEnabledSite.host(), "/set-cookie?name=value;Secure;SameSite=None");
CreateAndVerifyThirdPartyTrialGrant(iframe_url, top_level_url,
/*match_subdomains=*/false);
// Navigate the iframe to |iframe_url| to set a cookie via a network response,
// which should cause the setting to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
ASSERT_TRUE(NavigateIFrameAndWaitForCookieAccess(iframe_url));
setting_observer.Wait();
// Verify |iframe_url| no longer has third-party cookie access when embedded
// by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(
ValidityService3pTrialBrowserTest,
RemoveInvalidSubdomainMatchingSettingOnNavigationCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
// Navigate the top-level page to |top_level_url|.
GURL top_level_url = https_server_->GetURL("a.test", "/iframe_blank.html");
ASSERT_TRUE(content::NavigateToURL(web_contents, top_level_url));
// Create a subdomain-matching |TPCD_TRIAL| setting for |grant_url|
// (which |iframe_url| is a subdomain of) under |top_level_url| without
// actually enabling the "Tpcd" trial.
GURL iframe_url =
https_server_->GetURL(kTrialEnabledSiteSubdomain.host(),
"/set-cookie?name=value;Secure;SameSite=None");
GURL grant_url = GURL(base::StrCat(
{"https://", kTrialEnabledSite.host(), ":", iframe_url.port()}));
CreateAndVerifyThirdPartyTrialGrant(grant_url, top_level_url,
/*match_subdomains=*/true);
// Navigate the iframe to |iframe_url| to set a cookie via a network response,
// which should cause the setting to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
ASSERT_TRUE(NavigateIFrameAndWaitForCookieAccess(iframe_url));
setting_observer.Wait();
// Verify |iframe_url| and |grant_url| no longer have
// third-party cookie access when embedded by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(grant_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService3pTrialBrowserTest,
RemoveAllSettingsCreatedUsingAffectedToken) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame(kTrialEnabledSite.host(), "a.test");
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
// Create |TPCD_TRIAL| settings for |iframe_url| under various top-level
// sites.
CreateAndVerifyThirdPartyTrialGrant(iframe_url, top_level_url,
/*match_subdomains=*/false);
CreateAndVerifyThirdPartyTrialGrant(iframe_url, GURL("https://b.test"),
/*match_subdomains=*/false);
CreateAndVerifyThirdPartyTrialGrant(iframe_url, GURL("https://c.test"),
/*match_subdomains=*/false);
// Note: this setting matches subdomains, while the others don't, meaning it
// would've been created using a different origin trial token.
GURL other_top_level_url("https://other-top-level.test");
CreateAndVerifyThirdPartyTrialGrant(iframe_url, other_top_level_url,
/*match_subdomains=*/true);
// Also, create a |TPCD_TRIAL| setting for |other_embedded_url| under
// |top_level_url|.
GURL other_embedded_url("https://another-embedded-site.test");
CreateAndVerifyThirdPartyTrialGrant(other_embedded_url, top_level_url,
/*match_subdomains=*/false);
// Access cookies via javascript in the iframe, which should cause the setting
// to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify |TPCD_TRIAL| content settings with the same primary pattern as the
// setting that allowed 3PC access in the iframe have been removed.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
GURL("https://b.test"), {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
GURL("https://c.test"), {}, nullptr),
CONTENT_SETTING_BLOCK);
// Note: since the setting allowing |iframe_url| to access 3PC under
// |other_top_level_url| matches subdomains and the setting that
// allowed access in the iframe context did not, the setting for 3PC access
// under |other_top_level_url| must've been created with another
// token and should NOT be removed.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
other_top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings->GetThirdPartyCookieAllowMechanism(
iframe_url, net::SiteForCookies::FromUrl(other_top_level_url),
other_top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowBy3PCD);
// Verify |other_embedded_url| still has a |TPCD_TRIAL| grant for third-party
// cookie access when embedded by |top_level_url|.
EXPECT_EQ(
settings->GetCookieSetting(other_embedded_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings->GetThirdPartyCookieAllowMechanism(
other_embedded_url, net::SiteForCookies::FromUrl(top_level_url),
top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowBy3PCD);
}
IN_PROC_BROWSER_TEST_F(
ValidityService3pTrialBrowserTest,
RemoveAllSettingsCreatedUsingAffectedSubdomainMatchingToken) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame(kTrialEnabledSite.host(), "a.test");
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
// Create |TPCD_TRIAL| settings for |iframe_url| (and subdomains of it) under
// various top-level sites.
CreateAndVerifyThirdPartyTrialGrant(iframe_url, top_level_url,
/*match_subdomains=*/true);
CreateAndVerifyThirdPartyTrialGrant(iframe_url, GURL("https://b.test"),
/*match_subdomains=*/true);
CreateAndVerifyThirdPartyTrialGrant(iframe_url, GURL("https://c.test"),
/*match_subdomains=*/true);
// Note: this setting does NOT match subdomains, while the others do, meaning
// it would've been created using a different origin trial token.
GURL other_top_level_url("https://other-top-level.test");
CreateAndVerifyThirdPartyTrialGrant(iframe_url, other_top_level_url,
/*match_subdomains=*/false);
// Also, create a |TPCD_TRIAL| setting for |other_embedded_url| under
// |top_level_url|.
GURL other_embedded_url("https://another-embedded-site.test");
CreateAndVerifyThirdPartyTrialGrant(other_embedded_url, top_level_url,
/*match_subdomains=*/true);
// Access cookies via javascript in the iframe, which should cause the setting
// to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify |TPCD_TRIAL| content settings with the same primary pattern as the
// setting that allowed 3PC access in the iframe have been removed.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
GURL("https://b.test"), {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
GURL("https://c.test"), {}, nullptr),
CONTENT_SETTING_BLOCK);
// Note: since the setting allowing |iframe_url| to access 3PC under
// |other_top_level_url| does NOT match subdomains and the setting
// that allowed access in the iframe context did, the setting for 3PC access
// under |other_top_level_url| must've been created with another
// token and should NOT be removed.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
other_top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings->GetThirdPartyCookieAllowMechanism(
iframe_url, net::SiteForCookies::FromUrl(other_top_level_url),
other_top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowBy3PCD);
// Verify |other_embedded_url| still has a |TPCD_TRIAL| grant for
// third-party cookie access when embedded by |top_level_url|.
EXPECT_EQ(
settings->GetCookieSetting(other_embedded_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings->GetThirdPartyCookieAllowMechanism(
other_embedded_url, net::SiteForCookies::FromUrl(top_level_url),
top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowBy3PCD);
}
IN_PROC_BROWSER_TEST_F(ValidityService3pTrialBrowserTest,
PreserveValidSettings) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
GURL top_level_url =
embedded_test_server()->GetURL("a.test", "/iframe_blank.html");
const std::string kIframeId = "test"; // defined in iframe_blank.html
// Navigate the top-level page to |top_level_url| and update it to have an
// |kTrialEnabledSite| iframe that returns the origin trial token in its HTTP
// response headers.
{
ASSERT_TRUE(content::NavigateToURL(web_contents, top_level_url));
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), kTrialEnabledSite, top_level_url,
ContentSettingsType::TPCD_TRIAL);
GURL iframe_url = GURL(kTrialEnabledSite.spec() + kTrialEnabledIframePath);
ASSERT_TRUE(
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url));
setting_observer.Wait();
}
// Write a third-party cookie from the |kTrialEnabledSite| iframe.
AccessCookieViaJsIn(web_contents, GetIFrame());
// Since we can't deterministically wait for the ValidityService to do nothing
// in response to a third-party cookie access permitted by a valid
// |TPCD_TRIAL| content setting, also trigger a cookie access for a different
// origin with an invalid setting, then after the invalid setting has been
// removed, check that the |kTrialEnabledSite| content setting still remains.
{
GURL iframe_url =
https_server_->GetURL("different-host.test", "/title1.html");
ASSERT_TRUE(
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url));
// Create a |TPCD_TRIAL| setting for |iframe_url| under |top_level_url|
// without actually enabling the "Tpcd" trial.
CreateAndVerifyThirdPartyTrialGrant(iframe_url, top_level_url,
/*match_subdomains=*/false);
// Access cookies via javascript in the iframe, which should cause the
// setting to be removed.
ContentSettingChangeObserver setting_observer(
web_contents->GetBrowserContext(), iframe_url, top_level_url,
ContentSettingsType::TPCD_TRIAL);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify |iframe_url| no longer has access to third-party cookies when
// embedded by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(iframe_url, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
// Verify |kTrialEnabledSite| still has access to third-party cookies when
// embedded by |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(kTrialEnabledSite, net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
}
class ValidityService1pTrialBrowserTest
: public ValidityServiceBrowserTestBase {
void SetUp() override {
features_.InitWithFeaturesAndParameters(
{{net::features::kTopLevelTpcdTrialSettings, {}},
{content_settings::features::kTrackingProtection3pcd, {}}},
{});
PlatformBrowserTest::SetUp();
}
bool OnRequest(
content::URLLoaderInterceptor::RequestParams* params) override {
std::string host = params->url_request.url.host();
std::string path = params->url_request.url.path().substr(1);
if (host != kTrialEnabledDomain || path != kTrialEnabledTopLevelPath) {
return false;
}
URLLoaderInterceptor::WriteResponse(
base::StrCat({"HTTP/1.1 200 OK\n", "Content-type: text/html\n",
"Origin-Trial: ", k1pDeprecationTrialToken, "\n", "\n"}),
("<html><head><title>Trial enabled page with iframe</title></head>"
"<body>"
"<iframe id='test'></iframe>"
"</body></html>"),
params->client.get());
return true;
}
};
IN_PROC_BROWSER_TEST_F(ValidityService1pTrialBrowserTest,
RemovesInvalidSettingOnJsCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame(kTrialEnabledSite.host(), "a.test");
// Create a |TOP_LEVEL_TPCD_TRIAL| setting for |top_level_url| without
// actually enabling the "TopLevelTpcd" trial.
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
CreateAndVerifyFirstPartyTrialGrant(top_level_url,
/*match_subdomains=*/false);
// Access third-party cookies via javascript in the iframe, which should cause
// the setting to be removed.
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(top_level_url);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify third-party cookie access is no longer permitted under
// |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService1pTrialBrowserTest,
RemoveInvalidSettingOnNavigationCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
// Navigate to |top_level_url|, which has a blank iframe.
GURL top_level_url =
https_server_->GetURL(kTrialEnabledSite.host(), "/iframe_blank.html");
ASSERT_TRUE(content::NavigateToURL(web_contents, top_level_url));
// Create a |TOP_LEVEL_TPCD_TRIAL| setting for |top_level_url| without
// actually enabling the "TopLevelTpcd" trial.
CreateAndVerifyFirstPartyTrialGrant(top_level_url,
/*match_subdomains=*/false);
// Navigate the iframe to |iframe_url| to set a cookie via a network response,
// which should cause the setting to be removed.
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(top_level_url);
GURL iframe_url = https_server_->GetURL(
"a.test", "/set-cookie?name=value;Secure;SameSite=None");
ASSERT_TRUE(NavigateIFrameAndWaitForCookieAccess(iframe_url));
setting_observer.Wait();
// Verify third-party cookie access is no longer permitted under
// |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService1pTrialBrowserTest,
RemoveInvalidSubdomainMatchingSettingOnCookieAccess) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
NavigateToPageWithIFrame("a.test", kTrialEnabledSiteSubdomain.host());
// Create a subdomain-matching |TOP_LEVEL_TPCD_TRIAL| setting for |grant_url|
// (which |top_level_url| is a subdomain of) without actually enabling the
// "TopLevelTpcd" trial.
GURL top_level_url =
web_contents->GetPrimaryMainFrame()->GetLastCommittedURL();
GURL iframe_url = GetIFrame()->GetLastCommittedURL();
GURL grant_url = GURL(base::StrCat(
{"https://", kTrialEnabledSite.host(), ":", top_level_url.port()}));
CreateAndVerifyFirstPartyTrialGrant(grant_url,
/*match_subdomains=*/true);
// Access cookies via javascript in the iframe, which should cause the setting
// to be removed.
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(top_level_url);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify third-party cookie access is no longer permitted under
// |top_level_url| or |grant_url|.
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(), grant_url,
{}, nullptr),
CONTENT_SETTING_BLOCK);
}
IN_PROC_BROWSER_TEST_F(ValidityService1pTrialBrowserTest,
PreserveValidSettings) {
content::WebContents* web_contents = GetActiveWebContents();
content_settings::CookieSettings* settings =
CookieSettingsFactory::GetForProfile(GetProfile()).get();
GURL top_level_url =
GURL(kTrialEnabledSite.spec() + kTrialEnabledTopLevelPath);
GURL iframe_url = https_server_->GetURL("a.test", "/title1.html");
const std::string kIframeId = "test";
// Navigate to a |top_level_url| page that returns its origin trial
// token in its HTTP response headers and has an iframe.
{
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(top_level_url);
ASSERT_TRUE(content::NavigateToURL(web_contents, top_level_url));
ASSERT_TRUE(
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url));
setting_observer.Wait();
// Verify third-party cookie access is now permitted under
// |top_level_url|.
ASSERT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
ASSERT_EQ(settings->GetThirdPartyCookieAllowMechanism(
GURL(), net::SiteForCookies(), top_level_url, {}, nullptr),
content_settings::CookieSettingsBase::
ThirdPartyCookieAllowMechanism::kAllowByTopLevel3PCD);
}
// Write a third-party cookie from the iframe.
AccessCookieViaJsIn(web_contents, GetIFrame());
// Since we can't deterministically wait for the ValidityService to do nothing
// in response to a third-party cookie access permitted by a valid
// |TOP_LEVEL_TPCD_TRIAL| content setting, navigate to a different top-level
// site (with an invalid setting) and trigger a third-party cookie access,
// then after the invalid setting has been removed, check that the
// |kTrialEnabledSite| content setting still remains.
{
GURL other_top_level_url =
https_server_->GetURL("different-host.test", "/iframe_blank.html");
ASSERT_TRUE(content::NavigateToURL(web_contents, other_top_level_url));
ASSERT_TRUE(
content::NavigateIframeToURL(web_contents, kIframeId, iframe_url));
// Create a |TOP_LEVEL_TPCD_TRIAL| setting for |other_top_level_url| without
// actually enabling the "TopLevelTpcd" trial.
CreateAndVerifyFirstPartyTrialGrant(other_top_level_url,
/*match_subdomains=*/false);
// Access cookies via javascript in the iframe, which should cause the
// setting to be removed.
ContentSettingChangeObserver setting_observer =
CreateTopLevelTrialSettingsObserver(other_top_level_url);
AccessCookieViaJsIn(web_contents, GetIFrame());
setting_observer.Wait();
// Verify third-party cookie access is no longer permitted under
// |other_top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
other_top_level_url, {}, nullptr),
CONTENT_SETTING_BLOCK);
}
// Verify third-party cookie access is still permitted under
// |top_level_url|.
EXPECT_EQ(settings->GetCookieSetting(GURL(), net::SiteForCookies(),
top_level_url, {}, nullptr),
CONTENT_SETTING_ALLOW);
HostContentSettingsMap* settings_map =
HostContentSettingsMapFactory::GetForProfile(GetProfile());
EXPECT_EQ(settings_map->GetContentSetting(
top_level_url, GURL(),
ContentSettingsType::TOP_LEVEL_TPCD_TRIAL, nullptr),
CONTENT_SETTING_ALLOW);
}
} // namespace tpcd::trial