blob: ab0c50df8a1b9918b33264165ca2c77e3b996bbf [file] [log] [blame]
Alexander Timin1cc31f42020-05-12 16:26:011// Copyright 2020 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
danakjc492bf82020-09-09 20:02:445#include "content/browser/renderer_host/cookie_utils.h"
Alexander Timin1cc31f42020-05-12 16:26:016
Jayson Adams295430202021-07-27 01:07:577#include "base/ranges/algorithm.h"
Alexander Timin1cc31f42020-05-12 16:26:018#include "content/browser/devtools/devtools_instrumentation.h"
danakjc492bf82020-09-09 20:02:449#include "content/browser/renderer_host/render_frame_host_impl.h"
Alexander Timin1cc31f42020-05-12 16:26:0110#include "content/public/browser/browser_context.h"
11#include "content/public/browser/cookie_access_details.h"
12#include "content/public/common/content_client.h"
Jihwan Marc Kim3e132f12020-05-20 17:33:1913#include "net/cookies/cookie_inclusion_status.h"
Alexander Timin1cc31f42020-05-12 16:26:0114#include "services/metrics/public/cpp/ukm_builders.h"
15
16namespace content {
17
18namespace {
19
Jihwan Marc Kim3e132f12020-05-20 17:33:1920void RecordContextDowngradeUKM(RenderFrameHost* rfh,
21 CookieAccessDetails::Type access_type,
22 const net::CookieInclusionStatus& status,
23 const GURL& url) {
Alexander Timin1cc31f42020-05-12 16:26:0124 DCHECK(rfh);
25 ukm::SourceId source_id = rfh->GetPageUkmSourceId();
26
Lei Zhang3ab30192022-08-15 19:52:2027 auto downgrade_metric =
28 static_cast<int64_t>(status.GetBreakingDowngradeMetricsEnumValue(url));
Alexander Timin1cc31f42020-05-12 16:26:0129 if (access_type == CookieAccessDetails::Type::kRead) {
30 ukm::builders::SchemefulSameSiteContextDowngrade(source_id)
Lei Zhang3ab30192022-08-15 19:52:2031 .SetRequestPerCookie(downgrade_metric)
Alexander Timin1cc31f42020-05-12 16:26:0132 .Record(ukm::UkmRecorder::Get());
33 } else {
34 DCHECK(access_type == CookieAccessDetails::Type::kChange);
35 ukm::builders::SchemefulSameSiteContextDowngrade(source_id)
Lei Zhang3ab30192022-08-15 19:52:2036 .SetResponsePerCookie(downgrade_metric)
Alexander Timin1cc31f42020-05-12 16:26:0137 .Record(ukm::UkmRecorder::Get());
38 }
39}
40
Simon Zünd657178e2021-05-27 06:19:5541bool ShouldReportDevToolsIssueForStatus(
42 const net::CookieInclusionStatus& status) {
43 return status.ShouldWarn() ||
44 status.HasExclusionReason(
Johann Hofmann975c0b42022-08-02 21:05:5145 net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY) ||
46 status.HasExclusionReason(
47 net::CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII);
Simon Zünd657178e2021-05-27 06:19:5548}
49
Alexander Timin1cc31f42020-05-12 16:26:0150} // namespace
51
52void SplitCookiesIntoAllowedAndBlocked(
53 const network::mojom::CookieAccessDetailsPtr& cookie_details,
54 CookieAccessDetails* allowed,
55 CookieAccessDetails* blocked) {
56 *allowed =
57 CookieAccessDetails({cookie_details->type,
58 cookie_details->url,
59 cookie_details->site_for_cookies.RepresentativeUrl(),
60 {},
61 /* blocked_by_policy=*/false});
Jayson Adams295430202021-07-27 01:07:5762 int allowed_count = base::ranges::count_if(
63 cookie_details->cookie_list,
64 [](const network::mojom::CookieOrLineWithAccessResultPtr&
65 cookie_and_access_result) {
66 // "Included" cookies have no exclusion reasons so we don't also have to
67 // check for !(net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES).
68 return cookie_and_access_result->access_result.status.IsInclude();
69 });
70 allowed->cookie_list.reserve(allowed_count);
71
Alexander Timin1cc31f42020-05-12 16:26:0172 *blocked =
73 CookieAccessDetails({cookie_details->type,
74 cookie_details->url,
75 cookie_details->site_for_cookies.RepresentativeUrl(),
76 {},
77 /* blocked_by_policy=*/true});
Jayson Adams295430202021-07-27 01:07:5778 int blocked_count = base::ranges::count_if(
79 cookie_details->cookie_list,
80 [](const network::mojom::CookieOrLineWithAccessResultPtr&
81 cookie_and_access_result) {
82 return cookie_and_access_result->access_result.status
83 .HasOnlyExclusionReason(
84 net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES);
85 });
86 blocked->cookie_list.reserve(blocked_count);
Alexander Timin1cc31f42020-05-12 16:26:0187
Jayson Adams295430202021-07-27 01:07:5788 for (const auto& cookie_and_access_result : cookie_details->cookie_list) {
cfredric76b2d222021-01-27 20:12:0489 if (cookie_and_access_result->access_result.status.HasOnlyExclusionReason(
Jihwan Marc Kim3e132f12020-05-20 17:33:1990 net::CookieInclusionStatus::EXCLUDE_USER_PREFERENCES)) {
Jayson Adams295430202021-07-27 01:07:5791 blocked->cookie_list.emplace_back(
cfredric76b2d222021-01-27 20:12:0492 std::move(cookie_and_access_result->cookie_or_line->get_cookie()));
93 } else if (cookie_and_access_result->access_result.status.IsInclude()) {
Jayson Adams295430202021-07-27 01:07:5794 allowed->cookie_list.emplace_back(
cfredric76b2d222021-01-27 20:12:0495 std::move(cookie_and_access_result->cookie_or_line->get_cookie()));
Alexander Timin1cc31f42020-05-12 16:26:0196 }
97 }
98}
99
cfredrica5fb0982021-01-09 00:18:01100void EmitCookieWarningsAndMetrics(
Alexander Timin1cc31f42020-05-12 16:26:01101 RenderFrameHostImpl* rfh,
102 const network::mojom::CookieAccessDetailsPtr& cookie_details) {
103 RenderFrameHostImpl* root_frame_host = rfh->GetMainFrame();
104
Sreeja Kamishettye49854f82021-06-02 00:52:03105 if (!root_frame_host->IsActive())
Alexander Timin1cc31f42020-05-12 16:26:01106 return;
107
108 bool samesite_treated_as_lax_cookies = false;
109 bool samesite_none_insecure_cookies = false;
Alexander Timin1cc31f42020-05-12 16:26:01110 bool breaking_context_downgrade = false;
Lily Chenc4423c02021-03-11 16:02:02111 bool lax_allow_unsafe_cookies = false;
Alexander Timin1cc31f42020-05-12 16:26:01112
cfredrica5fb0982021-01-09 00:18:01113 bool same_party = false;
114 bool same_party_exclusion_overruled_samesite = false;
115 bool same_party_inclusion_overruled_samesite = false;
116
Lily Chen2db3a422021-07-20 18:02:25117 bool samesite_cookie_inclusion_changed_by_cross_site_redirect = false;
118
Dylan Cutler8d5f8912022-03-04 17:39:19119 bool partitioned_cookies_exist = false;
120
Ari Chivukula5f21c112022-04-26 19:23:34121 bool cookie_has_not_been_refreshed_in_201_to_300_days = false;
122 bool cookie_has_not_been_refreshed_in_301_to_350_days = false;
123 bool cookie_has_not_been_refreshed_in_351_to_400_days = false;
124
Johann Hofmanne5764d12022-07-13 23:06:28125 bool cookie_has_domain_non_ascii = false;
126
cfredric76b2d222021-01-27 20:12:04127 for (const network::mojom::CookieOrLineWithAccessResultPtr& cookie :
Alexander Timin1cc31f42020-05-12 16:26:01128 cookie_details->cookie_list) {
Johann Hofmann975c0b42022-08-02 21:05:51129 const net::CookieInclusionStatus& status = cookie->access_result.status;
130 if (ShouldReportDevToolsIssueForStatus(status)) {
Juba Borgohainc93969e2022-02-25 21:56:12131 devtools_instrumentation::ReportCookieIssue(
Simon Zünd657178e2021-05-27 06:19:55132 root_frame_host, cookie, cookie_details->url,
133 cookie_details->site_for_cookies,
134 cookie_details->type == CookieAccessDetails::Type::kRead
Juba Borgohainc93969e2022-02-25 21:56:12135 ? blink::mojom::CookieOperation::kReadCookie
136 : blink::mojom::CookieOperation::kSetCookie,
Simon Zünd657178e2021-05-27 06:19:55137 cookie_details->devtools_request_id);
138 }
139
cfredric76b2d222021-01-27 20:12:04140 if (cookie->access_result.status.ShouldWarn()) {
Lily Chen9de4065b2020-06-24 20:18:47141 samesite_treated_as_lax_cookies =
142 samesite_treated_as_lax_cookies ||
cfredrica5fb0982021-01-09 00:18:01143 status.HasWarningReason(
Jihwan Marc Kim3e132f12020-05-20 17:33:19144 net::CookieInclusionStatus::
Lily Chen9de4065b2020-06-24 20:18:47145 WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT) ||
cfredrica5fb0982021-01-09 00:18:01146 status.HasWarningReason(
Jihwan Marc Kim3e132f12020-05-20 17:33:19147 net::CookieInclusionStatus::
Lily Chen9de4065b2020-06-24 20:18:47148 WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
Alexander Timin1cc31f42020-05-12 16:26:01149
Lily Chen9de4065b2020-06-24 20:18:47150 samesite_none_insecure_cookies =
151 samesite_none_insecure_cookies ||
cfredrica5fb0982021-01-09 00:18:01152 status.HasWarningReason(
Lily Chen9de4065b2020-06-24 20:18:47153 net::CookieInclusionStatus::WARN_SAMESITE_NONE_INSECURE);
154
Lily Chenc4423c02021-03-11 16:02:02155 lax_allow_unsafe_cookies =
156 lax_allow_unsafe_cookies ||
157 status.HasWarningReason(
158 net::CookieInclusionStatus::
159 WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE);
160
cfredrica5fb0982021-01-09 00:18:01161 same_party = same_party ||
162 status.HasWarningReason(
163 net::CookieInclusionStatus::WARN_TREATED_AS_SAMEPARTY);
164
165 same_party_exclusion_overruled_samesite =
166 same_party_exclusion_overruled_samesite ||
167 status.HasWarningReason(
168 net::CookieInclusionStatus::
169 WARN_SAMEPARTY_EXCLUSION_OVERRULED_SAMESITE);
170
171 same_party_inclusion_overruled_samesite =
172 same_party_inclusion_overruled_samesite ||
173 status.HasWarningReason(
174 net::CookieInclusionStatus::
175 WARN_SAMEPARTY_INCLUSION_OVERRULED_SAMESITE);
cfredric362c4a02021-07-09 22:40:40176
Lily Chen2db3a422021-07-20 18:02:25177 samesite_cookie_inclusion_changed_by_cross_site_redirect =
178 samesite_cookie_inclusion_changed_by_cross_site_redirect ||
179 status.HasWarningReason(
180 net::CookieInclusionStatus::
181 WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION);
Alexander Timin1cc31f42020-05-12 16:26:01182 }
Alexander Timin1cc31f42020-05-12 16:26:01183
Johann Hofmann975c0b42022-08-02 21:05:51184 cookie_has_domain_non_ascii =
185 cookie_has_domain_non_ascii ||
186 status.HasWarningReason(
187 net::CookieInclusionStatus::WARN_DOMAIN_NON_ASCII) ||
188 status.HasExclusionReason(
189 net::CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII);
190
Dylan Cutler8d5f8912022-03-04 17:39:19191 partitioned_cookies_exist =
192 partitioned_cookies_exist ||
193 (cookie->cookie_or_line->is_cookie() &&
Dylan Cutler051411b42022-07-12 22:20:07194 cookie->cookie_or_line->get_cookie().IsPartitioned() &&
195 // Ignore nonced partition keys since this metric is meant to track
196 // usage of the Partitioned attribute.
197 !cookie->cookie_or_line->get_cookie().PartitionKey()->nonce());
Dylan Cutler8d5f8912022-03-04 17:39:19198
Ayu Ishii2e3998902020-07-14 18:22:30199 breaking_context_downgrade =
200 breaking_context_downgrade ||
cfredric76b2d222021-01-27 20:12:04201 cookie->access_result.status.HasDowngradeWarning();
Alexander Timin1cc31f42020-05-12 16:26:01202
cfredric76b2d222021-01-27 20:12:04203 if (cookie->access_result.status.HasDowngradeWarning()) {
Steven Binglerdad03342020-05-19 17:21:59204 // Unlike with UMA, do not record cookies that have no downgrade warning.
Alexander Timin1cc31f42020-05-12 16:26:01205 RecordContextDowngradeUKM(rfh, cookie_details->type,
cfredric76b2d222021-01-27 20:12:04206 cookie->access_result.status,
Ayu Ishii2e3998902020-07-14 18:22:30207 cookie_details->url);
Alexander Timin1cc31f42020-05-12 16:26:01208 }
Ari Chivukula5f21c112022-04-26 19:23:34209
210 // In order to anticipate the potential effects of the expiry limit in
211 // rfc6265bis, we need to check how long it's been since the cookie was
212 // refreshed (if LastUpdateDate is populated). These three buckets were
213 // picked so we could engage sites with some granularity around urgency.
214 // We ignore the space under 200 days as these cookies are not at risk
215 // of expiring and we ignore the space over 400 days as these cookies
216 // have already expired. Metrics will take 200 days from M103 to populate.
217 base::Time last_update_date =
218 cookie->cookie_or_line->is_cookie()
219 ? cookie->cookie_or_line->get_cookie().LastUpdateDate()
220 : base::Time();
221 if (!last_update_date.is_null()) {
222 int days_since_refresh = (base::Time::Now() - last_update_date).InDays();
223 cookie_has_not_been_refreshed_in_201_to_300_days |=
224 days_since_refresh > 200 && days_since_refresh <= 300;
225 cookie_has_not_been_refreshed_in_301_to_350_days |=
226 days_since_refresh > 300 && days_since_refresh <= 350;
227 cookie_has_not_been_refreshed_in_351_to_400_days |=
228 days_since_refresh > 350 && days_since_refresh <= 400;
229 }
Alexander Timin1cc31f42020-05-12 16:26:01230 }
231
Alexander Timin1cc31f42020-05-12 16:26:01232 if (samesite_treated_as_lax_cookies) {
233 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
234 rfh, blink::mojom::WebFeature::kCookieNoSameSite);
235 }
236
237 if (samesite_none_insecure_cookies) {
238 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
239 rfh, blink::mojom::WebFeature::kCookieInsecureAndSameSiteNone);
240 }
241
242 if (breaking_context_downgrade) {
243 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
244 rfh, blink::mojom::WebFeature::kSchemefulSameSiteContextDowngrade);
245 }
cfredrica5fb0982021-01-09 00:18:01246
Lily Chenc4423c02021-03-11 16:02:02247 if (lax_allow_unsafe_cookies) {
248 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
249 rfh, blink::mojom::WebFeature::kLaxAllowingUnsafeCookies);
250 }
251
cfredrica5fb0982021-01-09 00:18:01252 if (same_party) {
253 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
254 rfh, blink::mojom::WebFeature::kSamePartyCookieAttribute);
255 }
256
257 if (same_party_exclusion_overruled_samesite) {
258 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
259 rfh,
260 blink::mojom::WebFeature::kSamePartyCookieExclusionOverruledSameSite);
261 }
262
263 if (same_party_inclusion_overruled_samesite) {
264 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
265 rfh,
266 blink::mojom::WebFeature::kSamePartyCookieInclusionOverruledSameSite);
267 }
cfredric362c4a02021-07-09 22:40:40268
Lily Chen2db3a422021-07-20 18:02:25269 if (samesite_cookie_inclusion_changed_by_cross_site_redirect) {
270 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
271 rfh, blink::mojom::WebFeature::
272 kSameSiteCookieInclusionChangedByCrossSiteRedirect);
273 }
Dylan Cutler8d5f8912022-03-04 17:39:19274
275 if (partitioned_cookies_exist) {
276 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
277 rfh, blink::mojom::WebFeature::kPartitionedCookies);
278 }
Ari Chivukula5f21c112022-04-26 19:23:34279
280 if (cookie_has_not_been_refreshed_in_201_to_300_days) {
281 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
282 rfh,
283 blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn201To300Days);
284 }
285
286 if (cookie_has_not_been_refreshed_in_301_to_350_days) {
287 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
288 rfh,
289 blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn301To350Days);
290 }
291
292 if (cookie_has_not_been_refreshed_in_351_to_400_days) {
293 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
294 rfh,
295 blink::mojom::WebFeature::kCookieHasNotBeenRefreshedIn351To400Days);
296 }
Johann Hofmanne5764d12022-07-13 23:06:28297
298 if (cookie_has_domain_non_ascii) {
299 GetContentClient()->browser()->LogWebFeatureForCurrentPage(
300 rfh, blink::mojom::WebFeature::kCookieDomainNonASCII);
301 }
Alexander Timin1cc31f42020-05-12 16:26:01302}
303
304} // namespace content