blob: 4205767bb7fe997d322efb9b8857ada89bfbf39d [file] [log] [blame]
mkwst9f2cc892015-07-22 06:03:251// Copyright 2015 The Chromium Authors. All rights reserved.
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 URL_ORIGIN_H_
6#define URL_ORIGIN_H_
7
avic0c60312015-12-21 21:03:508#include <stdint.h>
9
mkwst9f2cc892015-07-22 06:03:2510#include <string>
11
Staphany Park6fd74a22018-12-04 21:15:4112#include "base/component_export.h"
Lukasz Anforowicz3d58b9392018-01-05 20:56:2213#include "base/debug/alias.h"
Daniel Cheng62ff0182018-08-25 07:59:3314#include "base/optional.h"
mkwst9f2cc892015-07-22 06:03:2515#include "base/strings/string16.h"
mkwstd8335d982015-07-25 05:18:4816#include "base/strings/string_piece.h"
Daniel Cheng62ff0182018-08-25 07:59:3317#include "base/strings/string_util.h"
18#include "base/unguessable_token.h"
Nasko Oskovd9e41d52018-09-27 23:12:4219#include "ipc/ipc_param_traits.h"
mkwst9f2cc892015-07-22 06:03:2520#include "url/scheme_host_port.h"
21#include "url/third_party/mozilla/url_parse.h"
22#include "url/url_canon.h"
23#include "url/url_constants.h"
mkwst9f2cc892015-07-22 06:03:2524
25class GURL;
26
Nasko Oskov99445acd2018-10-10 16:46:0027namespace blink {
28class SecurityOrigin;
29} // namespace blink
30
Nasko Oskov9277dfc2018-09-17 23:20:5431namespace ipc_fuzzer {
32template <class T>
33struct FuzzTraits;
34} // namespace ipc_fuzzer
35
Nasko Oskovd9e41d52018-09-27 23:12:4236namespace mojo {
37template <typename DataViewType, typename T>
38struct StructTraits;
Nasko Oskov99445acd2018-10-10 16:46:0039struct UrlOriginAdapter;
Nasko Oskovd9e41d52018-09-27 23:12:4240} // namespace mojo
41
mkwst9f2cc892015-07-22 06:03:2542namespace url {
43
Nasko Oskovd9e41d52018-09-27 23:12:4244namespace mojom {
45class OriginDataView;
46} // namespace mojom
47
Daniel Cheng62ff0182018-08-25 07:59:3348// Per https://html.spec.whatwg.org/multipage/origin.html#origin, an origin is
49// either:
50// - a tuple origin of (scheme, host, port) as described in RFC 6454.
Nasko Oskov9277dfc2018-09-17 23:20:5451// - an opaque origin with an internal value, and a memory of the tuple origin
52// from which it was derived.
mkwst9f2cc892015-07-22 06:03:2553//
54// TL;DR: If you need to make a security-relevant decision, use 'url::Origin'.
55// If you only need to extract the bits of a URL which are relevant for a
56// network connection, use 'url::SchemeHostPort'.
57//
58// STL;SDR: If you aren't making actual network connections, use 'url::Origin'.
59//
mkwst9f2cc892015-07-22 06:03:2560// This class ought to be used when code needs to determine if two resources
61// are "same-origin", and when a canonical serialization of an origin is
Daniel Cheng62ff0182018-08-25 07:59:3362// required. Note that the canonical serialization of an origin *must not* be
63// used to determine if two resources are same-origin.
64//
65// A tuple origin, like 'SchemeHostPort', is composed of a tuple of (scheme,
66// host, port), but contains a number of additional concepts which make it
67// appropriate for use as a security boundary and access control mechanism
68// between contexts. Two tuple origins are same-origin if the tuples are equal.
69// A tuple origin may also be re-created from its serialization.
70//
Nasko Oskov9277dfc2018-09-17 23:20:5471// An opaque origin has an internal globally unique identifier. When creating a
72// new opaque origin from a URL, a fresh globally unique identifier is
73// generated. However, if an opaque origin is copied or moved, the internal
74// globally unique identifier is preserved. Two opaque origins are same-origin
75// iff the globally unique identifiers match. Unlike tuple origins, an opaque
76// origin cannot be re-created from its serialization, which is always the
77// string "null".
Daniel Cheng62ff0182018-08-25 07:59:3378//
79// IMPORTANT: Since opaque origins always serialize as the string "null", it is
80// *never* safe to use the serialization for security checks!
81//
82// A tuple origin and an opaque origin are never same-origin.
mkwst9f2cc892015-07-22 06:03:2583//
84// There are a few subtleties to note:
85//
Nasko Oskov9277dfc2018-09-17 23:20:5486// * A default constructed Origin is opaque, with no precursor origin.
Daniel Cheng62ff0182018-08-25 07:59:3387//
88// * Invalid and non-standard GURLs are parsed as opaque origins. This includes
mkwst9f2cc892015-07-22 06:03:2589// non-hierarchical URLs like 'data:text/html,...' and 'javascript:alert(1)'.
90//
91// * GURLs with schemes of 'filesystem' or 'blob' parse the origin out of the
92// internals of the URL. That is, 'filesystem:https://example.com/temporary/f'
93// is parsed as ('https', 'example.com', 443).
94//
mkwst9f2cc892015-07-22 06:03:2595// * GURLs with a 'file' scheme are tricky. They are parsed as ('file', '', 0),
96// but their behavior may differ from embedder to embedder.
Daniel Cheng62ff0182018-08-25 07:59:3397// TODO(dcheng): This behavior is not consistent with Blink's notion of file
98// URLs, which always creates an opaque origin.
mkwst9f2cc892015-07-22 06:03:2599//
100// * The host component of an IPv6 address includes brackets, just like the URL
101// representation.
102//
103// Usage:
104//
105// * Origins are generally constructed from an already-canonicalized GURL:
106//
107// GURL url("https://example.com/");
Daniel Vogelheimdf4cf9e2018-06-14 11:42:40108// url::Origin origin = Origin::Create(url);
mkwst9f2cc892015-07-22 06:03:25109// origin.scheme(); // "https"
110// origin.host(); // "example.com"
111// origin.port(); // 443
Chris Palmerab5e5b52018-09-28 19:19:30112// origin.opaque(); // false
mkwst9f2cc892015-07-22 06:03:25113//
114// * To answer the question "Are |this| and |that| "same-origin" with each
115// other?", use |Origin::IsSameOriginWith|:
116//
117// if (this.IsSameOriginWith(that)) {
118// // Amazingness goes here.
119// }
Staphany Park6fd74a22018-12-04 21:15:41120class COMPONENT_EXPORT(URL) Origin {
mkwst9f2cc892015-07-22 06:03:25121 public:
Nasko Oskov9277dfc2018-09-17 23:20:54122 // Creates an opaque Origin with a nonce that is different from all previously
123 // existing origins.
mkwst9f2cc892015-07-22 06:03:25124 Origin();
125
126 // Creates an Origin from |url|, as described at
127 // https://url.spec.whatwg.org/#origin, with the following additions:
128 //
Daniel Cheng62ff0182018-08-25 07:59:33129 // 1. If |url| is invalid or non-standard, an opaque Origin is constructed.
mkwst9f2cc892015-07-22 06:03:25130 // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed
131 // out of everything in the URL which follows the scheme).
132 // 3. 'file' URLs all parse as ("file", "", 0).
Daniel Cheng88186bd52017-10-20 08:14:46133 static Origin Create(const GURL& url);
mkwst9f2cc892015-07-22 06:03:25134
Nasko Oskov9277dfc2018-09-17 23:20:54135 // Creates an Origin for the resource |url| as if it were requested
136 // from the context of |base_origin|. If |url| is standard
137 // (in the sense that it embeds a complete origin, like http/https),
138 // this returns the same value as would Create().
139 //
140 // If |url| is "about:blank", this returns a copy of |base_origin|.
141 //
142 // Otherwise, returns a new opaque origin derived from |base_origin|.
143 // In this case, the resulting opaque origin will inherit the tuple
144 // (or precursor tuple) of |base_origin|, but will not be same origin
145 // with |base_origin|, even if |base_origin| is already opaque.
146 static Origin Resolve(const GURL& url, const Origin& base_origin);
147
John Melloref62bce2017-10-04 11:25:33148 // Copyable and movable.
Daniel Cheng6ae11ad72017-10-17 20:42:33149 Origin(const Origin&);
150 Origin& operator=(const Origin&);
151 Origin(Origin&&);
152 Origin& operator=(Origin&&);
John Melloref62bce2017-10-04 11:25:33153
Takashi Toyoshima5641d7552018-02-09 08:57:52154 // Creates an Origin from a |scheme|, |host|, and |port|. All the parameters
Nasko Oskov9277dfc2018-09-17 23:20:54155 // must be valid and canonicalized. Returns nullopt if any parameter is not
156 // canonical, or if all the parameters are empty.
mkwstd8335d982015-07-25 05:18:48157 //
158 // This constructor should be used in order to pass 'Origin' objects back and
159 // forth over IPC (as transitioning through GURL would risk potentially
160 // dangerous recanonicalization); other potential callers should prefer the
161 // 'GURL'-based constructor.
Nasko Oskov9277dfc2018-09-17 23:20:54162 static base::Optional<Origin> UnsafelyCreateTupleOriginWithoutNormalization(
mkwstd8335d982015-07-25 05:18:48163 base::StringPiece scheme,
164 base::StringPiece host,
Takashi Toyoshima5641d7552018-02-09 08:57:52165 uint16_t port);
mkwstd8335d982015-07-25 05:18:48166
csharrisonedf893f2016-10-12 01:42:56167 // Creates an origin without sanity checking that the host is canonicalized.
168 // This should only be used when converting between already normalized types,
csharrisonf07ac3c2016-12-13 04:15:02169 // and should NOT be used for IPC. Method takes std::strings for use with move
170 // operators to avoid copies.
Takashi Toyoshima5641d7552018-02-09 08:57:52171 static Origin CreateFromNormalizedTuple(std::string scheme,
172 std::string host,
173 uint16_t port);
jww908428c2016-10-26 21:51:46174
mkwst9f2cc892015-07-22 06:03:25175 ~Origin();
176
Daniel Cheng62ff0182018-08-25 07:59:33177 // For opaque origins, these return ("", "", 0).
178 const std::string& scheme() const {
Chris Palmerab5e5b52018-09-28 19:19:30179 return !opaque() ? tuple_.scheme() : base::EmptyString();
Daniel Cheng62ff0182018-08-25 07:59:33180 }
181 const std::string& host() const {
Chris Palmerab5e5b52018-09-28 19:19:30182 return !opaque() ? tuple_.host() : base::EmptyString();
Daniel Cheng62ff0182018-08-25 07:59:33183 }
Chris Palmerab5e5b52018-09-28 19:19:30184 uint16_t port() const { return !opaque() ? tuple_.port() : 0; }
mkwst9f2cc892015-07-22 06:03:25185
Chris Palmerab5e5b52018-09-28 19:19:30186 bool opaque() const { return nonce_.has_value(); }
mkwst9f2cc892015-07-22 06:03:25187
188 // An ASCII serialization of the Origin as per Section 6.2 of RFC 6454, with
189 // the addition that all Origins with a 'file' scheme serialize to "file://".
190 std::string Serialize() const;
191
Nasko Oskov9277dfc2018-09-17 23:20:54192 // Two non-opaque Origins are "same-origin" if their schemes, hosts, and ports
193 // are exact matches. Two opaque origins are same-origin only if their
194 // internal nonce values match. A non-opaque origin is never same-origin with
195 // an opaque origin.
mkwst9f2cc892015-07-22 06:03:25196 bool IsSameOriginWith(const Origin& other) const;
Nasko Oskov9277dfc2018-09-17 23:20:54197 bool operator==(const Origin& other) const { return IsSameOriginWith(other); }
198 bool operator!=(const Origin& other) const {
199 return !IsSameOriginWith(other);
200 }
201
202 // Get the scheme, host, and port from which this origin derives. For
203 // a tuple Origin, this gives the same values as calling scheme(), host()
204 // and port(). For an opaque Origin that was created by calling
205 // Origin::DeriveNewOpaqueOrigin() on a precursor or Origin::Resolve(),
206 // this returns the tuple inherited from the precursor.
207 //
208 // If this Origin is opaque and was created via the default constructor or
209 // Origin::Create(), the precursor origin is unknown.
210 //
211 // Use with great caution: opaque origins should generally not inherit
212 // privileges from the origins they derive from. However, in some cases
213 // (such as restrictions on process placement, or determining the http lock
214 // icon) this information may be relevant to ensure that entering an
215 // opaque origin does not grant privileges initially denied to the original
216 // non-opaque origin.
217 //
218 // This method has a deliberately obnoxious name to prompt caution in its use.
219 const SchemeHostPort& GetTupleOrPrecursorTupleIfOpaque() const {
220 return tuple_;
mek0126c132016-02-17 23:50:59221 }
mkwst9f2cc892015-07-22 06:03:25222
csharrison048bee12016-10-04 00:08:21223 // Efficiently returns what GURL(Serialize()) would without re-parsing the
224 // URL. This can be used for the (rare) times a GURL representation is needed
225 // for an Origin.
226 // Note: The returned URL will not necessarily be serialized to the same value
227 // as the Origin would. The GURL will have an added "/" path for Origins with
228 // valid SchemeHostPorts and file Origins.
Charles Harrisonc5f8c91b2017-08-22 18:08:24229 //
230 // Try not to use this method under normal circumstances, as it loses type
231 // information. Downstream consumers can mistake the returned GURL with a full
232 // URL (e.g. with a path component).
csharrison048bee12016-10-04 00:08:21233 GURL GetURL() const;
234
Chris Palmerab5e5b52018-09-28 19:19:30235 // Same as GURL::DomainIs. If |this| origin is opaque, then returns false.
Charles Harrison81dc2fb2017-08-30 23:41:12236 bool DomainIs(base::StringPiece canonical_domain) const;
pkalinnikov054f4032016-08-31 10:54:17237
nick1466c842015-11-25 20:08:06238 // Allows Origin to be used as a key in STL (for example, a std::set or
mkwst9f2cc892015-07-22 06:03:25239 // std::map).
240 bool operator<(const Origin& other) const;
241
Daniel Cheng62ff0182018-08-25 07:59:33242 // Creates a new opaque origin that is guaranteed to be cross-origin to all
243 // currently existing origins. An origin created by this method retains its
244 // identity across copies. Copies are guaranteed to be same-origin to each
245 // other, e.g.
246 //
Nasko Oskov9277dfc2018-09-17 23:20:54247 // url::Origin page = Origin::Create(GURL("http://example.com"))
248 // url::Origin a = page.DeriveNewOpaqueOrigin();
249 // url::Origin b = page.DeriveNewOpaqueOrigin();
Daniel Cheng62ff0182018-08-25 07:59:33250 // url::Origin c = a;
251 // url::Origin d = b;
252 //
253 // |a| and |c| are same-origin, since |c| was copied from |a|. |b| and |d| are
254 // same-origin as well, since |d| was copied from |b|. All other combinations
255 // of origins are considered cross-origin, e.g. |a| is cross-origin to |b| and
256 // |d|, |b| is cross-origin to |a| and |c|, |c| is cross-origin to |b| and
257 // |d|, and |d| is cross-origin to |a| and |c|.
Nasko Oskov9277dfc2018-09-17 23:20:54258 Origin DeriveNewOpaqueOrigin() const;
259
260 private:
Nasko Oskov99445acd2018-10-10 16:46:00261 friend class blink::SecurityOrigin;
Nasko Oskov9277dfc2018-09-17 23:20:54262 friend class OriginTest;
Nasko Oskov99445acd2018-10-10 16:46:00263 friend struct mojo::UrlOriginAdapter;
Nasko Oskov9277dfc2018-09-17 23:20:54264 friend struct ipc_fuzzer::FuzzTraits<Origin>;
Nasko Oskovd9e41d52018-09-27 23:12:42265 friend struct mojo::StructTraits<url::mojom::OriginDataView, url::Origin>;
Nasko Oskov99445acd2018-10-10 16:46:00266 friend IPC::ParamTraits<url::Origin>;
Staphany Park6fd74a22018-12-04 21:15:41267 friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
268 const Origin& origin);
Nasko Oskov9277dfc2018-09-17 23:20:54269
270 // Origin::Nonce is a wrapper around base::UnguessableToken that generates
271 // the random value only when the value is first accessed. The lazy generation
272 // allows Origin to be default-constructed quickly, without spending time
273 // in random number generation.
Daniel Cheng62ff0182018-08-25 07:59:33274 //
Nasko Oskov9277dfc2018-09-17 23:20:54275 // TODO(nick): Should this optimization move into UnguessableToken, once it no
276 // longer treats the Null case specially?
Staphany Park6fd74a22018-12-04 21:15:41277 class COMPONENT_EXPORT(URL) Nonce {
Nasko Oskov9277dfc2018-09-17 23:20:54278 public:
279 // Creates a nonce to hold a newly-generated UnguessableToken. The actual
280 // token value will be generated lazily.
281 Nonce();
Daniel Cheng62ff0182018-08-25 07:59:33282
Nasko Oskov9277dfc2018-09-17 23:20:54283 // Creates a nonce to hold an already-generated UnguessableToken value. This
284 // constructor should only be used for IPC serialization and testing --
285 // regular code should never need to touch the UnguessableTokens directly,
286 // and the default constructor is faster.
287 explicit Nonce(const base::UnguessableToken& token);
Daniel Cheng62ff0182018-08-25 07:59:33288
Nasko Oskov9277dfc2018-09-17 23:20:54289 // Accessor, which lazily initializes the underlying |token_| member.
290 const base::UnguessableToken& token() const;
Daniel Cheng62ff0182018-08-25 07:59:33291
Nasko Oskov9277dfc2018-09-17 23:20:54292 // Do not use in cases where lazy initialization is expected! This
293 // accessor does not initialize the |token_| member.
294 const base::UnguessableToken& raw_token() const;
295
296 // Copyable and movable. Copying a Nonce triggers lazy-initialization,
297 // moving it does not.
298 Nonce(const Nonce&);
299 Nonce& operator=(const Nonce&);
300 Nonce(Nonce&&);
301 Nonce& operator=(Nonce&&);
302
303 // Note that operator<, used by maps type containers, will trigger |token_|
304 // lazy-initialization. Equality comparisons do not.
305 bool operator<(const Nonce& other) const;
306 bool operator==(const Nonce& other) const;
307 bool operator!=(const Nonce& other) const;
308
309 private:
310 friend class OriginTest;
311
312 // mutable to support lazy generation.
313 mutable base::UnguessableToken token_;
314 };
315
316 // This needs to be friended within Origin as well, since Nonce is a private
317 // nested class of Origin.
Staphany Park6fd74a22018-12-04 21:15:41318 friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
319 const Nonce& nonce);
Nasko Oskov9277dfc2018-09-17 23:20:54320
321 // Creates an origin without sanity checking that the host is canonicalized.
322 // This should only be used when converting between already normalized types,
323 // and should NOT be used for IPC. Method takes std::strings for use with move
324 // operators to avoid copies.
325 static Origin CreateOpaqueFromNormalizedPrecursorTuple(
326 std::string precursor_scheme,
327 std::string precursor_host,
328 uint16_t precursor_port,
329 const Nonce& nonce);
330
331 // Creates an opaque Origin with the identity given by |nonce|, and an
332 // optional precursor origin given by |precursor_scheme|, |precursor_host| and
333 // |precursor_port|. Returns nullopt if any parameter is not canonical. When
334 // the precursor is unknown, the precursor parameters should be ("", "", 0).
335 //
336 // This factory method should be used in order to pass opaque Origin objects
337 // back and forth over IPC (as transitioning through GURL would risk
338 // potentially dangerous recanonicalization).
339 static base::Optional<Origin> UnsafelyCreateOpaqueOriginWithoutNormalization(
340 base::StringPiece precursor_scheme,
341 base::StringPiece precursor_host,
342 uint16_t precursor_port,
343 const Nonce& nonce);
344
345 // Constructs a non-opaque tuple origin. |tuple| must be valid.
Takashi Toyoshima5641d7552018-02-09 08:57:52346 explicit Origin(SchemeHostPort tuple);
mkwstd8335d982015-07-25 05:18:48347
Nasko Oskov9277dfc2018-09-17 23:20:54348 // Constructs an opaque origin derived from the |precursor| tuple, with the
349 // given |nonce|.
350 Origin(const Nonce& nonce, SchemeHostPort precursor);
351
Chris Palmerab5e5b52018-09-28 19:19:30352 // Get the nonce associated with this origin, if it is opaque. This should be
Nasko Oskov9277dfc2018-09-17 23:20:54353 // used only when trying to send an Origin across an IPC pipe.
354 base::Optional<base::UnguessableToken> GetNonceForSerialization() const;
355
356 // The tuple is used for both tuple origins (e.g. https://example.com:80), as
357 // well as for opaque origins, where it tracks the tuple origin from which
358 // the opaque origin was initially derived (we call this the "precursor"
359 // origin).
mkwst9f2cc892015-07-22 06:03:25360 SchemeHostPort tuple_;
Daniel Cheng62ff0182018-08-25 07:59:33361
362 // The nonce is used for maintaining identity of an opaque origin. This
Nasko Oskov9277dfc2018-09-17 23:20:54363 // nonce is preserved when an opaque origin is copied or moved. An Origin
364 // is considered opaque if and only if |nonce_| holds a value.
365 base::Optional<Nonce> nonce_;
mkwst9f2cc892015-07-22 06:03:25366};
367
Nasko Oskov9277dfc2018-09-17 23:20:54368// Pretty-printers for logging. These expose the internal state of the nonce.
Staphany Park6fd74a22018-12-04 21:15:41369COMPONENT_EXPORT(URL)
370std::ostream& operator<<(std::ostream& out, const Origin& origin);
371COMPONENT_EXPORT(URL)
372std::ostream& operator<<(std::ostream& out, const Origin::Nonce& origin);
palmer5c437bcc2016-02-03 23:21:36373
Staphany Park6fd74a22018-12-04 21:15:41374COMPONENT_EXPORT(URL) bool IsSameOriginWith(const GURL& a, const GURL& b);
mkwst9f2cc892015-07-22 06:03:25375
Lukasz Anforowicz3d58b9392018-01-05 20:56:22376// DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies |origin| into a new
377// stack-allocated variable named |<var_name>|. This helps ensure that the
378// value of |origin| gets preserved in crash dumps.
379#define DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) \
Daniel Chengafbf6352018-04-24 23:59:25380 DEBUG_ALIAS_FOR_CSTR(var_name, (origin).Serialize().c_str(), 128)
Lukasz Anforowicz3d58b9392018-01-05 20:56:22381
mkwst9f2cc892015-07-22 06:03:25382} // namespace url
383
qyearsley2bc727d2015-08-14 20:17:15384#endif // URL_ORIGIN_H_