origin.h 20 KB

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