Fix for Geolocation webTCT failures
[platform/framework/web/chromium-efl.git] / url / origin.h
1 // Copyright 2015 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 URL_ORIGIN_H_
6 #define URL_ORIGIN_H_
7
8 #include <stdint.h>
9
10 #include <memory>
11 #include <string>
12 #include <string_view>
13
14 #include "base/component_export.h"
15 #include "base/debug/alias.h"
16 #include "base/debug/crash_logging.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/strings/string_util.h"
19 #include "base/trace_event/base_tracing_forward.h"
20 #include "base/unguessable_token.h"
21 #include "build/build_config.h"
22 #include "build/buildflag.h"
23 #include "build/robolectric_buildflags.h"
24 #include "third_party/abseil-cpp/absl/types/optional.h"
25 #include "url/scheme_host_port.h"
26
27 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
28 #include "base/android/jni_android.h"
29 #endif
30
31 class GURL;
32
33 namespace blink {
34 class SecurityOrigin;
35 class SecurityOriginTest;
36 class StorageKey;
37 class StorageKeyTest;
38 }  // namespace blink
39
40 namespace IPC {
41 template <class P>
42 struct ParamTraits;
43 }  // namespace IPC
44
45 namespace ipc_fuzzer {
46 template <class T>
47 struct FuzzTraits;
48 }  // namespace ipc_fuzzer
49
50 namespace mojo {
51 template <typename DataViewType, typename T>
52 struct StructTraits;
53 struct UrlOriginAdapter;
54 }  // namespace mojo
55
56 namespace net {
57 class SchemefulSite;
58 }  // namespace net
59
60 namespace url {
61
62 namespace mojom {
63 class OriginDataView;
64 }  // namespace mojom
65
66 // Per https://html.spec.whatwg.org/multipage/origin.html#origin, an origin is
67 // either:
68 // - a tuple origin of (scheme, host, port) as described in RFC 6454.
69 // - an opaque origin with an internal value, and a memory of the tuple origin
70 //   from which it was derived.
71 //
72 // TL;DR: If you need to make a security-relevant decision, use 'url::Origin'.
73 // If you only need to extract the bits of a URL which are relevant for a
74 // network connection, use 'url::SchemeHostPort'.
75 //
76 // STL;SDR: If you aren't making actual network connections, use 'url::Origin'.
77 //
78 // This class ought to be used when code needs to determine if two resources
79 // are "same-origin", and when a canonical serialization of an origin is
80 // required. Note that the canonical serialization of an origin *must not* be
81 // used to determine if two resources are same-origin.
82 //
83 // A tuple origin, like 'SchemeHostPort', is composed of a tuple of (scheme,
84 // host, port), but contains a number of additional concepts which make it
85 // appropriate for use as a security boundary and access control mechanism
86 // between contexts. Two tuple origins are same-origin if the tuples are equal.
87 // A tuple origin may also be re-created from its serialization.
88 //
89 // An opaque origin has an internal globally unique identifier. When creating a
90 // new opaque origin from a URL, a fresh globally unique identifier is
91 // generated. However, if an opaque origin is copied or moved, the internal
92 // globally unique identifier is preserved. Two opaque origins are same-origin
93 // iff the globally unique identifiers match. Unlike tuple origins, an opaque
94 // origin cannot be re-created from its serialization, which is always the
95 // string "null".
96 //
97 // IMPORTANT: Since opaque origins always serialize as the string "null", it is
98 // *never* safe to use the serialization for security checks!
99 //
100 // A tuple origin and an opaque origin are never same-origin.
101 //
102 // There are a few subtleties to note:
103 //
104 // * A default constructed Origin is opaque, with no precursor origin.
105 //
106 // * Invalid and non-standard GURLs are parsed as opaque origins. This includes
107 //   non-hierarchical URLs like 'data:text/html,...' and 'javascript:alert(1)'.
108 //
109 // * GURLs with schemes of 'filesystem' or 'blob' parse the origin out of the
110 //   internals of the URL. That is, 'filesystem:https://example.com/temporary/f'
111 //   is parsed as ('https', 'example.com', 443).
112 //
113 // * GURLs with a 'file' scheme are tricky. They are parsed as ('file', '', 0),
114 //   but their behavior may differ from embedder to embedder.
115 //   TODO(dcheng): This behavior is not consistent with Blink's notion of file
116 //   URLs, which always creates an opaque origin.
117 //
118 // * The host component of an IPv6 address includes brackets, just like the URL
119 //   representation.
120 //
121 // * Constructing origins from GURLs (or from SchemeHostPort) is typically a red
122 //   flag (this is true for `url::Origin::Create` but also to some extent for
123 //   `url::Origin::Resolve`). See docs/security/origin-vs-url.md for more.
124 //
125 // * To answer the question "Are |this| and |that| "same-origin" with each
126 //   other?", use |Origin::IsSameOriginWith|:
127 //
128 //     if (this.IsSameOriginWith(that)) {
129 //       // Amazingness goes here.
130 //     }
131 class COMPONENT_EXPORT(URL) Origin {
132  public:
133   // Creates an opaque Origin with a nonce that is different from all previously
134   // existing origins.
135   Origin();
136
137   // WARNING: Converting an URL into an Origin is usually a red flag. See
138   // //docs/security/origin-vs-url.md for more details. Some discussion about
139   // deprecating the Create method can be found in https://crbug.com/1270878.
140   //
141   // Creates an Origin from `url`, as described at
142   // https://url.spec.whatwg.org/#origin, with the following additions:
143   // 1. If `url` is invalid or non-standard, an opaque Origin is constructed.
144   // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed
145   //    out of everything in the URL which follows the scheme).
146   // 3. 'file' URLs all parse as ("file", "", 0).
147   //
148   // WARNING: `url::Origin::Create(url)` can give unexpected results if:
149   // 1) `url` is "about:blank", or "about:srcdoc" (returning unique, opaque
150   //    origin rather than the real origin of the frame)
151   // 2) `url` comes from a sandboxed frame (potentially returning a non-opaque
152   //    origin, when an opaque one is needed; see also
153   //    https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)
154   // 3) Wrong `url` is used - e.g. in some navigations `base_url_for_data_url`
155   //    might need to be used instead of relying on
156   //    `content::NavigationHandle::GetURL`.
157   //
158   // WARNING: The returned Origin may have a different scheme and host from
159   // `url` (e.g. in case of blob URLs - see OriginTest.ConstructFromGURL).
160   //
161   // WARNING: data: URLs will be correctly be translated into opaque origins,
162   // but the precursor origin will be lost (unlike with `url::Origin::Resolve`).
163   static Origin Create(const GURL& url);
164
165   // Creates an Origin for the resource `url` as if it were requested
166   // from the context of `base_origin`. If `url` is standard
167   // (in the sense that it embeds a complete origin, like http/https),
168   // this returns the same value as would Create().
169   //
170   // If `url` is "about:blank" or "about:srcdoc", this returns a copy of
171   // `base_origin`.
172   //
173   // Otherwise, returns a new opaque origin derived from `base_origin`.
174   // In this case, the resulting opaque origin will inherit the tuple
175   // (or precursor tuple) of `base_origin`, but will not be same origin
176   // with `base_origin`, even if `base_origin` is already opaque.
177   static Origin Resolve(const GURL& url, const Origin& base_origin);
178
179   // Copyable and movable.
180   Origin(const Origin&);
181   Origin& operator=(const Origin&);
182   Origin(Origin&&) noexcept;
183   Origin& operator=(Origin&&) noexcept;
184
185   // Creates an Origin from a |scheme|, |host|, and |port|. All the parameters
186   // must be valid and canonicalized. Returns nullopt if any parameter is not
187   // canonical, or if all the parameters are empty.
188   //
189   // This constructor should be used in order to pass 'Origin' objects back and
190   // forth over IPC (as transitioning through GURL would risk potentially
191   // dangerous recanonicalization); other potential callers should prefer the
192   // 'GURL'-based constructor.
193   static absl::optional<Origin> UnsafelyCreateTupleOriginWithoutNormalization(
194       std::string_view scheme,
195       std::string_view host,
196       uint16_t port);
197
198   // Creates an origin without sanity checking that the host is canonicalized.
199   // This should only be used when converting between already normalized types,
200   // and should NOT be used for IPC. Method takes std::strings for use with move
201   // operators to avoid copies.
202   static Origin CreateFromNormalizedTuple(std::string scheme,
203                                           std::string host,
204                                           uint16_t port);
205
206   ~Origin();
207
208   // For opaque origins, these return ("", "", 0).
209   const std::string& scheme() const {
210     return !opaque() ? tuple_.scheme() : base::EmptyString();
211   }
212   const std::string& host() const {
213     return !opaque() ? tuple_.host() : base::EmptyString();
214   }
215   uint16_t port() const { return !opaque() ? tuple_.port() : 0; }
216
217   bool opaque() const { return nonce_.has_value(); }
218
219   // An ASCII serialization of the Origin as per Section 6.2 of RFC 6454, with
220   // the addition that all Origins with a 'file' scheme serialize to "file://".
221   std::string Serialize() const;
222
223   // Two non-opaque Origins are "same-origin" if their schemes, hosts, and ports
224   // are exact matches. Two opaque origins are same-origin only if their
225   // internal nonce values match. A non-opaque origin is never same-origin with
226   // an opaque origin.
227   bool IsSameOriginWith(const Origin& other) const;
228   bool operator==(const Origin& other) const { return IsSameOriginWith(other); }
229   bool operator!=(const Origin& other) const {
230     return !IsSameOriginWith(other);
231   }
232
233   // Non-opaque origin is "same-origin" with `url` if their schemes, hosts, and
234   // ports are exact matches. Opaque origin is never "same-origin" with any
235   // `url`.  about:blank, about:srcdoc, and invalid GURLs are never
236   // "same-origin" with any origin. This method is a shorthand for
237   // `origin.IsSameOriginWith(url::Origin::Create(url))`.
238   //
239   // See also CanBeDerivedFrom.
240   bool IsSameOriginWith(const GURL& url) const;
241
242   // This method returns true for any |url| which if navigated to could result
243   // in an origin compatible with |this|.
244   bool CanBeDerivedFrom(const GURL& url) const;
245
246   // Get the scheme, host, and port from which this origin derives. For
247   // a tuple Origin, this gives the same values as calling scheme(), host()
248   // and port(). For an opaque Origin that was created by calling
249   // Origin::DeriveNewOpaqueOrigin() on a precursor or Origin::Resolve(),
250   // this returns the tuple inherited from the precursor.
251   //
252   // If this Origin is opaque and was created via the default constructor or
253   // Origin::Create(), the precursor origin is unknown.
254   //
255   // Use with great caution: opaque origins should generally not inherit
256   // privileges from the origins they derive from. However, in some cases
257   // (such as restrictions on process placement, or determining the http lock
258   // icon) this information may be relevant to ensure that entering an
259   // opaque origin does not grant privileges initially denied to the original
260   // non-opaque origin.
261   //
262   // This method has a deliberately obnoxious name to prompt caution in its use.
263   const SchemeHostPort& GetTupleOrPrecursorTupleIfOpaque() const {
264     return tuple_;
265   }
266
267   // Efficiently returns what GURL(Serialize()) would without re-parsing the
268   // URL. This can be used for the (rare) times a GURL representation is needed
269   // for an Origin.
270   // Note: The returned URL will not necessarily be serialized to the same value
271   // as the Origin would. The GURL will have an added "/" path for Origins with
272   // valid SchemeHostPorts and file Origins.
273   //
274   // Try not to use this method under normal circumstances, as it loses type
275   // information. Downstream consumers can mistake the returned GURL with a full
276   // URL (e.g. with a path component).
277   GURL GetURL() const;
278
279   // Same as GURL::DomainIs. If |this| origin is opaque, then returns false.
280   bool DomainIs(std::string_view canonical_domain) const;
281
282   // Allows Origin to be used as a key in STL (for example, a std::set or
283   // std::map).
284   bool operator<(const Origin& other) const;
285
286   // Creates a new opaque origin that is guaranteed to be cross-origin to all
287   // currently existing origins. An origin created by this method retains its
288   // identity across copies. Copies are guaranteed to be same-origin to each
289   // other, e.g.
290   //
291   //   url::Origin page = Origin::Create(GURL("http://example.com"))
292   //   url::Origin a = page.DeriveNewOpaqueOrigin();
293   //   url::Origin b = page.DeriveNewOpaqueOrigin();
294   //   url::Origin c = a;
295   //   url::Origin d = b;
296   //
297   // |a| and |c| are same-origin, since |c| was copied from |a|. |b| and |d| are
298   // same-origin as well, since |d| was copied from |b|. All other combinations
299   // of origins are considered cross-origin, e.g. |a| is cross-origin to |b| and
300   // |d|, |b| is cross-origin to |a| and |c|, |c| is cross-origin to |b| and
301   // |d|, and |d| is cross-origin to |a| and |c|.
302   Origin DeriveNewOpaqueOrigin() const;
303
304   // Creates a string representation of the object that can be used for logging
305   // and debugging. It serializes the internal state, such as the nonce value
306   // and precursor information.
307   std::string GetDebugString(bool include_nonce = true) const;
308
309 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
310   base::android::ScopedJavaLocalRef<jobject> ToJavaObject() const;
311   static Origin FromJavaObject(
312       const base::android::JavaRef<jobject>& java_origin);
313   static jlong CreateNative(JNIEnv* env,
314                             const base::android::JavaRef<jstring>& java_scheme,
315                             const base::android::JavaRef<jstring>& java_host,
316                             uint16_t port,
317                             bool is_opaque,
318                             uint64_t tokenHighBits,
319                             uint64_t tokenLowBits);
320 #endif  // BUILDFLAG(IS_ANDROID)
321
322   void WriteIntoTrace(perfetto::TracedValue context) const;
323
324   // Estimates dynamic memory usage.
325   // See base/trace_event/memory_usage_estimator.h for more info.
326   size_t EstimateMemoryUsage() const;
327
328  private:
329 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_ROBOLECTRIC)
330   friend Origin CreateOpaqueOriginForAndroid(
331       const std::string& scheme,
332       const std::string& host,
333       uint16_t port,
334       const base::UnguessableToken& nonce_token);
335 #endif
336   friend class blink::SecurityOrigin;
337   friend class blink::SecurityOriginTest;
338   friend class blink::StorageKey;
339   // SchemefulSite needs access to the serialization/deserialization logic which
340   // includes the nonce.
341   friend class net::SchemefulSite;
342   friend class OriginTest;
343   friend struct mojo::UrlOriginAdapter;
344   friend struct ipc_fuzzer::FuzzTraits<Origin>;
345   friend struct mojo::StructTraits<url::mojom::OriginDataView, url::Origin>;
346   friend IPC::ParamTraits<url::Origin>;
347   friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
348                                                         const Origin& origin);
349   friend class blink::StorageKeyTest;
350
351   // Origin::Nonce is a wrapper around base::UnguessableToken that generates
352   // the random value only when the value is first accessed. The lazy generation
353   // allows Origin to be default-constructed quickly, without spending time
354   // in random number generation.
355   //
356   // TODO(nick): Should this optimization move into UnguessableToken, once it no
357   // longer treats the Null case specially?
358   class COMPONENT_EXPORT(URL) Nonce {
359    public:
360     // Creates a nonce to hold a newly-generated UnguessableToken. The actual
361     // token value will be generated lazily.
362     Nonce();
363
364     // Creates a nonce to hold an already-generated UnguessableToken value. This
365     // constructor should only be used for IPC serialization and testing --
366     // regular code should never need to touch the UnguessableTokens directly,
367     // and the default constructor is faster.
368     explicit Nonce(const base::UnguessableToken& token);
369
370     // Accessor, which lazily initializes the underlying |token_| member.
371     const base::UnguessableToken& token() const;
372
373     // Do not use in cases where lazy initialization is expected! This
374     // accessor does not initialize the |token_| member.
375     const base::UnguessableToken& raw_token() const;
376
377     // Copyable and movable. Copying a Nonce triggers lazy-initialization,
378     // moving it does not.
379     Nonce(const Nonce&);
380     Nonce& operator=(const Nonce&);
381     Nonce(Nonce&&) noexcept;
382     Nonce& operator=(Nonce&&) noexcept;
383
384     // Note that operator<, used by maps type containers, will trigger |token_|
385     // lazy-initialization. Equality comparisons do not.
386     bool operator<(const Nonce& other) const;
387     bool operator==(const Nonce& other) const;
388     bool operator!=(const Nonce& other) const;
389
390    private:
391     friend class OriginTest;
392
393     // mutable to support lazy generation.
394     mutable base::UnguessableToken token_;
395   };
396
397   // This needs to be friended within Origin as well, since Nonce is a private
398   // nested class of Origin.
399   friend COMPONENT_EXPORT(URL) std::ostream& operator<<(std::ostream& out,
400                                                         const Nonce& nonce);
401
402   // Creates an origin without sanity checking that the host is canonicalized.
403   // This should only be used when converting between already normalized types,
404   // and should NOT be used for IPC. Method takes std::strings for use with move
405   // operators to avoid copies.
406   static Origin CreateOpaqueFromNormalizedPrecursorTuple(
407       std::string precursor_scheme,
408       std::string precursor_host,
409       uint16_t precursor_port,
410       const Nonce& nonce);
411
412   // Creates an opaque Origin with the identity given by |nonce|, and an
413   // optional precursor origin given by |precursor_scheme|, |precursor_host| and
414   // |precursor_port|. Returns nullopt if any parameter is not canonical. When
415   // the precursor is unknown, the precursor parameters should be ("", "", 0).
416   //
417   // This factory method should be used in order to pass opaque Origin objects
418   // back and forth over IPC (as transitioning through GURL would risk
419   // potentially dangerous recanonicalization).
420   static absl::optional<Origin> UnsafelyCreateOpaqueOriginWithoutNormalization(
421       std::string_view precursor_scheme,
422       std::string_view precursor_host,
423       uint16_t precursor_port,
424       const Nonce& nonce);
425
426   // Constructs a non-opaque tuple origin. |tuple| must be valid.
427   explicit Origin(SchemeHostPort tuple);
428
429   // Constructs an opaque origin derived from the |precursor| tuple, with the
430   // given |nonce|.
431   Origin(const Nonce& nonce, SchemeHostPort precursor);
432
433   // Get the nonce associated with this origin, if it is opaque, or nullptr
434   // otherwise. This should be used only when trying to send an Origin across an
435   // IPC pipe.
436   const base::UnguessableToken* GetNonceForSerialization() const;
437
438   // Serializes this Origin, including its nonce if it is opaque. If an opaque
439   // origin's |tuple_| is invalid nullopt is returned. If the nonce is not
440   // initialized, a nonce of 0 is used. Use of this method should be limited as
441   // an opaque origin will never be matchable in future browser sessions.
442   absl::optional<std::string> SerializeWithNonce() const;
443
444   // Like SerializeWithNonce(), but forces |nonce_| to be initialized prior to
445   // serializing.
446   absl::optional<std::string> SerializeWithNonceAndInitIfNeeded();
447
448   absl::optional<std::string> SerializeWithNonceImpl() const;
449
450   // Deserializes an origin from |ToValueWithNonce|. Returns nullopt if the
451   // value was invalid in any way.
452   static absl::optional<Origin> Deserialize(const std::string& value);
453
454   // The tuple is used for both tuple origins (e.g. https://example.com:80), as
455   // well as for opaque origins, where it tracks the tuple origin from which
456   // the opaque origin was initially derived (we call this the "precursor"
457   // origin).
458   SchemeHostPort tuple_;
459
460   // The nonce is used for maintaining identity of an opaque origin. This
461   // nonce is preserved when an opaque origin is copied or moved. An Origin
462   // is considered opaque if and only if |nonce_| holds a value.
463   absl::optional<Nonce> nonce_;
464 };
465
466 // Pretty-printers for logging. These expose the internal state of the nonce.
467 COMPONENT_EXPORT(URL)
468 std::ostream& operator<<(std::ostream& out, const Origin& origin);
469 COMPONENT_EXPORT(URL)
470 std::ostream& operator<<(std::ostream& out, const Origin::Nonce& origin);
471
472 COMPONENT_EXPORT(URL) bool IsSameOriginWith(const GURL& a, const GURL& b);
473
474 // DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) copies `origin` into a new
475 // stack-allocated variable named `<var_name>`. This helps ensure that the
476 // value of `origin` gets preserved in crash dumps.
477 #define DEBUG_ALIAS_FOR_ORIGIN(var_name, origin) \
478   DEBUG_ALIAS_FOR_CSTR(var_name, (origin).Serialize().c_str(), 128)
479
480 namespace debug {
481
482 class COMPONENT_EXPORT(URL) ScopedOriginCrashKey {
483  public:
484   ScopedOriginCrashKey(base::debug::CrashKeyString* crash_key,
485                        const url::Origin* value);
486   ~ScopedOriginCrashKey();
487
488   ScopedOriginCrashKey(const ScopedOriginCrashKey&) = delete;
489   ScopedOriginCrashKey& operator=(const ScopedOriginCrashKey&) = delete;
490
491  private:
492   base::debug::ScopedCrashKeyString scoped_string_value_;
493 };
494
495 }  // namespace debug
496
497 }  // namespace url
498
499 #endif  // URL_ORIGIN_H_