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 216 217 218 219 220 221
|
// Copyright 2020 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_BASE_ISOLATION_INFO_H_
#define NET_BASE_ISOLATION_INFO_H_
#include <set>
#include <string>
#include "base/unguessable_token.h"
#include "net/base/net_export.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/network_isolation_key.h"
#include "net/cookies/site_for_cookies.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/origin.h"
namespace network::mojom {
class IsolationInfoDataView;
} // namespace network::mojom
namespace mojo {
template <typename DataViewType, typename T>
struct StructTraits;
} // namespace mojo
namespace net {
// Class to store information about network stack requests based on the context
// in which they are made. It provides NetworkIsolationKeys, used to shard
// storage, and SiteForCookies, used determine when to send same site cookies.
// The IsolationInfo is typically the same for all subresource requests made in
// the context of the same frame, but may be different for different frames
// within a page. The IsolationInfo associated with requests for frames may
// change as redirects are followed, and this class also contains the logic on
// how to do that.
//
// The SiteForCookies logic in this class is currently unused, but will
// eventually replace the logic in URLRequest/RedirectInfo for tracking and
// updating that value.
class NET_EXPORT IsolationInfo {
public:
// The update-on-redirect patterns.
//
// In general, almost everything should use kOther, as a
// kMainFrame request accidentally sent or redirected to an attacker
// allows cross-site tracking, and kSubFrame allows information
// leaks between sites that iframe each other. Anything that uses
// kMainFrame should be user triggered and user visible, like a main
// frame navigation or downloads.
//
// The RequestType is a core part of an IsolationInfo, and using an
// IsolationInfo with one value to create an IsolationInfo with another
// RequestType is generally not a good idea, unless the RequestType of the
// new IsolationInfo is kOther.
enum class RequestType {
// Updates top level origin, frame origin, and SiteForCookies on redirect.
// These requests allow users to be recognized across sites on redirect, so
// should not generally be used for anything other than navigations.
kMainFrame,
// Only updates frame origin on redirect.
kSubFrame,
// Updates nothing on redirect.
kOther,
};
// Default constructor returns an IsolationInfo with empty origins, a null
// SiteForCookies(), and a RequestType of kOther.
IsolationInfo();
IsolationInfo(const IsolationInfo&);
IsolationInfo(IsolationInfo&&);
~IsolationInfo();
IsolationInfo& operator=(const IsolationInfo&);
IsolationInfo& operator=(IsolationInfo&&);
// Simple constructor for internal requests. Sets |frame_origin| and
// |site_for_cookies| match |top_frame_origin|. Sets |request_type| to
// kOther. Will only send SameSite cookies to the site associated with
// the passed in origin.
static IsolationInfo CreateForInternalRequest(
const url::Origin& top_frame_origin);
// Creates a transient IsolationInfo. A transient IsolationInfo will not save
// data to disk and not send SameSite cookies. Equivalent to calling
// CreateForInternalRequest with a fresh opaque origin.
static IsolationInfo CreateTransient();
// Creates an IsolationInfo from the serialized contents. Returns a nullopt
// if deserialization fails or if data is inconsistent.
static absl::optional<IsolationInfo> Deserialize(
const std::string& serialized);
// Creates an IsolationInfo with the provided parameters. If the parameters
// are inconsistent, DCHECKs. In particular:
// * If |request_type| is kMainFrame, |top_frame_origin| must equal
// |frame_origin|, and |site_for_cookies| must be either null or first party
// with respect to them.
// * If |request_type| is kSubFrame, |top_frame_origin| must be
// first party with respect to |site_for_cookies|, or |site_for_cookies|
// must be null.
// * If |request_type| is kOther, |top_frame_origin| and
// |frame_origin| must be first party with respect to |site_for_cookies|, or
// |site_for_cookies| must be null.
// * If |nonce| is specified, then |top_frame_origin| must not be null.
//
// Note that the |site_for_cookies| consistency checks are skipped when
// |site_for_cookies| is not HTTP/HTTPS.
static IsolationInfo Create(
RequestType request_type,
const url::Origin& top_frame_origin,
const url::Origin& frame_origin,
const SiteForCookies& site_for_cookies,
const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);
// TODO(crbug/1372769): Remove this and create a safer way to ensure NIKs
// created from NAKs aren't used by accident.
static IsolationInfo DoNotUseCreatePartialFromNak(
const net::NetworkAnonymizationKey& network_anonymization_key);
// Returns nullopt if the arguments are not consistent. Otherwise, returns a
// fully populated IsolationInfo. Any IsolationInfo that can be created by
// the other construction methods, including the 0-argument constructor, is
// considered consistent.
//
// Intended for use by cross-process deserialization.
static absl::optional<IsolationInfo> CreateIfConsistent(
RequestType request_type,
const absl::optional<url::Origin>& top_frame_origin,
const absl::optional<url::Origin>& frame_origin,
const SiteForCookies& site_for_cookies,
const absl::optional<base::UnguessableToken>& nonce = absl::nullopt);
// Create a new IsolationInfo for a redirect to the supplied origin. |this| is
// unmodified.
IsolationInfo CreateForRedirect(const url::Origin& new_origin) const;
RequestType request_type() const { return request_type_; }
bool IsEmpty() const { return !top_frame_origin_; }
// These may only be nullopt if created by the empty constructor. If one is
// nullopt, both are, and SiteForCookies is null.
//
// Note that these are the values the IsolationInfo was created with. In the
// case an IsolationInfo was created from a NetworkIsolationKey, they may be
// scheme + eTLD+1 instead of actual origins.
const absl::optional<url::Origin>& top_frame_origin() const {
return top_frame_origin_;
}
const absl::optional<url::Origin>& frame_origin() const;
const NetworkIsolationKey& network_isolation_key() const {
return network_isolation_key_;
}
const NetworkAnonymizationKey& network_anonymization_key() const {
return network_anonymization_key_;
}
const absl::optional<base::UnguessableToken>& nonce() const { return nonce_; }
// The value that should be consulted for the third-party cookie blocking
// policy, as defined in Section 2.1.1 and 2.1.2 of
// https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site.
//
// WARNING: This value must only be used for the third-party cookie blocking
// policy. It MUST NEVER be used for any kind of SECURITY check.
const SiteForCookies& site_for_cookies() const { return site_for_cookies_; }
// Do not use outside of testing. Returns the `frame_origin_`.
const absl::optional<url::Origin>& frame_origin_for_testing() const;
bool IsEqualForTesting(const IsolationInfo& other) const;
NetworkAnonymizationKey CreateNetworkAnonymizationKeyForIsolationInfo(
const absl::optional<url::Origin>& top_frame_origin,
const absl::optional<url::Origin>& frame_origin,
const absl::optional<base::UnguessableToken>& nonce) const;
// Serialize the `IsolationInfo` into a string. Fails if transient, returning
// an empty string.
std::string Serialize() const;
std::string DebugString() const;
private:
IsolationInfo(RequestType request_type,
const absl::optional<url::Origin>& top_frame_origin,
const absl::optional<url::Origin>& frame_origin,
const SiteForCookies& site_for_cookies,
const absl::optional<base::UnguessableToken>& nonce);
RequestType request_type_;
absl::optional<url::Origin> top_frame_origin_;
absl::optional<url::Origin> frame_origin_;
// This can be deduced from the two origins above, but keep a cached version
// to avoid repeated eTLD+1 calculations, when this is using eTLD+1.
NetworkIsolationKey network_isolation_key_;
NetworkAnonymizationKey network_anonymization_key_;
SiteForCookies site_for_cookies_;
// Having a nonce is a way to force a transient opaque `IsolationInfo`
// for non-opaque origins.
absl::optional<base::UnguessableToken> nonce_;
// Mojo serialization code needs to access internal fields.
friend struct mojo::StructTraits<network::mojom::IsolationInfoDataView,
IsolationInfo>;
};
} // namespace net
#endif // NET_BASE_ISOLATION_INFO_H_
|