• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_COOKIES_COOKIE_PARTITION_KEY_H_
6 #define NET_COOKIES_COOKIE_PARTITION_KEY_H_
7 
8 #include <string>
9 
10 #include "net/base/net_export.h"
11 #include "net/base/network_isolation_key.h"
12 #include "net/base/schemeful_site.h"
13 #include "third_party/abseil-cpp/absl/types/optional.h"
14 #include "url/gurl.h"
15 
16 namespace net {
17 
18 class NET_EXPORT CookiePartitionKey {
19  public:
20   CookiePartitionKey();
21   CookiePartitionKey(const CookiePartitionKey& other);
22   CookiePartitionKey(CookiePartitionKey&& other);
23   CookiePartitionKey& operator=(const CookiePartitionKey& other);
24   CookiePartitionKey& operator=(CookiePartitionKey&& other);
25   ~CookiePartitionKey();
26 
27   bool operator==(const CookiePartitionKey& other) const;
28   bool operator!=(const CookiePartitionKey& other) const;
29   bool operator<(const CookiePartitionKey& other) const;
30 
31   // Methods for serializing and deserializing a partition key to/from a string.
32   // This is currently used for:
33   // -  Storing persistent partitioned cookies
34   // -  Loading partitioned cookies into Java code
35   // -  Sending cookie partition keys as strings in the DevTools protocol
36   //
37   // This function returns true if the partition key is not opaque and if nonce_
38   // is not present. We do not want to serialize cookies with opaque origins or
39   // nonce in their partition key to disk, because if the browser session ends
40   // we will not be able to attach the saved cookie to any future requests. This
41   // is because opaque origins' nonces are only stored in volatile memory.
42   //
43   // TODO(crbug.com/1225444) Investigate ways to persist partition keys with
44   // opaque origins if a browser session is restored.
45   [[nodiscard]] static bool Serialize(
46       const absl::optional<CookiePartitionKey>& in,
47       std::string& out);
48   // Deserializes the result of the method above.
49   // If the result is absl::nullopt, the resulting cookie is not partitioned.
50   //
51   // Returns if the resulting partition key is valid.
52   [[nodiscard]] static bool Deserialize(
53       const std::string& in,
54       absl::optional<CookiePartitionKey>& out);
55 
56   static CookiePartitionKey FromURLForTesting(
57       const GURL& url,
58       const absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
59     return nonce ? CookiePartitionKey(SchemefulSite(url), nonce)
60                  : CookiePartitionKey(url);
61   }
62 
63   // Create a partition key from a network isolation key. Partition key is
64   // derived from the key's top-frame site.
65   static absl::optional<CookiePartitionKey> FromNetworkIsolationKey(
66       const NetworkIsolationKey& network_isolation_key);
67 
68   // Create a new CookiePartitionKey from the site of an existing
69   // CookiePartitionKey. This should only be used for sites of partition keys
70   // which were already created using Deserialize or FromNetworkIsolationKey.
71   static CookiePartitionKey FromWire(
72       const SchemefulSite& site,
73       absl::optional<base::UnguessableToken> nonce = absl::nullopt) {
74     return CookiePartitionKey(site, nonce);
75   }
76 
77   // Create a new CookiePartitionKey in a script running in a renderer. We do
78   // not trust the renderer to provide us with a cookie partition key, so we let
79   // the renderer use this method to indicate the cookie is partitioned but the
80   // key still needs to be determined.
81   //
82   // When the browser is ingesting cookie partition keys from the renderer,
83   // either the `from_script_` flag should be set or the cookie partition key
84   // should match the browser's. Otherwise the renderer may be compromised.
85   //
86   // TODO(crbug.com/1225444) Consider removing this factory method and
87   // `from_script_` flag when BlinkStorageKey is available in
88   // ServiceWorkerGlobalScope.
FromScript()89   static absl::optional<CookiePartitionKey> FromScript() {
90     return absl::make_optional(CookiePartitionKey(true));
91   }
92 
93   // Create a new CookiePartitionKey from the components of a StorageKey.
94   // Forwards to FromWire, but unlike that method in this one the optional nonce
95   // argument has no default. It also checks that cookie partitioning is enabled
96   // before returning a valid key, which FromWire does not check.
97   static absl::optional<CookiePartitionKey> FromStorageKeyComponents(
98       const SchemefulSite& top_level_site,
99       const absl::optional<base::UnguessableToken>& nonce);
100 
site()101   const SchemefulSite& site() const { return site_; }
102 
from_script()103   bool from_script() const { return from_script_; }
104 
105   // Returns true if the current partition key can be serialized to a string.
106   // Cookie partition keys whose internal site is opaque cannot be serialized.
107   bool IsSerializeable() const;
108 
nonce()109   const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; }
110 
HasNonce(const absl::optional<CookiePartitionKey> & key)111   static bool HasNonce(const absl::optional<CookiePartitionKey>& key) {
112     return key && key->nonce();
113   }
114 
115  private:
116   explicit CookiePartitionKey(const SchemefulSite& site,
117                               absl::optional<base::UnguessableToken> nonce);
118   explicit CookiePartitionKey(const GURL& url);
119   explicit CookiePartitionKey(bool from_script);
120 
121   SchemefulSite site_;
122   bool from_script_ = false;
123 
124   // Having a nonce is a way to force a transient opaque `CookiePartitionKey`
125   // for non-opaque origins.
126   absl::optional<base::UnguessableToken> nonce_;
127 };
128 
129 // Used so that CookiePartitionKeys can be the arguments of DCHECK_EQ.
130 NET_EXPORT std::ostream& operator<<(std::ostream& os,
131                                     const CookiePartitionKey& cpk);
132 
133 }  // namespace net
134 
135 #endif  // NET_COOKIES_COOKIE_PARTITION_KEY_H_
136