summaryrefslogtreecommitdiffstats
path: root/chromium/net/cookies/site_for_cookies.h
blob: 0de33fabeba9e54f3f96fb33e67bfca8addb9461 (plain)
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
// Copyright 2019 The Chromium Authors. All rights reserved.
// 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/strings/string_piece.h"
#include "net/base/net_export.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {

// Represents which origins are to be considered first-party for a given
// context (e.g. frame). There may be none.
//
// The currently implemented policy is that two valid URLs would be considered
// the same party if either:
// 1) They both have non-empty and equal registrable domains or hostnames/IPs.
// 2) They both have empty hostnames and equal schemes.
// Invalid URLs are not first party to anything.
//
// With the SchemefulSameSite feature enabled the policy is that two valid URLs
// would be considered the same party if either:
// 1) They both have compatible schemes along with non-empty and equal
// registrable domains or hostnames/IPs. See CompatibleScheme() for more details
// on what it means to have a compatible scheme.
// 2) They both have empty hostnames and exactly equal schemes. Invalid URLs are
// not first party to anything.
class NET_EXPORT SiteForCookies {
 public:
  // Matches nothing.
  SiteForCookies();

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

  ~SiteForCookies();

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

  // Tries to construct an instance from (potentially untrusted) values of
  // scheme() and registrable_domain() 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 std::string& scheme,
                       const std::string& registrable_domain,
                       bool schemefully_same,
                       SiteForCookies* out);

  // If the origin is opaque, returns SiteForCookies that matches nothing.
  //
  // If it's not, 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.
  //
  // See CompatibleScheme() for more information on scheme compatibility.
  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).
  bool IsEquivalent(const SiteForCookies& other) const;

  // Clears the schemefully_same_ flag if |other|'s scheme is cross-scheme to
  // |this|. Schemes are considered cross-scheme if they're !CompatibleScheme().
  void MarkIfCrossScheme(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;

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

  const std::string& registrable_domain() const { return registrable_domain_; }

  // Used for serialization/deserialization. This value is irrelevant if
  // IsNull() 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;

 private:
  SiteForCookies(const std::string& scheme, const std::string& host);

  // Two schemes are considered compatible if they exactly match, they are both
  // in ["https", "wss"], or they are both in ["http", "ws"].
  bool CompatibleScheme(const std::string& other_scheme) const;

  bool IsSchemefullyFirstParty(const GURL& url) const;

  bool IsSchemelesslyFirstParty(const GURL& url) const;

  // These should be canonicalized appropriately by GURL/url::Origin.
  // An empty |scheme_| means that this matches nothing.
  std::string scheme_;

  // Represents which host or family of hosts this represents.
  // This is usually an eTLD+1 when one exists, but lacking that it may be
  // just the bare hostname or IP, or an empty string if this represents
  // something like file:///
  std::string registrable_domain_;

  // 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 first-partyness.
  // See CompatibleScheme() for more information on scheme comparison.
  //
  // 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 !scheme_.empty() 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_;
};

}  // namespace net

#endif  // NET_COOKIES_SITE_FOR_COOKIES_H_