File: cookie_craving.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 (183 lines) | stat: -rw-r--r-- 8,192 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
// Copyright 2024 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_DEVICE_BOUND_SESSIONS_COOKIE_CRAVING_H_
#define NET_DEVICE_BOUND_SESSIONS_COOKIE_CRAVING_H_

#include <optional>
#include <string>

#include "base/time/time.h"
#include "net/base/net_export.h"
#include "net/cookies/cookie_base.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_partition_key.h"

namespace net {
class URLRequest;
class CanonicalCookie;
class FirstPartySetMetadata;
}

namespace net::device_bound_sessions {

namespace proto {
class CookieCraving;
}

// This class represents the need for a certain cookie to be present. It is not
// a cookie itself, but rather represents a requirement which can be satisfied
// by a real cookie (i.e. a CanonicalCookie). Each CookieCraving is specified by
// and associated with a DBSC (Device Bound Session Credentials) session.
//
// In general, CookieCraving behavior is intended to be as close as possible to
// CanonicalCookie, especially the inclusion logic, since they need to be
// matched up. However, some notable differences include:
//
// CookieCraving does not have a value field, i.e. they only have a name (and
// other attributes). The name can be the empty string. The name of a cookie is
// needed to identify it, but the value of a cookie is not relevant to its
// inclusion or exclusion, so CookieCraving omits it.
//
// CookieCraving does not have an expiry date. The expiry date of a
// CanonicalCookie often depends upon the creation time (if it is set via
// Max-Age), and a DBSC session config is not necessarily created at the same
// time as its corresponding Set-Cookie header, so we cannot guarantee that
// they'd match. DBSC also does not require a specific expiry date for the
// cookies whose presence it guarantees.
//
// CookieCraving does not implement lax-allow-unsafe behavior (it does not
// set a non-zero age threshold for it). The default CanonicalCookie
// lax-allow-unsafe behavior is problematic because it can result in two
// identical set-cookie lines (set from the same URL) exhibiting different
// inclusion results, if they happen to be on opposite sides of the
// lax-allow-unsafe age threshold. By not implementing lax-allow-unsafe,
// CookieCraving may sometimes be excluded even when a corresponding
// CanonicalCookie would be included for being under its lax-allow-unsafe age
// threshold. This means that servers deploying DBSC with SameSite-unspecified
// cookies SHOULD NOT rely on the presence of SameSite-unspecified cookies
// within 2 minutes of their creation time on cross-site POST and other unsafe
// request types, as DBSC cannot make any such guarantee.
class NET_EXPORT CookieCraving : public CookieBase {
 public:
  // Creates a new CookieCraving in the context of `url`, given a `name` and
  // associated cookie `attributes`. (Note that CookieCravings do not have a
  // "value".) `url` must be valid. `creation_time` may not be null. May return
  // nullopt if an attribute value is invalid. If a CookieCraving is returned,
  // it will satisfy IsValid(). If there is leading or trailing whitespace in
  // `name`, it will get trimmed.
  //
  // `cookie_partition_key` only needs to be present if the attributes contain
  // the Partitioned attribute. std::nullopt indicates an unpartitioned
  // CookieCraving will be created. If there is a partition key but the
  // attributes do not specify Partitioned, the resulting CookieCraving will be
  // unpartitioned. If the partition_key is nullopt, the CookieCraving will
  // always be unpartitioned even if the attributes specify Partitioned.
  //
  // SameSite and HttpOnly related parameters are not checked here,
  // so creation of CookieCravings with e.g. SameSite=Strict from a cross-site
  // context is allowed. Create() also does not check whether `url` has a secure
  // scheme if attempting to create a Secure cookie. The Secure, SameSite, and
  // HttpOnly related parameters should be checked when deciding CookieCraving
  // inclusion for a given request/context.
  //
  // In general this is intended to closely mirror CanonicalCookie::Create.
  // However, there are some simplifying assumptions made*, and metrics are not
  // (currently) logged so as to not interfere with CanonicalCookie metrics.
  // There is also no (current) need for a CookieInclusionStatus to be returned.
  //
  // * Simplifying assumptions (differing from CanonicalCookie):
  //  - The Domain() member of a CookieCraving is required to be non-empty,
  //    which CanonicalCookie does not require.
  //  - Cookie name prefixes (__Host- and __Secure-) are always checked
  //    case-insensitively, unlike CanonicalCookie which reads a Feature value
  //    to decide whether to check insensitively.
  //  - CanonicalCookie allows non-cryptographic URLs to create a cookie with a
  //    secure source_scheme, if that cookie was Secure, on the basis that that
  //    URL might be trustworthy when checked later. CookieCraving does not
  //    allow this.
  static std::optional<CookieCraving> Create(
      const GURL& url,
      const std::string& name,
      const std::string& attributes,
      base::Time creation_time,
      std::optional<CookiePartitionKey> cookie_partition_key);

  CookieCraving(const CookieCraving& other);
  CookieCraving(CookieCraving&& other);
  CookieCraving& operator=(const CookieCraving& other);
  CookieCraving& operator=(CookieCraving&& other);
  ~CookieCraving() override;

  // Returns whether all CookieCraving fields are consistent, in canonical form,
  // etc. (Mostly analogous to CanonicalCookie::IsCanonical, except without
  // checks for access time.) Essentially, if this returns true, then this
  // CookieCraving instance could have been created by Create().
  // Other public methods of this class may not be called if IsValid() is false.
  bool IsValid() const;

  // Returns whether the given "real" cookie satisfies this CookieCraving, in
  // the sense that DBSC will consider the required cookie present.
  // The provided CanonicalCookie must be canonical.
  bool IsSatisfiedBy(const CanonicalCookie& canonical_cookie) const;

  std::string DebugString() const;

  bool IsEqualForTesting(const CookieCraving& other) const;

  // May return an invalid instance.
  static CookieCraving CreateUnsafeForTesting(
      std::string name,
      std::string domain,
      std::string path,
      base::Time creation,
      bool secure,
      bool httponly,
      CookieSameSite same_site,
      std::optional<CookiePartitionKey> partition_key,
      CookieSourceScheme source_scheme,
      int source_port);

  // Returns a protobuf object. May only be called for
  // a valid CookieCraving object.
  proto::CookieCraving ToProto() const;

  // Creates a CookieCraving object from a protobuf
  // object. If the protobuf contents are invalid,
  // a std::nullopt is returned.
  static std::optional<CookieCraving> CreateFromProto(
      const proto::CookieCraving& proto);

  // Whether the craving applies to the given `request`, with other
  // arguments providing context for the access.
  bool ShouldIncludeForRequest(
      URLRequest* request,
      const FirstPartySetMetadata& first_party_set_metadata,
      const CookieOptions& options,
      const CookieAccessParams& params) const;

 private:
  CookieCraving();

  // Prefer Create() over this constructor. This may return non-valid instances.
  CookieCraving(std::string name,
                std::string domain,
                std::string path,
                base::Time creation,
                bool secure,
                bool httponly,
                CookieSameSite same_site,
                std::optional<CookiePartitionKey> partition_key,
                CookieSourceScheme source_scheme,
                int source_port);

  using CookieBase::IncludeForRequestURL;
};

// Outputs a debug string, e.g. for more helpful test failure messages.
NET_EXPORT std::ostream& operator<<(std::ostream& os, const CookieCraving& cc);

}  // namespace net::device_bound_sessions

#endif  // NET_DEVICE_BOUND_SESSIONS_COOKIE_CRAVING_H_