blob: 4b838e420f3ffac5d280d70204030a6d9b84844c [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
12#include "base/strings/string16.h"
mkwstd8335d982015-07-25 05:18:4813#include "base/strings/string_piece.h"
mkwst9f2cc892015-07-22 06:03:2514#include "url/scheme_host_port.h"
15#include "url/third_party/mozilla/url_parse.h"
16#include "url/url_canon.h"
17#include "url/url_constants.h"
18#include "url/url_export.h"
19
20class GURL;
21
22namespace url {
23
24// An Origin is a tuple of (scheme, host, port), as described in RFC 6454.
25//
26// TL;DR: If you need to make a security-relevant decision, use 'url::Origin'.
27// If you only need to extract the bits of a URL which are relevant for a
28// network connection, use 'url::SchemeHostPort'.
29//
30// STL;SDR: If you aren't making actual network connections, use 'url::Origin'.
31//
32// 'Origin', like 'SchemeHostPort', is composed of a tuple of (scheme, host,
33// port), but contains a number of additional concepts which make it appropriate
34// for use as a security boundary and access control mechanism between contexts.
35//
36// This class ought to be used when code needs to determine if two resources
37// are "same-origin", and when a canonical serialization of an origin is
38// required. Note that some origins are "unique", meaning that they are not
39// same-origin with any other origin (including themselves).
40//
41// There are a few subtleties to note:
42//
43// * Invalid and non-standard GURLs are parsed as unique origins. This includes
44// non-hierarchical URLs like 'data:text/html,...' and 'javascript:alert(1)'.
45//
46// * GURLs with schemes of 'filesystem' or 'blob' parse the origin out of the
47// internals of the URL. That is, 'filesystem:https://example.com/temporary/f'
48// is parsed as ('https', 'example.com', 443).
49//
50// * Unique origins all serialize to the string "null"; this means that the
51// serializations of two unique origins are identical to each other, though
52// the origins themselves are not "the same". This means that origins'
53// serializations must not be relied upon for security checks.
54//
55// * GURLs with a 'file' scheme are tricky. They are parsed as ('file', '', 0),
56// but their behavior may differ from embedder to embedder.
57//
58// * The host component of an IPv6 address includes brackets, just like the URL
59// representation.
60//
61// Usage:
62//
63// * Origins are generally constructed from an already-canonicalized GURL:
64//
65// GURL url("https://example.com/");
66// url::Origin origin(url);
67// origin.scheme(); // "https"
68// origin.host(); // "example.com"
69// origin.port(); // 443
iclellande099c8a2016-01-07 21:10:3970// origin.unique(); // false
mkwst9f2cc892015-07-22 06:03:2571//
72// * To answer the question "Are |this| and |that| "same-origin" with each
73// other?", use |Origin::IsSameOriginWith|:
74//
75// if (this.IsSameOriginWith(that)) {
76// // Amazingness goes here.
77// }
78class URL_EXPORT Origin {
79 public:
80 // Creates a unique Origin.
81 Origin();
82
83 // Creates an Origin from |url|, as described at
84 // https://url.spec.whatwg.org/#origin, with the following additions:
85 //
86 // 1. If |url| is invalid or non-standard, a unique Origin is constructed.
87 // 2. 'filesystem' URLs behave as 'blob' URLs (that is, the origin is parsed
88 // out of everything in the URL which follows the scheme).
89 // 3. 'file' URLs all parse as ("file", "", 0).
90 explicit Origin(const GURL& url);
91
mkwstd8335d982015-07-25 05:18:4892 // Creates an Origin from a |scheme|, |host|, and |port|. All the parameters
csharrisonedf893f2016-10-12 01:42:5693 // must be valid and canonicalized. Do not use this method to create unique
94 // origins. Use Origin() for that.
mkwstd8335d982015-07-25 05:18:4895 //
96 // This constructor should be used in order to pass 'Origin' objects back and
97 // forth over IPC (as transitioning through GURL would risk potentially
98 // dangerous recanonicalization); other potential callers should prefer the
99 // 'GURL'-based constructor.
100 static Origin UnsafelyCreateOriginWithoutNormalization(
101 base::StringPiece scheme,
102 base::StringPiece host,
avic0c60312015-12-21 21:03:50103 uint16_t port);
mkwstd8335d982015-07-25 05:18:48104
csharrisonedf893f2016-10-12 01:42:56105 // Creates an origin without sanity checking that the host is canonicalized.
106 // This should only be used when converting between already normalized types,
csharrisonf07ac3c2016-12-13 04:15:02107 // and should NOT be used for IPC. Method takes std::strings for use with move
108 // operators to avoid copies.
jww908428c2016-10-26 21:51:46109 static Origin CreateFromNormalizedTupleWithSuborigin(
csharrisonf07ac3c2016-12-13 04:15:02110 std::string scheme,
111 std::string host,
jww908428c2016-10-26 21:51:46112 uint16_t port,
csharrisonf07ac3c2016-12-13 04:15:02113 std::string suborigin);
jww908428c2016-10-26 21:51:46114
mkwst9f2cc892015-07-22 06:03:25115 ~Origin();
116
117 // For unique origins, these return ("", "", 0).
mkwstf5fef062015-07-22 08:29:01118 const std::string& scheme() const { return tuple_.scheme(); }
119 const std::string& host() const { return tuple_.host(); }
avic0c60312015-12-21 21:03:50120 uint16_t port() const { return tuple_.port(); }
mkwst9f2cc892015-07-22 06:03:25121
jww04480402016-10-25 02:50:33122 // Note that an origin without a suborgin will return the empty string.
123 const std::string& suborigin() const { return suborigin_; }
124
mkwst9f2cc892015-07-22 06:03:25125 bool unique() const { return unique_; }
126
127 // An ASCII serialization of the Origin as per Section 6.2 of RFC 6454, with
128 // the addition that all Origins with a 'file' scheme serialize to "file://".
jww04480402016-10-25 02:50:33129 // If the Origin has a suborigin, it will be serialized per
130 // https://w3c.github.io/webappsec-suborigins/#serializing.
mkwst9f2cc892015-07-22 06:03:25131 std::string Serialize() const;
132
jww04480402016-10-25 02:50:33133 // Returns the physical origin for Origin. If the suborigin is empty, this
134 // will just return a copy of the Origin. If it has a suborigin, will return
135 // the Origin of just the scheme/host/port tuple, without the suborigin. See
136 // https://w3c.github.io/webappsec-suborigins/.
137 Origin GetPhysicalOrigin() const;
138
mkwst9f2cc892015-07-22 06:03:25139 // Two Origins are "same-origin" if their schemes, hosts, and ports are exact
jww04480402016-10-25 02:50:33140 // matches; and neither is unique. If either of the origins have suborigins,
141 // the suborigins also must be exact matches.
mkwst9f2cc892015-07-22 06:03:25142 bool IsSameOriginWith(const Origin& other) const;
mek0126c132016-02-17 23:50:59143 bool operator==(const Origin& other) const {
144 return IsSameOriginWith(other);
145 }
mkwst9f2cc892015-07-22 06:03:25146
jww04480402016-10-25 02:50:33147 // Same as above, but ignores suborigins if they exist.
148 bool IsSamePhysicalOriginWith(const Origin& other) const;
149
csharrison048bee12016-10-04 00:08:21150 // Efficiently returns what GURL(Serialize()) would without re-parsing the
151 // URL. This can be used for the (rare) times a GURL representation is needed
152 // for an Origin.
153 // Note: The returned URL will not necessarily be serialized to the same value
154 // as the Origin would. The GURL will have an added "/" path for Origins with
155 // valid SchemeHostPorts and file Origins.
156 GURL GetURL() const;
157
pkalinnikov054f4032016-08-31 10:54:17158 // Same as GURL::DomainIs. If |this| origin is unique, then returns false.
159 bool DomainIs(base::StringPiece lower_ascii_domain) const;
160
nick1466c842015-11-25 20:08:06161 // Allows Origin to be used as a key in STL (for example, a std::set or
mkwst9f2cc892015-07-22 06:03:25162 // std::map).
163 bool operator<(const Origin& other) const;
164
165 private:
csharrisonedf893f2016-10-12 01:42:56166 Origin(base::StringPiece scheme,
167 base::StringPiece host,
168 uint16_t port,
jww908428c2016-10-26 21:51:46169 base::StringPiece suborigin,
csharrisonedf893f2016-10-12 01:42:56170 SchemeHostPort::ConstructPolicy policy);
csharrisonf07ac3c2016-12-13 04:15:02171 Origin(std::string scheme,
172 std::string host,
173 uint16_t port,
174 std::string suborigin,
175 SchemeHostPort::ConstructPolicy policy);
mkwstd8335d982015-07-25 05:18:48176
mkwst9f2cc892015-07-22 06:03:25177 SchemeHostPort tuple_;
178 bool unique_;
jww04480402016-10-25 02:50:33179 std::string suborigin_;
mkwst9f2cc892015-07-22 06:03:25180};
181
palmer5c437bcc2016-02-03 23:21:36182URL_EXPORT std::ostream& operator<<(std::ostream& out, const Origin& origin);
183
184URL_EXPORT bool IsSameOriginWith(const GURL& a, const GURL& b);
jww04480402016-10-25 02:50:33185URL_EXPORT bool IsSamePhysicalOriginWith(const GURL& a, const GURL& b);
mkwst9f2cc892015-07-22 06:03:25186
187} // namespace url
188
qyearsley2bc727d2015-08-14 20:17:15189#endif // URL_ORIGIN_H_