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 "content/browser/browsing_data/same_site_data_remover_impl.h"
6 
7 #include <memory>
8 #include <set>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/barrier_closure.h"
14 #include "base/bind.h"
15 #include "base/callback.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/same_site_data_remover.h"
18 #include "content/public/browser/storage_partition.h"
19 #include "net/cookies/canonical_cookie.h"
20 #include "net/cookies/cookie_constants.h"
21 #include "net/cookies/cookie_monster.h"
22 #include "net/cookies/cookie_util.h"
23 #include "services/network/public/mojom/cookie_manager.mojom.h"
24 #include "url/origin.h"
25 
26 namespace content {
27 
28 namespace {
29 
OnGetAllCookiesWithAccessSemantics(base::OnceClosure closure,network::mojom::CookieManager * cookie_manager,std::set<std::string> * same_site_none_domains,const std::vector<net::CanonicalCookie> & cookies,const std::vector<net::CookieAccessSemantics> & access_semantics_list)30 void OnGetAllCookiesWithAccessSemantics(
31     base::OnceClosure closure,
32     network::mojom::CookieManager* cookie_manager,
33     std::set<std::string>* same_site_none_domains,
34     const std::vector<net::CanonicalCookie>& cookies,
35     const std::vector<net::CookieAccessSemantics>& access_semantics_list) {
36   DCHECK(cookies.size() == access_semantics_list.size());
37   base::RepeatingClosure barrier =
38       base::BarrierClosure(cookies.size(), std::move(closure));
39   for (size_t i = 0; i < cookies.size(); ++i) {
40     const net::CanonicalCookie& cookie = cookies[i];
41     if (cookie.IsEffectivelySameSiteNone(access_semantics_list[i])) {
42       same_site_none_domains->emplace(cookie.Domain());
43       cookie_manager->DeleteCanonicalCookie(
44           cookie, base::BindOnce([](const base::RepeatingClosure& callback,
45                                     bool success) { callback.Run(); },
46                                  barrier));
47     } else {
48       barrier.Run();
49     }
50   }
51 }
52 
DoesOriginMatchDomain(const std::set<std::string> & same_site_none_domains,const url::Origin & origin,storage::SpecialStoragePolicy * policy)53 bool DoesOriginMatchDomain(const std::set<std::string>& same_site_none_domains,
54                            const url::Origin& origin,
55                            storage::SpecialStoragePolicy* policy) {
56   for (const std::string& domain : same_site_none_domains) {
57     if (net::cookie_util::IsDomainMatch(domain, origin.host())) {
58       return true;
59     }
60   }
61   return false;
62 }
63 
OnDeleteSameSiteNoneCookies(base::OnceClosure closure,std::unique_ptr<SameSiteDataRemoverImpl> remover,bool clear_storage)64 void OnDeleteSameSiteNoneCookies(
65     base::OnceClosure closure,
66     std::unique_ptr<SameSiteDataRemoverImpl> remover,
67     bool clear_storage) {
68   if (clear_storage) {
69     remover->ClearStoragePartitionData(std::move(closure));
70   } else {
71     std::move(closure).Run();
72   }
73 }
74 
75 }  // namespace
76 
SameSiteDataRemoverImpl(BrowserContext * browser_context)77 SameSiteDataRemoverImpl::SameSiteDataRemoverImpl(
78     BrowserContext* browser_context)
79     : browser_context_(browser_context),
80       storage_partition_(
81           BrowserContext::GetDefaultStoragePartition(browser_context_)) {
82   DCHECK(browser_context_);
83 }
84 
~SameSiteDataRemoverImpl()85 SameSiteDataRemoverImpl::~SameSiteDataRemoverImpl() {}
86 
87 const std::set<std::string>&
GetDeletedDomainsForTesting()88 SameSiteDataRemoverImpl::GetDeletedDomainsForTesting() {
89   return same_site_none_domains_;
90 }
91 
OverrideStoragePartitionForTesting(StoragePartition * storage_partition)92 void SameSiteDataRemoverImpl::OverrideStoragePartitionForTesting(
93     StoragePartition* storage_partition) {
94   storage_partition_ = storage_partition;
95 }
96 
DeleteSameSiteNoneCookies(base::OnceClosure closure)97 void SameSiteDataRemoverImpl::DeleteSameSiteNoneCookies(
98     base::OnceClosure closure) {
99   same_site_none_domains_.clear();
100   auto* cookie_manager =
101       storage_partition_->GetCookieManagerForBrowserProcess();
102   cookie_manager->GetAllCookiesWithAccessSemantics(
103       base::BindOnce(&OnGetAllCookiesWithAccessSemantics, std::move(closure),
104                      cookie_manager, &same_site_none_domains_));
105 }
106 
ClearStoragePartitionData(base::OnceClosure closure)107 void SameSiteDataRemoverImpl::ClearStoragePartitionData(
108     base::OnceClosure closure) {
109   const uint32_t storage_partition_removal_mask =
110       content::StoragePartition::REMOVE_DATA_MASK_ALL &
111       ~content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
112   const uint32_t quota_storage_removal_mask =
113       StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL;
114   // TODO(crbug.com/987177): Figure out how to handle protected storage.
115 
116   storage_partition_->ClearData(
117       storage_partition_removal_mask, quota_storage_removal_mask,
118       base::BindRepeating(&DoesOriginMatchDomain, same_site_none_domains_),
119       nullptr, false, base::Time(), base::Time::Max(), std::move(closure));
120 }
121 
122 // Defines the ClearSameSiteNoneData function declared in same_site_remover.h.
123 // Clears cookies and associated data available in third-party contexts.
ClearSameSiteNoneData(base::OnceClosure closure,BrowserContext * context,bool clear_storage)124 void ClearSameSiteNoneData(base::OnceClosure closure,
125                            BrowserContext* context,
126                            bool clear_storage) {
127   auto same_site_remover = std::make_unique<SameSiteDataRemoverImpl>(context);
128   SameSiteDataRemoverImpl* remover = same_site_remover.get();
129 
130   remover->DeleteSameSiteNoneCookies(
131       base::BindOnce(&OnDeleteSameSiteNoneCookies, std::move(closure),
132                      std::move(same_site_remover), clear_storage));
133 }
134 
135 }  // namespace content
136