File: site_for_cookies.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (215 lines) | stat: -rw-r--r-- 9,353 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_COOKIES_SITE_FOR_COOKIES_H_
#define NET_COOKIES_SITE_FOR_COOKIES_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "net/base/net_export.h"
#include "net/base/schemeful_site.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {

// Represents which origins are to be considered same-site for a given
// context (e.g. frame). There may be none.
//
// The currently implemented policy ("schemeful") is that
// two valid URLs would be considered same-site if either:
// 1) They both have compatible schemes along with non-empty and equal
//    registrable domains or hostnames/IPs. Two schemes are compatible if they
//    are either equal, or are both in {http, ws}, or are both in {https, wss}.
//    E.x. "https://example.com" and "wss://example.com"
// 2) They both have empty hostnames and exactly equal schemes. E.x. "file://"
// and "file://"
//
// With the SchemefulSameSite feature disabled the policy ("schemeless") is that
// two valid URLs would be considered the same site if either: 1) They both have
// non-empty and equal registrable domains or hostnames/IPs. E.x. "example.com"
// and "example.com" 2) They both have empty hostnames and equal schemes. E.x.
// "file://" and "file://"
//
//
// Invalid URLs are never same-site to anything.
class NET_EXPORT SiteForCookies {
 public:
  // Matches nothing.
  SiteForCookies();

  SiteForCookies(const SiteForCookies& other);
  SiteForCookies(SiteForCookies&& other);

  explicit SiteForCookies(const SchemefulSite& schemeful_site);

  ~SiteForCookies();

  SiteForCookies& operator=(const SiteForCookies& other);
  SiteForCookies& operator=(SiteForCookies&& other);

  // Tries to construct an instance from (potentially untrusted) values of
  // site() and schemefully_same() that got received over an RPC.
  //
  // Returns whether successful or not. Doesn't touch `*out` if false is
  // returned.  This returning `true` does not mean that whoever sent the values
  // did not lie, merely that they are well-formed.
  static bool FromWire(const SchemefulSite& site,
                       bool schemefully_same,
                       SiteForCookies* out);

  // If the origin is opaque, returns SiteForCookies that matches nothing.
  //
  // If it's not opaque, returns one that matches URLs which are considered to
  // be same-party as URLs from `origin`.
  static SiteForCookies FromOrigin(const url::Origin& origin);

  // Equivalent to FromOrigin(url::Origin::Create(url)).
  static SiteForCookies FromUrl(const GURL& url);

  // Returns a string with the values of the member variables.
  // `schemefully_same` being false does not change the output.
  std::string ToDebugString() const;

  // Returns true if `url` should be considered first-party to the context
  // `this` represents.
  bool IsFirstParty(const GURL& url) const;

  // Don't use this function unless you know what you're doing, if you're unsure
  // you probably want IsFirstParty().
  //
  // If `compute_schemefully` is true this function will return true if `url`
  // should be considered first-party to the context `this` represents when the
  // compatibility of the schemes are taken into account.
  //
  // If `compute_schemefully` is false this function will return true if `url`
  // should be considered first-party to the context `this` represents when the
  // compatibility of the scheme are not taken into account. Note that schemes
  // are still compared for exact equality if neither `this` nor `url` have a
  // registered domain.
  bool IsFirstPartyWithSchemefulMode(const GURL& url,
                                     bool compute_schemefully) const;

  // Returns true if `other.IsFirstParty()` is true for exactly the same URLs
  // as `this->IsFirstParty` (potentially none). Two SFCs are also considered
  // equivalent if neither ever returns true for `IsFirstParty()`. I.e., both
  // are null.
  bool IsEquivalent(const SiteForCookies& other) const;

