| // Copyright 2012 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/browsing_data/content/browsing_data_helper.h" |
| |
| #include "components/browsing_data/content/browsing_data_model.h" |
| #include "components/content_settings/core/common/content_settings_pattern.h" |
| #include "content/public/browser/browsing_data_filter_builder.h" |
| #include "content/public/common/url_constants.h" |
| #include "content/public/test/browser_task_environment.h" |
| #include "content/public/test/test_browser_context.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/blink/public/common/storage_key/storage_key.h" |
| #include "url/gurl.h" |
| #include "url/url_constants.h" |
| |
| namespace browsing_data { |
| namespace { |
| |
| class BrowsingDataHelperTest : public testing::Test { |
| public: |
| BrowsingDataHelperTest() = default; |
| |
| BrowsingDataHelperTest(const BrowsingDataHelperTest&) = delete; |
| BrowsingDataHelperTest& operator=(const BrowsingDataHelperTest&) = delete; |
| |
| ~BrowsingDataHelperTest() override {} |
| |
| bool IsWebScheme(const std::string& scheme) { |
| GURL test(scheme + "://example.com"); |
| return (HasWebScheme(test) && browsing_data::IsWebScheme(scheme)); |
| } |
| |
| content::BrowserTaskEnvironment task_environment_; |
| content::TestBrowserContext browser_context_; |
| }; |
| |
| TEST_F(BrowsingDataHelperTest, WebStorageSchemesAreWebSchemes) { |
| EXPECT_TRUE(IsWebScheme(url::kHttpScheme)); |
| EXPECT_TRUE(IsWebScheme(url::kHttpsScheme)); |
| EXPECT_TRUE(IsWebScheme(url::kFileScheme)); |
| EXPECT_TRUE(IsWebScheme(url::kFtpScheme)); |
| EXPECT_TRUE(IsWebScheme(url::kWsScheme)); |
| EXPECT_TRUE(IsWebScheme(url::kWssScheme)); |
| } |
| |
| TEST_F(BrowsingDataHelperTest, ChromeSchemesAreNotWebSchemes) { |
| EXPECT_FALSE(IsWebScheme(url::kAboutScheme)); |
| EXPECT_FALSE(IsWebScheme(content::kChromeDevToolsScheme)); |
| EXPECT_FALSE(IsWebScheme(content::kChromeUIScheme)); |
| EXPECT_FALSE(IsWebScheme(url::kJavaScriptScheme)); |
| EXPECT_FALSE(IsWebScheme(url::kMailToScheme)); |
| EXPECT_FALSE(IsWebScheme(content::kViewSourceScheme)); |
| } |
| |
| TEST_F(BrowsingDataHelperTest, SchemesThatCantStoreDataDontMatchAnything) { |
| EXPECT_FALSE(IsWebScheme(url::kDataScheme)); |
| EXPECT_FALSE(IsWebScheme("feed")); |
| EXPECT_FALSE(IsWebScheme(url::kBlobScheme)); |
| EXPECT_FALSE(IsWebScheme(url::kFileSystemScheme)); |
| EXPECT_FALSE(IsWebScheme("invalid-scheme-i-just-made-up")); |
| } |
| |
| TEST_F(BrowsingDataHelperTest, CreateWebsiteSettingsFilter) { |
| // A filter builder in "preserve" mode with no rules matches everything for |
| // deletion, and should result in a null filter. |
| std::unique_ptr<content::BrowsingDataFilterBuilder> filter_builder = |
| content::BrowsingDataFilterBuilder::Create( |
| content::BrowsingDataFilterBuilder::Mode::kPreserve); |
| EXPECT_TRUE(CreateWebsiteSettingsFilter(filter_builder.get()).is_null()); |
| |
| // A filter builder in "delete" mode with no rules should not result in a |
| // null filter, as it matches nothing. |
| filter_builder = content::BrowsingDataFilterBuilder::Create( |
| content::BrowsingDataFilterBuilder::Mode::kDelete); |
| EXPECT_FALSE(CreateWebsiteSettingsFilter(filter_builder.get()).is_null()); |
| |
| // Test "preserve" mode. |
| filter_builder = content::BrowsingDataFilterBuilder::Create( |
| content::BrowsingDataFilterBuilder::Mode::kPreserve); |
| filter_builder->AddOrigin(url::Origin::Create(GURL("https://google.com"))); |
| auto preserve_predicate = CreateWebsiteSettingsFilter(filter_builder.get()); |
| EXPECT_FALSE(preserve_predicate.is_null()); |
| |
| // The wildcard pattern should be ignored. |
| EXPECT_FALSE(preserve_predicate.Run(ContentSettingsPattern::Wildcard(), |
| ContentSettingsPattern::Wildcard())); |
| |
| // A non-wildcard pattern for an origin added to the filter should not match, |
| // as it is preserved. |
| EXPECT_FALSE(preserve_predicate.Run( |
| ContentSettingsPattern::FromString("[*.]google.com"), |
| ContentSettingsPattern::Wildcard())); |
| |
| // A non-wildcard pattern for an origin not in the filter should match, as it |
| // should be deleted. |
| EXPECT_TRUE(preserve_predicate.Run( |
| ContentSettingsPattern::FromString("[*.]example.com"), |
| ContentSettingsPattern::Wildcard())); |
| |
| // Test "delete" mode. |
| filter_builder = content::BrowsingDataFilterBuilder::Create( |
| content::BrowsingDataFilterBuilder::Mode::kDelete); |
| filter_builder->AddOrigin(url::Origin::Create(GURL("https://google.com"))); |
| auto delete_predicate = CreateWebsiteSettingsFilter(filter_builder.get()); |
| EXPECT_FALSE(delete_predicate.is_null()); |
| |
| // The wildcard pattern should be ignored. |
| EXPECT_FALSE(delete_predicate.Run(ContentSettingsPattern::Wildcard(), |
| ContentSettingsPattern::Wildcard())); |
| |
| // A non-wildcard pattern for an origin added to the filter should match. |
| EXPECT_TRUE( |
| delete_predicate.Run(ContentSettingsPattern::FromString("[*.]google.com"), |
| ContentSettingsPattern::Wildcard())); |
| |
| // A non-wildcard pattern for an origin not in the filter should not match. |
| EXPECT_FALSE(delete_predicate.Run( |
| ContentSettingsPattern::FromString("[*.]example.com"), |
| ContentSettingsPattern::Wildcard())); |
| } |
| |
| TEST_F(BrowsingDataHelperTest, GetUniqueThirdPartyCookiesHostCount) { |
| std::unique_ptr<BrowsingDataModel> browsing_data_model = |
| BrowsingDataModel::BuildEmpty( |
| browser_context_.GetDefaultStoragePartition(), /*delegate=*/nullptr); |
| |
| // 1. |
| auto google_url = GURL("http://google.com"); |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty(url::Origin::Create(google_url)), |
| BrowsingDataModel::StorageType::kLocalStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // Should be consolidated in first entry. |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty(url::Origin::Create(google_url)), |
| BrowsingDataModel::StorageType::kSharedStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // 2. Subdomains should be treated separately. |
| auto google_subdomain_url = GURL("http://maps.google.com"); |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty( |
| url::Origin::Create(google_subdomain_url)), |
| BrowsingDataModel::StorageType::kQuotaStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // 3. |
| auto localhost_url = GURL("http://localhost"); |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty(url::Origin::Create(localhost_url)), |
| BrowsingDataModel::StorageType::kQuotaStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // 4. |
| auto localhost_ip_url = GURL("http://127.0.0.1"); |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty( |
| url::Origin::Create(localhost_ip_url)), |
| BrowsingDataModel::StorageType::kLocalStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // 5. |
| auto example_url = GURL("http://example.com"); |
| auto example_origin = url::Origin::Create(example_url); |
| // Should be counted once in the unique hosts. |
| browsing_data_model->AddBrowsingData( |
| example_origin, BrowsingDataModel::StorageType::kTrustTokens, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // 6. |
| auto ip_url = GURL("http://192.168.1.1"); |
| browsing_data_model->AddBrowsingData( |
| blink::StorageKey::CreateFirstParty(url::Origin::Create(ip_url)), |
| BrowsingDataModel::StorageType::kLocalStorage, |
| /*storage_size=*/0, |
| /*cookie_count=*/0); |
| |
| // When `google_url` is the top frame unique third-party count should sites |
| // other than google URLs (out of 6 entries should be 4). |
| int unique_site_count = |
| GetUniqueThirdPartyCookiesHostCount(google_url, *browsing_data_model); |
| EXPECT_EQ(3, unique_site_count); |
| |
| // When `google_subdomain_url` is the top frame unique third-party count |
| // should sites other than google URLs (out of 6 entries should be 4). |
| unique_site_count = GetUniqueThirdPartyCookiesHostCount(google_subdomain_url, |
| *browsing_data_model); |
| EXPECT_EQ(3, unique_site_count); |
| |
| // When `ip_url` is the top frame this tests empty top frame domain with other |
| // sites. Subdomains are counted separately because they're different hosts |
| // (out of 6 entries should be 5). |
| unique_site_count = |
| GetUniqueThirdPartyCookiesHostCount(ip_url, *browsing_data_model); |
| EXPECT_EQ(4, unique_site_count); |
| } |
| |
| TEST_F(BrowsingDataHelperTest, ABAEmbedCookies) { |
| std::unique_ptr<BrowsingDataModel> browsing_data_model = |
| BrowsingDataModel::BuildEmpty( |
| browser_context_.GetDefaultStoragePartition(), /*delegate=*/nullptr); |
| |
| // 1P cookies accessed in contexts with a cross-site ancestor (aka ABA embeds) |
| // should also be counted as third-party cookies. |
| browsing_data_model->AddBrowsingData( |
| *net::CanonicalCookie::CreateForTesting( |
| GURL("https://example.com/"), "abc=123; SameSite=None; Secure", |
| base::Time::Now(), |
| /*server_time=*/std::nullopt, |
| /*cookie_partition_key=*/std::nullopt, net::CookieSourceType::kOther), |
| BrowsingDataModel::StorageType::kCookie, |
| /*storage_size=*/0, |
| /*cookie_count=*/1, |
| /*blocked_third_party=*/true); |
| |
| EXPECT_EQ(1, GetUniqueThirdPartyCookiesHostCount(GURL("https://example.com/"), |
| *browsing_data_model)); |
| } |
| |
| } // namespace |
| } // namespace browsing_data |