1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <memory>
6 #include <string>
7 #include <utility>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/run_loop.h"
12 #include "base/test/bind_test_util.h"
13 #include "base/time/time.h"
14 #include "content/browser/browsing_data/browsing_data_test_utils.h"
15 #include "content/browser/browsing_data/same_site_data_remover_impl.h"
16 #include "content/public/browser/storage_partition.h"
17 #include "content/public/test/browser_task_environment.h"
18 #include "content/public/test/test_browser_context.h"
19 #include "content/public/test/test_storage_partition.h"
20 #include "net/cookies/cookie_monster.h"
21 #include "net/url_request/url_request_context.h"
22 #include "services/network/public/mojom/cookie_manager.mojom.h"
23 #include "storage/browser/test/mock_special_storage_policy.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using testing::IsEmpty;
28 using testing::SizeIs;
29 using testing::UnorderedElementsAre;
30
31 namespace content {
32
33 struct StoragePartitionSameSiteRemovalData {
34 uint32_t removal_mask = 0;
35 uint32_t quota_storage_removal_mask = 0;
36 StoragePartition::OriginMatcherFunction origin_matcher;
37 };
38
39 class SameSiteRemoverTestStoragePartition : public TestStoragePartition {
40 public:
SameSiteRemoverTestStoragePartition()41 SameSiteRemoverTestStoragePartition() {}
~SameSiteRemoverTestStoragePartition()42 ~SameSiteRemoverTestStoragePartition() override {}
43
ClearData(uint32_t removal_mask,uint32_t quota_storage_removal_mask,OriginMatcherFunction origin_matcher,network::mojom::CookieDeletionFilterPtr cookie_deletion_filter,bool perform_storage_cleanup,const base::Time begin,const base::Time end,base::OnceClosure callback)44 void ClearData(uint32_t removal_mask,
45 uint32_t quota_storage_removal_mask,
46 OriginMatcherFunction origin_matcher,
47 network::mojom::CookieDeletionFilterPtr cookie_deletion_filter,
48 bool perform_storage_cleanup,
49 const base::Time begin,
50 const base::Time end,
51 base::OnceClosure callback) override {
52 storage_partition_removal_data_.removal_mask = removal_mask;
53 storage_partition_removal_data_.quota_storage_removal_mask =
54 quota_storage_removal_mask;
55 storage_partition_removal_data_.origin_matcher = std::move(origin_matcher);
56 std::move(callback).Run();
57 }
58
GetStoragePartitionRemovalData()59 const StoragePartitionSameSiteRemovalData& GetStoragePartitionRemovalData() {
60 return storage_partition_removal_data_;
61 }
62
63 private:
64 StoragePartitionSameSiteRemovalData storage_partition_removal_data_;
65
66 DISALLOW_COPY_AND_ASSIGN(SameSiteRemoverTestStoragePartition);
67 };
68
69 class SameSiteDataRemoverImplTest : public testing::Test {
70 public:
SameSiteDataRemoverImplTest()71 SameSiteDataRemoverImplTest()
72 : browser_context_(std::make_unique<TestBrowserContext>()),
73 same_site_remover_(
74 std::make_unique<SameSiteDataRemoverImpl>(browser_context_.get())) {
75 }
76
TearDown()77 void TearDown() override { browser_context_.reset(); }
78
GetSameSiteDataRemoverImpl()79 SameSiteDataRemoverImpl* GetSameSiteDataRemoverImpl() {
80 return same_site_remover_.get();
81 }
82
GetBrowserContext()83 BrowserContext* GetBrowserContext() { return browser_context_.get(); }
84
DeleteSameSiteNoneCookies()85 void DeleteSameSiteNoneCookies() {
86 base::RunLoop run_loop;
87 GetSameSiteDataRemoverImpl()->DeleteSameSiteNoneCookies(
88 run_loop.QuitClosure());
89 run_loop.Run();
90 }
91
ClearStoragePartitionData()92 void ClearStoragePartitionData() {
93 base::RunLoop run_loop;
94 GetSameSiteDataRemoverImpl()->ClearStoragePartitionData(
95 run_loop.QuitClosure());
96 run_loop.Run();
97 }
98
99 private:
100 BrowserTaskEnvironment task_environment_;
101 std::unique_ptr<BrowserContext> browser_context_;
102 std::unique_ptr<SameSiteDataRemoverImpl> same_site_remover_;
103
104 DISALLOW_COPY_AND_ASSIGN(SameSiteDataRemoverImplTest);
105 };
106
TEST_F(SameSiteDataRemoverImplTest,TestRemoveSameSiteNoneCookies)107 TEST_F(SameSiteDataRemoverImplTest, TestRemoveSameSiteNoneCookies) {
108 BrowserContext* browser_context = GetBrowserContext();
109
110 CreateCookieForTest(
111 "TestCookie1", "www.google.com", net::CookieSameSite::NO_RESTRICTION,
112 net::CookieOptions::SameSiteCookieContext(
113 net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
114 true /* is_cookie_secure */, browser_context);
115 CreateCookieForTest(
116 "TestCookie2", "www.gmail.google.com",
117 net::CookieSameSite::NO_RESTRICTION,
118 net::CookieOptions::SameSiteCookieContext(
119 net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
120 true /* is_cookie_secure */, browser_context);
121
122 DeleteSameSiteNoneCookies();
123
124 EXPECT_THAT(GetSameSiteDataRemoverImpl()->GetDeletedDomainsForTesting(),
125 UnorderedElementsAre("www.google.com", "www.gmail.google.com"));
126
127 const std::vector<net::CanonicalCookie>& cookies =
128 GetAllCookies(browser_context);
129 EXPECT_THAT(cookies, IsEmpty());
130 }
131
TEST_F(SameSiteDataRemoverImplTest,TestRemoveOnlySameSiteNoneCookies)132 TEST_F(SameSiteDataRemoverImplTest, TestRemoveOnlySameSiteNoneCookies) {
133 BrowserContext* browser_context = GetBrowserContext();
134 CreateCookieForTest(
135 "TestCookie1", "www.google.com", net::CookieSameSite::NO_RESTRICTION,
136 net::CookieOptions::SameSiteCookieContext(
137 net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
138 true /* is_cookie_secure */, browser_context);
139 // The second cookie has SameSite value STRICT_MODE instead of NO_RESTRICTION.
140 CreateCookieForTest("TestCookie2", "www.gmail.google.com",
141 net::CookieSameSite::STRICT_MODE,
142 net::CookieOptions::SameSiteCookieContext(
143 net::CookieOptions::SameSiteCookieContext::
144 ContextType::SAME_SITE_STRICT),
145 true /* is_cookie_secure */, browser_context);
146
147 DeleteSameSiteNoneCookies();
148
149 EXPECT_THAT(GetSameSiteDataRemoverImpl()->GetDeletedDomainsForTesting(),
150 UnorderedElementsAre("www.google.com"));
151
152 const std::vector<net::CanonicalCookie>& cookies =
153 GetAllCookies(browser_context);
154 ASSERT_EQ(1u, cookies.size());
155 ASSERT_EQ(cookies[0].Name(), "TestCookie2");
156 }
157
TEST_F(SameSiteDataRemoverImplTest,TestRemoveSameDomainCookies)158 TEST_F(SameSiteDataRemoverImplTest, TestRemoveSameDomainCookies) {
159 BrowserContext* browser_context = GetBrowserContext();
160 CreateCookieForTest(
161 "TestCookie1", "www.google.com", net::CookieSameSite::NO_RESTRICTION,
162 net::CookieOptions::SameSiteCookieContext(
163 net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
164 true /* is_cookie_secure */, browser_context);
165 // The second cookie has the same domain as the first cookie, but also has
166 // SameSite value STRICT_MODE instead of NO_RESTRICTION.
167 CreateCookieForTest("TestCookie2", "www.google.com",
168 net::CookieSameSite::STRICT_MODE,
169 net::CookieOptions::SameSiteCookieContext(
170 net::CookieOptions::SameSiteCookieContext::
171 ContextType::SAME_SITE_STRICT),
172 false /* is_cookie_secure */, browser_context);
173
174 DeleteSameSiteNoneCookies();
175
176 EXPECT_THAT(GetSameSiteDataRemoverImpl()->GetDeletedDomainsForTesting(),
177 UnorderedElementsAre("www.google.com"));
178
179 const std::vector<net::CanonicalCookie>& cookies =
180 GetAllCookies(browser_context);
181 ASSERT_EQ(1u, cookies.size());
182 ASSERT_EQ(cookies[0].Name(), "TestCookie2");
183 }
184
TEST_F(SameSiteDataRemoverImplTest,TestKeepSameSiteCookies)185 TEST_F(SameSiteDataRemoverImplTest, TestKeepSameSiteCookies) {
186 BrowserContext* browser_context = GetBrowserContext();
187 CreateCookieForTest("TestCookie1", "www.google.com",
188 net::CookieSameSite::LAX_MODE,
189 net::CookieOptions::SameSiteCookieContext(
190 net::CookieOptions::SameSiteCookieContext::
191 ContextType::SAME_SITE_LAX),
192 false /* is_cookie_secure */, browser_context);
193 CreateCookieForTest("TestCookie2", "www.gmail.google.com",
194 net::CookieSameSite::STRICT_MODE,
195 net::CookieOptions::SameSiteCookieContext(
196 net::CookieOptions::SameSiteCookieContext::
197 ContextType::SAME_SITE_STRICT),
198 false /* is_cookie_secure */, browser_context);
199
200 DeleteSameSiteNoneCookies();
201
202 ASSERT_THAT(GetSameSiteDataRemoverImpl()->GetDeletedDomainsForTesting(),
203 IsEmpty());
204
205 const std::vector<net::CanonicalCookie>& cookies =
206 GetAllCookies(browser_context);
207 EXPECT_THAT(2u, cookies.size());
208 }
209
TEST_F(SameSiteDataRemoverImplTest,TestCookieRemovalUnaffectedByParameters)210 TEST_F(SameSiteDataRemoverImplTest, TestCookieRemovalUnaffectedByParameters) {
211 BrowserContext* browser_context = GetBrowserContext();
212 network::mojom::CookieManager* cookie_manager =
213 GetCookieManager(browser_context);
214
215 base::RunLoop run_loop1;
216 net::CookieOptions options;
217 options.set_include_httponly();
218 bool result_out = false;
219 cookie_manager->SetCanonicalCookie(
220 net::CanonicalCookie("TestCookie1", "20", "google.com", "/",
221 base::Time::Now(), base::Time(), base::Time(), true,
222 true, net::CookieSameSite::NO_RESTRICTION,
223 net::COOKIE_PRIORITY_HIGH),
224 "https", options,
225 base::BindLambdaForTesting(
226 [&](net::CanonicalCookie::CookieInclusionStatus result) {
227 result_out = result.IsInclude();
228 run_loop1.Quit();
229 }));
230 run_loop1.Run();
231 EXPECT_TRUE(result_out);
232
233 base::RunLoop run_loop2;
234 options.set_same_site_cookie_context(
235 net::CookieOptions::SameSiteCookieContext(
236 net::CookieOptions::SameSiteCookieContext::ContextType::
237 SAME_SITE_LAX));
238 result_out = false;
239 cookie_manager->SetCanonicalCookie(
240 net::CanonicalCookie("TestCookie2", "10", "gmail.google.com", "/",
241 base::Time(), base::Time::Max(), base::Time(), false,
242 true, net::CookieSameSite::LAX_MODE,
243 net::COOKIE_PRIORITY_HIGH),
244 "https", options,
245 base::BindLambdaForTesting(
246 [&](net::CanonicalCookie::CookieInclusionStatus result) {
247 result_out = result.IsInclude();
248 run_loop2.Quit();
249 }));
250 run_loop2.Run();
251 EXPECT_TRUE(result_out);
252
253 DeleteSameSiteNoneCookies();
254
255 EXPECT_THAT(GetSameSiteDataRemoverImpl()->GetDeletedDomainsForTesting(),
256 UnorderedElementsAre("google.com"));
257
258 const std::vector<net::CanonicalCookie>& cookies =
259 GetAllCookies(browser_context);
260 ASSERT_EQ(1u, cookies.size());
261 ASSERT_EQ(cookies[0].Name(), "TestCookie2");
262 }
263
TEST_F(SameSiteDataRemoverImplTest,TestStoragePartitionDataRemoval)264 TEST_F(SameSiteDataRemoverImplTest, TestStoragePartitionDataRemoval) {
265 BrowserContext* browser_context = GetBrowserContext();
266 network::mojom::CookieManager* cookie_manager =
267 GetCookieManager(browser_context);
268 SameSiteRemoverTestStoragePartition storage_partition;
269 storage_partition.set_cookie_manager_for_browser_process(cookie_manager);
270 GetSameSiteDataRemoverImpl()->OverrideStoragePartitionForTesting(
271 &storage_partition);
272
273 CreateCookieForTest(
274 "TestCookie1", ".google.com", net::CookieSameSite::NO_RESTRICTION,
275 net::CookieOptions::SameSiteCookieContext(
276 net::CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE),
277 true /* is_cookie_secure */, browser_context);
278 DeleteSameSiteNoneCookies();
279
280 ClearStoragePartitionData();
281 StoragePartitionSameSiteRemovalData removal_data =
282 storage_partition.GetStoragePartitionRemovalData();
283
284 const uint32_t expected_removal_mask =
285 content::StoragePartition::REMOVE_DATA_MASK_ALL &
286 ~content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
287 EXPECT_EQ(removal_data.removal_mask, expected_removal_mask);
288
289 const uint32_t expected_quota_storage_mask =
290 StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
291 EXPECT_EQ(removal_data.quota_storage_removal_mask,
292 expected_quota_storage_mask);
293
294 auto special_storage_policy =
295 base::MakeRefCounted<storage::MockSpecialStoragePolicy>();
296 EXPECT_TRUE(removal_data.origin_matcher.Run(
297 url::Origin::Create(GURL("http://www.google.com/test")),
298 special_storage_policy.get()));
299 EXPECT_TRUE(removal_data.origin_matcher.Run(
300 url::Origin::Create(GURL("http://google.com")),
301 special_storage_policy.get()));
302 EXPECT_FALSE(removal_data.origin_matcher.Run(
303 url::Origin::Create(GURL("http://youtube.com")),
304 special_storage_policy.get()));
305 }
306
307 } // namespace content
308