[go: nahoru, domu]

blob: 3e639b015ba84d582bc3717919ca5d2c105eebea [file] [log] [blame]
Avi Drissman3e1a26c2022-09-15 20:26:031// Copyright 2015 The Chromium Authors
mkwst9f2cc892015-07-22 06:03:252// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef URL_ORIGIN_H_
6#define URL_ORIGIN_H_
7
avic0c60312015-12-21 21:03:508#include <stdint.h>
9
Robert Ogdendd74d732020-03-12 17:33:1910#include <memory>
mkwst9f2cc892015-07-22 06:03:2511#include <string>
David Benjaminbf75caf2023-09-29 04:39:5912#include <string_view>
mkwst9f2cc892015-07-22 06:03:2513
Arthur Sonzogni75165b82023-11-07 18:25:4714#include <optional>
Staphany Park6fd74a22018-12-04 21:15:4115#include "base/component_export.h"
Lukasz Anforowicz3d58b9392018-01-05 20:56:2216#include "base/debug/alias.h"
Lukasz Anforowicz731c39c2020-02-07 23:35:5817#include "base/debug/crash_logging.h"
Ari Chivukula2e5fd082023-01-25 05:34:5918#include "base/gtest_prod_util.h"
Daniel Cheng62ff0182018-08-25 07:59:3319#include "base/strings/string_util.h"
Stefano Duod54f69882023-04-03 15:45:5420#include "base/trace_event/base_tracing_forward.h"
Daniel Cheng62ff0182018-08-25 07:59:3321#include "base/unguessable_token.h"
Rouslan Solomakhin63cdb1482019-09-30 21:53:1422#include "build/build_config.h"
David Sandersf0ac4c92022-04-20 03:09:0023#include "build/buildflag.h"
Andrew Grieve5cec6392023-09-06 14:46:0124#include "build/robolectric_buildflags.h"
mkwst9f2cc892015-07-22 06:03:2525#include "url/scheme_host_port.h"
mkwst9f2cc892015-07-22 06:03:2526
Andrew Grieve5cec6392023-09-06 14:46:0127#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
28#include "base/android/jni_android.h"
29#endif
Rouslan Solomakhin63cdb1482019-09-30 21:53:1430
mkwst9f2cc892015-07-22 06:03:2531class GURL;
32
Nasko Oskov99445acd2018-10-10 16:46:0033namespace blink {
34class SecurityOrigin;
Daniel Cheng8cc870212022-02-04 20:52:2735class SecurityOriginTest;
Ari Chivukula2e5fd082023-01-25 05:34:5936class StorageKey;
37class StorageKeyTest;
Nasko Oskov99445acd2018-10-10 16:46:0038} // namespace blink
39
Sharon Yangb670da6b2023-11-21 02:01:2040namespace content {
41class SiteInfo;
42} // namespace content
43
Stefano Duoe4f33c52022-12-07 13:44:3544namespace IPC {
45template <class P>
46struct ParamTraits;
47} // namespace IPC
48
Nasko Oskov9277dfc2018-09-17 23:20:5449namespace ipc_fuzzer {
50template <class T>
51struct FuzzTraits;
52} // namespace ipc_fuzzer
53
Nasko Oskovd9e41d52018-09-27 23:12:4254namespace mojo {
55template <typename DataViewType, typename T>
56struct StructTraits;
Nasko Oskov99445acd2018-10-10 16:46:0057struct UrlOriginAdapter;
Nasko Oskovd9e41d52018-09-27 23:12:4258} // namespace mojo
59
Robert Ogdendd74d732020-03-12 17:33:1960namespace net {
John Delaney513e53f2020-10-29 20:16:0461class SchemefulSite;
Robert Ogdendd74d732020-03-12 17:33:1962} // namespace net
63
mkwst9f2cc892015-07-22 06:03:2564namespace url {
65
Nasko Oskovd9e41d52018-09-27 23:12:4266namespace mojom {
67class OriginDataView;
68} // namespace mojom
69
Daniel Cheng62ff0182018-08-25 07:59:3370// Per https://html.spec.whatwg.org/multipage/origin.html#origin, an origin is
71// either:
72// - a tuple origin of (scheme, host, port) as described in RFC 6454.
Nasko Oskov9277dfc2018-09-17 23:20:5473// - an opaque origin with an internal value, and a memory of the tuple origin
74// from which it was derived.
mkwst9f2cc892015-07-22 06:03:2575//
76// TL;DR: If you need to make a security-relevant decision, use 'url::Origin'.
77// If you only need to extract the bits of a URL which are relevant for a
78// network connection, use 'url::SchemeHostPort'.
79//
80// STL;SDR: If you aren't making actual network connections, use 'url::Origin'.
81//
mkwst9f2cc892015-07-22 06:03:2582// This class ought to be used when code needs to determine if two resources
83// are "same-origin", and when a canonical serialization of an origin is
Daniel Cheng62ff0182018-08-25 07:59:3384// required. Note that the canonical serialization of an origin *must not* be
85// used to determine if two resources are same-origin.
86//
87// A tuple origin, like 'SchemeHostPort', is composed of a tuple of (scheme,
88// host, port), but contains a number of additional concepts which make it
89// appropriate for use as a security boundary and access control mechanism
90// between contexts. Two tuple origins are same-origin if the tuples are equal.
91// A tuple origin may also be re-created from its serialization.
92//
Nasko Oskov9277dfc2018-09-17 23:20:5493// An opaque origin has an internal globally unique identifier. When creating a
94// new opaque origin from a URL, a fresh globally unique identifier is
95// generated. However, if an opaque origin is copied or moved, the internal
96// globally unique identifier is preserved. Two opaque origins are same-origin
97// iff the globally unique identifiers match. Unlike tuple origins, an opaque
98// origin cannot be re-created from its serialization, which is always the
99// string "null".
Daniel Cheng62ff0182018-08-25 07:59:33100//
101// IMPORTANT: Since opaque origins always serialize as the string "null", it is
102// *never* safe to use the serialization for security checks!
103//
104// A tuple origin and an opaque origin are never same-origin.
mkwst9f2cc892015-07-22 06:03:25105//
106// There are a few subtleties to note:
107//
Nasko Oskov9277dfc2018-09-17 23:20:54108// * A default constructed Origin is opaque, with no precursor origin.
Daniel Cheng62ff0182018-08-25 07:59:33109//
110// * Invalid and non-standard GURLs are parsed as opaque origins. This includes
mkwst9f2cc892015-07-22 06:03:25111// non-hierarchical URLs like 'data:text/html,...' and 'javascript:alert(1)'.
112//
113// * GURLs with schemes of 'filesystem' or 'blob' parse the origin out of the
114// internals of the URL. That is, 'filesystem:https://example.com/temporary/f'
115// is parsed as ('https', 'example.com', 443).
116//
mkwst9f2cc892015-07-22 06:03:25117// * GURLs with a 'file' scheme are tricky. They are parsed as ('file', '', 0),
118// but their behavior may differ from embedder to embedder.
Daniel Cheng62ff0182018-08-25 07:59:33119// TODO(dcheng): This behavior is not consistent with Blink's notion of file
120// URLs, which always creates an opaque origin.
mkwst9f2cc892015-07-22 06:03:25121//
122// * The host component of an IPv6 address includes brackets, just like the URL
123// representation.
124//
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16125// * Constructing origins from GURLs (or from SchemeHostPort) is typically a red
126// flag (this is true for `url::Origin::Create` but also to some extent for
127// `url::Origin::Resolve`). See docs/security/origin-vs-url.md for more.
mkwst9f2cc892015-07-22 06:03:25128//
129// * To answer the question "Are |this| and |that| "same-origin" with each
130// other?", use |Origin::IsSameOriginWith|:
131//
132// if (this.IsSameOriginWith(that)) {
133// // Amazingness goes here.
134// }
Staphany Park6fd74a22018-12-04 21:15:41135class COMPONENT_EXPORT(URL) Origin {
mkwst9f2cc892015-07-22 06:03:25136 public:
Nasko Oskov9277dfc2018-09-17 23:20:54137 // Creates an opaque Origin with a nonce that is different from all previously
138 // existing origins.
mkwst9f2cc892015-07-22 06:03:25139 Origin();
140
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16141 // WARNING: Converting an URL into an Origin is usually a red flag. See
142 // //docs/security/origin-vs-url.md for more details. Some discussion about
143 // deprecating the Create method can be found in https://crbug.com/1270878.
mkwst9f2cc892015-07-22 06:03:25144 //
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16145 // Creates an Origin from `url`, as described at
146 // https://url.spec.whatwg.org/#origin, with the following additions:
147 // 1. If `url` is invalid or non-standard, an opaque Origin is constructed.
mkwst9f2cc892015-07-22 06:03:25148 // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed
149 // out of everything in the URL which follows the scheme).
150 // 3. 'file' URLs all parse as ("file", "", 0).
Lukasz Anforowiczfd7834ec2020-03-04 02:11:57151 //
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16152 // WARNING: `url::Origin::Create(url)` can give unexpected results if:
153 // 1) `url` is "about:blank", or "about:srcdoc" (returning unique, opaque
154 // origin rather than the real origin of the frame)
155 // 2) `url` comes from a sandboxed frame (potentially returning a non-opaque
156 // origin, when an opaque one is needed; see also
157 // https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)
158 // 3) Wrong `url` is used - e.g. in some navigations `base_url_for_data_url`
159 // might need to be used instead of relying on
160 // `content::NavigationHandle::GetURL`.
161 //
162 // WARNING: The returned Origin may have a different scheme and host from
163 // `url` (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL).
164 //
165 // WARNING: data: URLs will be correctly be translated into opaque origins,
166 // but the precursor origin will be lost (unlike with `url::Origin::Resolve`).
Daniel Cheng88186bd52017-10-20 08:14:46167 static Origin Create(const GURL& url);
mkwst9f2cc892015-07-22 06:03:25168
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16169 // Creates an Origin for the resource `url` as if it were requested
170 // from the context of `base_origin`. If `url` is standard
Nasko Oskov9277dfc2018-09-17 23:20:54171 // (in the sense that it embeds a complete origin, like http/https),
172 // this returns the same value as would Create().
173 //
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16174 // If `url` is "about:blank" or "about:srcdoc", this returns a copy of
175 // `base_origin`.
Nasko Oskov9277dfc2018-09-17 23:20:54176 //
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16177 // Otherwise, returns a new opaque origin derived from `base_origin`.
Nasko Oskov9277dfc2018-09-17 23:20:54178 // In this case, the resulting opaque origin will inherit the tuple
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16179 // (or precursor tuple) of `base_origin`, but will not be same origin
180 // with `base_origin`, even if `base_origin` is already opaque.
Nasko Oskov9277dfc2018-09-17 23:20:54181 static Origin Resolve(const GURL& url, const Origin& base_origin);
182
John Melloref62bce2017-10-04 11:25:33183 // Copyable and movable.
Daniel Cheng6ae11ad72017-10-17 20:42:33184 Origin(const Origin&);
185 Origin& operator=(const Origin&);
Victor Costan7c9d0b1482020-07-07 14:13:03186 Origin(Origin&&) noexcept;
187 Origin& operator=(Origin&&) noexcept;
John Melloref62bce2017-10-04 11:25:33188
Takashi Toyoshima5641d7552018-02-09 08:57:52189 // Creates an Origin from a |scheme|, |host|, and |port|. All the parameters
Nasko Oskov9277dfc2018-09-17 23:20:54190 // must be valid and canonicalized. Returns nullopt if any parameter is not
191 // canonical, or if all the parameters are empty.
mkwstd8335d982015-07-25 05:18:48192 //
193 // This constructor should be used in order to pass 'Origin' objects back and
194 // forth over IPC (as transitioning through GURL would risk potentially
195 // dangerous recanonicalization); other potential callers should prefer the
196 // 'GURL'-based constructor.
Arthur Sonzogni75165b82023-11-07 18:25:47197 static std::optional<Origin> UnsafelyCreateTupleOriginWithoutNormalization(
David Benjaminbf75caf2023-09-29 04:39:59198 std::string_view scheme,
199 std::string_view host,
Takashi Toyoshima5641d7552018-02-09 08:57:52200 uint16_t port);
mkwstd8335d982015-07-25 05:18:48201
csharrisonedf893f2016-10-12 01:42:56202 // Creates an origin without sanity checking that the host is canonicalized.
203 // This should only be used when converting between already normalized types,
csharrisonf07ac3c2016-12-13 04:15:02204 // and should NOT be used for IPC. Method takes std::strings for use with move
205 // operators to avoid copies.
Takashi Toyoshima5641d7552018-02-09 08:57:52206 static Origin CreateFromNormalizedTuple(std::string scheme,
207 std::string host,
208 uint16_t port);
jww908428c2016-10-26 21:51:46209
mkwst9f2cc892015-07-22 06:03:25210 ~Origin();
211
Daniel Cheng62ff0182018-08-25 07:59:33212 // For opaque origins, these return ("", "", 0).
213 const std::string& scheme() const {
Chris Palmerab5e5b52018-09-28 19:19:30214 return !opaque() ? tuple_.scheme() : base::EmptyString();
Daniel Cheng62ff0182018-08-25 07:59:33215 }
216 const std::string& host() const {
Chris Palmerab5e5b52018-09-28 19:19:30217 return !opaque() ? tuple_.host() : base::EmptyString();
Daniel Cheng62ff0182018-08-25 07:59:33218 }
Chris Palmerab5e5b52018-09-28 19:19:30219 uint16_t port() const { return !opaque() ? tuple_.port() : 0; }
mkwst9f2cc892015-07-22 06:03:25220
Chris Palmerab5e5b52018-09-28 19:19:30221 bool opaque() const { return nonce_.has_value(); }
mkwst9f2cc892015-07-22 06:03:25222
223 // An ASCII serialization of the Origin as per Section 6.2 of RFC 6454, with
224 // the addition that all Origins with a 'file' scheme serialize to "file://".
225 std::string Serialize() const;
226
Nasko Oskov9277dfc2018-09-17 23:20:54227 // Two non-opaque Origins are "same-origin" if their schemes, hosts, and ports
228 // are exact matches. Two opaque origins are same-origin only if their
229 // internal nonce values match. A non-opaque origin is never same-origin with
230 // an opaque origin.
mkwst9f2cc892015-07-22 06:03:25231 bool IsSameOriginWith(const Origin& other) const;
Nasko Oskov9277dfc2018-09-17 23:20:54232 bool operator==(const Origin& other) const { return IsSameOriginWith(other); }
233 bool operator!=(const Origin& other) const {
234 return !IsSameOriginWith(other);
235 }
236
Lukasz Anforowiczd00c1ed2022-01-13 05:25:10237 // Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16238 // ports are exact matches. Opaque origin is never "same-origin" with any
Lukasz Anforowiczd00c1ed2022-01-13 05:25:10239 // `url`. about:blank, about:srcdoc, and invalid GURLs are never
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16240 // "same-origin" with any origin. This method is a shorthand for
Lukasz Anforowiczd00c1ed2022-01-13 05:25:10241 // `origin.IsSameOriginWith(url::Origin::Create(url))`.
242 //
243 // See also CanBeDerivedFrom.
244 bool IsSameOriginWith(const GURL& url) const;
245
Nasko Oskov97e305f2019-01-05 03:52:10246 // This method returns true for any |url| which if navigated to could result
247 // in an origin compatible with |this|.
248 bool CanBeDerivedFrom(const GURL& url) const;
249
Nasko Oskov9277dfc2018-09-17 23:20:54250 // Get the scheme, host, and port from which this origin derives. For
251 // a tuple Origin, this gives the same values as calling scheme(), host()
252 // and port(). For an opaque Origin that was created by calling
253 // Origin::DeriveNewOpaqueOrigin() on a precursor or Origin::Resolve(),
254 // this returns the tuple inherited from the precursor.
255 //
256 // If this Origin is opaque and was created via the default constructor or
257 // Origin::Create(), the precursor origin is unknown.
258 //
259 // Use with great caution: opaque origins should generally not inherit
260 // privileges from the origins they derive from. However, in some cases
261 // (such as restrictions on process placement, or determining the http lock
262 // icon) this information may be relevant to ensure that entering an
263 // opaque origin does not grant privileges initially denied to the original
264 // non-opaque origin.
265 //
266 // This method has a deliberately obnoxious name to prompt caution in its use.
267 const SchemeHostPort& GetTupleOrPrecursorTupleIfOpaque() const {
268 return tuple_;
mek0126c132016-02-17 23:50:59269 }
mkwst9f2cc892015-07-22 06:03:25270
csharrison048bee12016-10-04 00:08:21271 // Efficiently returns what GURL(Serialize()) would without re-parsing the
272 // URL. This can be used for the (rare) times a GURL representation is needed
273 // for an Origin.
274 // Note: The returned URL will not necessarily be serialized to the same value
275 // as the Origin would. The GURL will have an added "/" path for Origins with
276 // valid SchemeHostPorts and file Origins.
Charles Harrisonc5f8c91b2017-08-22 18:08:24277 //
278 // Try not to use this method under normal circumstances, as it loses type
279 // information. Downstream consumers can mistake the returned GURL with a full
280 // URL (e.g. with a path component).
csharrison048bee12016-10-04 00:08:21281 GURL GetURL() const;
282
Chris Palmerab5e5b52018-09-28 19:19:30283 // Same as GURL::DomainIs. If |this| origin is opaque, then returns false.
David Benjaminbf75caf2023-09-29 04:39:59284 bool DomainIs(std::string_view canonical_domain) const;
pkalinnikov054f4032016-08-31 10:54:17285
nick1466c842015-11-25 20:08:06286 // Allows Origin to be used as a key in STL (for example, a std::set or
mkwst9f2cc892015-07-22 06:03:25287 // std::map).
288 bool operator<(const Origin& other) const;
289
Daniel Cheng62ff0182018-08-25 07:59:33290 // Creates a new opaque origin that is guaranteed to be cross-origin to all
291 // currently existing origins. An origin created by this method retains its
292 // identity across copies. Copies are guaranteed to be same-origin to each
293 // other, e.g.
294 //
Nasko Oskov9277dfc2018-09-17 23:20:54295 // url::Origin page = Origin::Create(GURL("http://example.com"))
296 // url::Origin a = page.DeriveNewOpaqueOrigin();
297 // url::Origin b = page.DeriveNewOpaqueOrigin();
Daniel Cheng62ff0182018-08-25 07:59:33298 // url::Origin c = a;
299 // url::Origin d = b;
300 //
301 // |a| and |c| are same-origin, since |c| was copied from |a|. |b| and |d| are
302 // same-origin as well, since |d| was copied from |b|. All other combinations
303 // of origins are considered cross-origin, e.g. |a| is cross-origin to |b| and
304 // |d|, |b| is cross-origin to |a| and |c|, |c| is cross-origin to |b| and
305 // |d|, and |d| is cross-origin to |a| and |c|.
Nasko Oskov9277dfc2018-09-17 23:20:54306 Origin DeriveNewOpaqueOrigin() const;
307
Sharon Yangb670da6b2023-11-21 02:01:20308 // Returns the nonce associated with the origin, if it is opaque, or nullptr
309 // otherwise. This is only for use in tests.
310 const base::UnguessableToken* GetNonceForTesting() const;
311
Nasko Oskov1ed4e8f2019-02-13 01:39:19312 // Creates a string representation of the object that can be used for logging
313 // and debugging. It serializes the internal state, such as the nonce value
314 // and precursor information.
Lukasz Anforowicz949141f2020-07-08 19:45:34315 std::string GetDebugString(bool include_nonce = true) const;
Nasko Oskov1ed4e8f2019-02-13 01:39:19316
Andrew Grieve5cec6392023-09-06 14:46:01317#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
318 base::android::ScopedJavaLocalRef<jobject> ToJavaObject() const;
Rouslan Solomakhin63cdb1482019-09-30 21:53:14319 static Origin FromJavaObject(
320 const base::android::JavaRef<jobject>& java_origin);
Michael Thiessen6f03acb2022-11-01 03:19:47321 static jlong CreateNative(JNIEnv* env,
322 const base::android::JavaRef<jstring>& java_scheme,
323 const base::android::JavaRef<jstring>& java_host,
324 uint16_t port,
325 bool is_opaque,
326 uint64_t tokenHighBits,
327 uint64_t tokenLowBits);
Xiaohan Wang3b01513a2022-01-20 03:22:55328#endif // BUILDFLAG(IS_ANDROID)
Rouslan Solomakhin63cdb1482019-09-30 21:53:14329
Alexander Timin1b6b2722021-04-21 01:34:27330 void WriteIntoTrace(perfetto::TracedValue context) const;
Alexander Timine4fc8482021-02-10 15:27:46331
Xiaochen Zhou4350e462023-08-21 15:06:12332 // Estimates dynamic memory usage.
333 // See base/trace_event/memory_usage_estimator.h for more info.
334 size_t EstimateMemoryUsage() const;
335
Nasko Oskov9277dfc2018-09-17 23:20:54336 private:
Andrew Grieve5cec6392023-09-06 14:46:01337#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
338 friend Origin CreateOpaqueOriginForAndroid(
339 const std::string& scheme,
340 const std::string& host,
341 uint16_t port,
342 const base::UnguessableToken& nonce_token);
343#endif
Nasko Oskov99445acd2018-10-10 16:46:00344 friend class blink::SecurityOrigin;
Daniel Cheng8cc870212022-02-04 20:52:27345 friend class blink::SecurityOriginTest;
Ari Chivukula2e5fd082023-01-25 05:34:59346 friend class blink::StorageKey;
Sharon Yangb670da6b2023-11-21 02:01:20347 // SiteInfo needs the nonce to compute the site URL for some opaque origins,
348 // like data: URLs.
349 friend class content::SiteInfo;
John Delaney513e53f2020-10-29 20:16:04350 // SchemefulSite needs access to the serialization/deserialization logic which
351 // includes the nonce.
352 friend class net::SchemefulSite;
Nasko Oskov9277dfc2018-09-17 23:20:54353 friend class OriginTest;
Nasko Oskov99445acd2018-10-10 16:46:00354 friend struct mojo::UrlOriginAdapter;
Nasko Oskov9277dfc2018-09-17 23:20:54355 friend struct ipc_fuzzer::FuzzTraits<Origin>;
Nasko Oskovd9e41d52018-09-27 23:12:42356 friend struct mojo::StructTraits<url::mojom::OriginDataView, url::Origin>;
Nasko Oskov99445acd2018-10-10 16:46:00357 friend IPC::ParamTraits<url::Origin>;
Staphany Park6fd74a22018-12-04 21:15:41358 friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
359 const Origin& origin);
Ari Chivukula2e5fd082023-01-25 05:34:59360 friend class blink::StorageKeyTest;
Nasko Oskov9277dfc2018-09-17 23:20:54361
362 // Origin::Nonce is a wrapper around base::UnguessableToken that generates
363 // the random value only when the value is first accessed. The lazy generation
364 // allows Origin to be default-constructed quickly, without spending time
365 // in random number generation.
Daniel Cheng62ff0182018-08-25 07:59:33366 //
Nasko Oskov9277dfc2018-09-17 23:20:54367 // TODO(nick): Should this optimization move into UnguessableToken, once it no
368 // longer treats the Null case specially?
Staphany Park6fd74a22018-12-04 21:15:41369 class COMPONENT_EXPORT(URL) Nonce {
Nasko Oskov9277dfc2018-09-17 23:20:54370 public:
371 // Creates a nonce to hold a newly-generated UnguessableToken. The actual
372 // token value will be generated lazily.
373 Nonce();
Daniel Cheng62ff0182018-08-25 07:59:33374
Nasko Oskov9277dfc2018-09-17 23:20:54375 // Creates a nonce to hold an already-generated UnguessableToken value. This
376 // constructor should only be used for IPC serialization and testing --
377 // regular code should never need to touch the UnguessableTokens directly,
378 // and the default constructor is faster.
379 explicit Nonce(const base::UnguessableToken& token);
Daniel Cheng62ff0182018-08-25 07:59:33380
Nasko Oskov9277dfc2018-09-17 23:20:54381 // Accessor, which lazily initializes the underlying |token_| member.
382 const base::UnguessableToken& token() const;
Daniel Cheng62ff0182018-08-25 07:59:33383
Nasko Oskov9277dfc2018-09-17 23:20:54384 // Do not use in cases where lazy initialization is expected! This
385 // accessor does not initialize the |token_| member.
386 const base::UnguessableToken& raw_token() const;
387
388 // Copyable and movable. Copying a Nonce triggers lazy-initialization,
389 // moving it does not.
390 Nonce(const Nonce&);
391 Nonce& operator=(const Nonce&);
Victor Costan7c9d0b1482020-07-07 14:13:03392 Nonce(Nonce&&) noexcept;
393 Nonce& operator=(Nonce&&) noexcept;
Nasko Oskov9277dfc2018-09-17 23:20:54394
395 // Note that operator<, used by maps type containers, will trigger |token_|
396 // lazy-initialization. Equality comparisons do not.
397 bool operator<(const Nonce& other) const;
398 bool operator==(const Nonce& other) const;
399 bool operator!=(const Nonce& other) const;
400
401 private:
402 friend class OriginTest;
403
404 // mutable to support lazy generation.
405 mutable base::UnguessableToken token_;
406 };
407
408 // This needs to be friended within Origin as well, since Nonce is a private
409 // nested class of Origin.
Staphany Park6fd74a22018-12-04 21:15:41410 friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
411 const Nonce& nonce);
Nasko Oskov9277dfc2018-09-17 23:20:54412
413 // Creates an origin without sanity checking that the host is canonicalized.
414 // This should only be used when converting between already normalized types,
415 // and should NOT be used for IPC. Method takes std::strings for use with move
416 // operators to avoid copies.
417 static Origin CreateOpaqueFromNormalizedPrecursorTuple(
418 std::string precursor_scheme,
419 std::string precursor_host,
420 uint16_t precursor_port,
421 const Nonce& nonce);
422
423 // Creates an opaque Origin with the identity given by |nonce|, and an
424 // optional precursor origin given by |precursor_scheme|, |precursor_host| and
425 // |precursor_port|. Returns nullopt if any parameter is not canonical. When
426 // the precursor is unknown, the precursor parameters should be ("", "", 0).
427 //
428 // This factory method should be used in order to pass opaque Origin objects
429 // back and forth over IPC (as transitioning through GURL would risk
430 // potentially dangerous recanonicalization).
Arthur Sonzogni75165b82023-11-07 18:25:47431 static std::optional<Origin> UnsafelyCreateOpaqueOriginWithoutNormalization(
David Benjaminbf75caf2023-09-29 04:39:59432 std::string_view precursor_scheme,
433 std::string_view precursor_host,
Nasko Oskov9277dfc2018-09-17 23:20:54434 uint16_t precursor_port,
435 const Nonce& nonce);
436
437 // Constructs a non-opaque tuple origin. |tuple| must be valid.
Takashi Toyoshima5641d7552018-02-09 08:57:52438 explicit Origin(SchemeHostPort tuple);
mkwstd8335d982015-07-25 05:18:48439
Nasko Oskov9277dfc2018-09-17 23:20:54440 // Constructs an opaque origin derived from the |precursor| tuple, with the
441 // given |nonce|.
442 Origin(const Nonce& nonce, SchemeHostPort precursor);
443
Daniel Chengb38154b32022-03-03 19:46:21444 // Get the nonce associated with this origin, if it is opaque, or nullptr
445 // otherwise. This should be used only when trying to send an Origin across an
446 // IPC pipe.
447 const base::UnguessableToken* GetNonceForSerialization() const;
Nasko Oskov9277dfc2018-09-17 23:20:54448
Robert Ogdendd74d732020-03-12 17:33:19449 // Serializes this Origin, including its nonce if it is opaque. If an opaque
John Delaney513e53f2020-10-29 20:16:04450 // origin's |tuple_| is invalid nullopt is returned. If the nonce is not
451 // initialized, a nonce of 0 is used. Use of this method should be limited as
452 // an opaque origin will never be matchable in future browser sessions.
Arthur Sonzogni75165b82023-11-07 18:25:47453 std::optional<std::string> SerializeWithNonce() const;
Robert Ogdendd74d732020-03-12 17:33:19454
John Delaney513e53f2020-10-29 20:16:04455 // Like SerializeWithNonce(), but forces |nonce_| to be initialized prior to
456 // serializing.
Arthur Sonzogni75165b82023-11-07 18:25:47457 std::optional<std::string> SerializeWithNonceAndInitIfNeeded();
John Delaney513e53f2020-10-29 20:16:04458
Arthur Sonzogni75165b82023-11-07 18:25:47459 std::optional<std::string> SerializeWithNonceImpl() const;
John Delaney513e53f2020-10-29 20:16:04460
Robert Ogdendd74d732020-03-12 17:33:19461 // Deserializes an origin from |ToValueWithNonce|. Returns nullopt if the
462 // value was invalid in any way.
Arthur Sonzogni75165b82023-11-07 18:25:47463 static std::optional<Origin> Deserialize(const std::string& value);
Robert Ogdendd74d732020-03-12 17:33:19464
Nasko Oskov9277dfc2018-09-17 23:20:54465 // The tuple is used for both tuple origins (e.g. https://example.com:80), as
466 // well as for opaque origins, where it tracks the tuple origin from which
467 // the opaque origin was initially derived (we call this the "precursor"
468 // origin).
mkwst9f2cc892015-07-22 06:03:25469 SchemeHostPort tuple_;
Daniel Cheng62ff0182018-08-25 07:59:33470
471 // The nonce is used for maintaining identity of an opaque origin. This
Nasko Oskov9277dfc2018-09-17 23:20:54472 // nonce is preserved when an opaque origin is copied or moved. An Origin
473 // is considered opaque if and only if |nonce_| holds a value.
Arthur Sonzogni75165b82023-11-07 18:25:47474 std::optional<Nonce> nonce_;
mkwst9f2cc892015-07-22 06:03:25475};
476
Nasko Oskov9277dfc2018-09-17 23:20:54477// Pretty-printers for logging. These expose the internal state of the nonce.
Staphany Park6fd74a22018-12-04 21:15:41478COMPONENT_EXPORT(URL)
479std::ostream& operator<<(std::ostream& out, const Origin& origin);
480COMPONENT_EXPORT(URL)
481std::ostream& operator<<(std::ostream& out, const Origin::Nonce& origin);
palmer5c437bcc2016-02-03 23:21:36482
Staphany Park6fd74a22018-12-04 21:15:41483COMPONENT_EXPORT(URL) bool IsSameOriginWith(const GURL& a, const GURL& b);
mkwst9f2cc892015-07-22 06:03:25484
Lukasz Anforowiczcfe9b2f62022-05-25 15:47:16485// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies `origin` into a new
486// stack-allocated variable named `<var_name>`. This helps ensure that the
487// value of `origin` gets preserved in crash dumps.
Lukasz Anforowicz3d58b9392018-01-05 20:56:22488#define DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) \
Daniel Chengafbf6352018-04-24 23:59:25489 DEBUG_ALIAS_FOR_CSTR(var_name, (origin).Serialize().c_str(), 128)
Lukasz Anforowicz3d58b9392018-01-05 20:56:22490
Lukasz Anforowicz731c39c2020-02-07 23:35:58491namespace debug {
492
Lukasz Anforowicz36d24d32022-02-15 19:02:53493class COMPONENT_EXPORT(URL) ScopedOriginCrashKey {
Lukasz Anforowicz731c39c2020-02-07 23:35:58494 public:
495 ScopedOriginCrashKey(base::debug::CrashKeyString* crash_key,
496 const url::Origin* value);
497 ~ScopedOriginCrashKey();
498
499 ScopedOriginCrashKey(const ScopedOriginCrashKey&) = delete;
500 ScopedOriginCrashKey& operator=(const ScopedOriginCrashKey&) = delete;
Lukasz Anforowicz36d24d32022-02-15 19:02:53501
502 private:
503 base::debug::ScopedCrashKeyString scoped_string_value_;
Lukasz Anforowicz731c39c2020-02-07 23:35:58504};
505
506} // namespace debug
507
mkwst9f2cc892015-07-22 06:03:25508} // namespace url
509
qyearsley2bc727d2015-08-14 20:17:15510#endif // URL_ORIGIN_H_