  // Compares a "candidate" SFC, `this`, with an origin (represented as a
  // SchemefulSite) from the frame tree and revises `this` to be null as
  // required.
  //
  // This method is used when a sub-frame needs to have its SiteForCookies
  // computed, which is dependent on all of its ancestors' origins (`other`). If
  // its or any of its ancestors' frame's origins are not first-party with the
  // top-level origin then this frame's SFC should be null. Otherwise, if it and
  // all its ancestors are first-party with the top-level frame, the frame's
  // SFC is the same as the top-level.
  //
  // This computation gets a bit tricky when considering "Schemeful Same-Site"
  // as we don't know ahead of time if `this` is going to be used for a
  // schemeful or schemeless computation later down the line, so we need to
  // be careful to not completely nullify the entire SFC just because an `other`
  // isn't schemefully first-party. If the computation is schemelessly
  // first-party but *not schemefully* first-party then only the
  // `schemefully_same_` flag will be cleared (which informs other functions to
  // treat `this` as null for schemeful purposes). If the computation is not
  // schemelessly first-party then `this` will have an opaque `site_` which
  // completely nullifies it.
  //
  // This function should be called on all ancestors up to the top-level frame
  // unless it returns false in which case `this` has been completely nullified
  // and the caller may stop early.
  //
  // (This function's return value is the same as IsEquivalent() when "Schemeful
  // Same-Site" is disabled.)
  bool CompareWithFrameTreeSiteAndRevise(const SchemefulSite& other);

  // Converts an Origin into a SchemefulSite and then calls
  //`CompareWithFrameTreeSiteAndRevise(SchemefulSite)`
  //
  // If possible, prefer `CompareWithFrameTreeSiteAndRevise(SchemefulSite)`
  // for performance reasons.
  bool CompareWithFrameTreeOriginAndRevise(const url::Origin& other);

  // Returns a URL that's first party to this SiteForCookies (an empty URL if
  // none) --- that is, it has the property that
  // site_for_cookies.IsEquivalent(
  //     SiteForCookies::FromUrl(site_for_cookies.RepresentativeUrl()));
  //
  // The convention used here (empty for nothing) is equivalent to that
  // used before SiteForCookies existed as a type; this method is mostly
  // meant to help incrementally migrate towards the type. New code probably
  // should not need this.
  GURL RepresentativeUrl() const;

  const SchemefulSite& site() const { return site_; }

  // Guaranteed to be lowercase.
  const std::string& scheme() const { return site_.site_as_origin_.scheme(); }

  const std::string& registrable_domain() const {
    return site_.site_as_origin_.host();
  }

  // Used for serialization/deserialization. This value is irrelevant if
  // site().opaque() is true.
  bool schemefully_same() const { return schemefully_same_; }

  void SetSchemefullySameForTesting(bool schemefully_same) {
    schemefully_same_ = schemefully_same;
  }

  // Returns true if this SiteForCookies matches nothing.
  // If the SchemefulSameSite feature is enabled then !schemefully_same_ causes
  // this function to return true.
  bool IsNull() const;

  // Allows SiteForCookies to be used as a key in STL (for example, a std::set
  // or std::map).
  NET_EXPORT friend bool operator<(const SiteForCookies& lhs,
                                   const SiteForCookies& rhs);

 private:
  FRIEND_TEST_ALL_PREFIXES(SiteForCookiesTest, SameScheme);
  FRIEND_TEST_ALL_PREFIXES(SiteForCookiesTest, SameSchemeOpaque);

  bool IsSchemefullyFirstParty(const GURL& url) const;

  bool IsSchemelesslyFirstParty(const GURL& url) const;

  // Sets the schemefully_same_ flag to false if other`'s scheme is
  // cross-scheme to `this`. Schemes are considered cross-scheme if they're not
  // compatible. Two schemes are compatible if they are either equal, or are
  // both in {http, ws}, or are both in {https, wss}.
  void MarkIfCrossScheme(const SchemefulSite& other);

  // Represents the scheme and registrable domain of the site. The scheme should
  // not be a WebSocket scheme; instead, ws is normalized to http, and
  // wss is normalized to https upon construction.
  SchemefulSite site_;

  // Used to indicate if the SiteForCookies would be the same if computed
  // schemefully. A schemeful computation means to take the scheme as well as
  // the registrable_domain into account when determining same-siteness.
  // See the class-level comment for more details on schemeless vs schemeful.
  //
  // True means to treat `this` as-is while false means that `this` should be
  // treated as if it matches nothing i.e. IsNull() returns true.
  //
  // This value is important in the case where the SiteForCookies is being used
  // to assess the first-partyness of a sub-frame in a document.
  //
  // For a SiteForCookies with !site_.opaque() this value starts as true and
  // will only go false via MarkIfCrossScheme(), otherwise this value is
  // irrelevant (For tests this value can also be modified by
  // SetSchemefullySameForTesting()).
  bool schemefully_same_ = false;
};

}  // namespace net

#endif  // NET_COOKIES_SITE_FOR_COOKIES_H_