1 // Copyright (c) 2017 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 CONTENT_BROWSER_ISOLATED_ORIGIN_UTIL_H_ 5 #define CONTENT_BROWSER_ISOLATED_ORIGIN_UTIL_H_ 6 7 #include <string> 8 9 #include "base/gtest_prod_util.h" 10 #include "base/strings/string_util.h" 11 #include "content/common/content_export.h" 12 #include "url/origin.h" 13 14 namespace content { 15 16 // This class holds isolated origin patterns, providing support for double 17 // wildcard origins, e.g. https://[*.]foo.com indicates that all domains under 18 // foo.com are to be treated as if they are distinct isolated 19 // origins. Non-wildcard origins to be isolated are also supported, e.g. 20 // https://bar.com. 21 class CONTENT_EXPORT IsolatedOriginPattern { 22 public: 23 explicit IsolatedOriginPattern(base::StringPiece pattern); 24 explicit IsolatedOriginPattern(const url::Origin& origin); 25 ~IsolatedOriginPattern(); 26 27 // Copying and moving supported. 28 IsolatedOriginPattern(const IsolatedOriginPattern& other); 29 IsolatedOriginPattern& operator=(const IsolatedOriginPattern& other); 30 31 IsolatedOriginPattern(IsolatedOriginPattern&& other); 32 IsolatedOriginPattern& operator=(IsolatedOriginPattern&& other); 33 34 bool operator==(const IsolatedOriginPattern& other) const { 35 // |pattern_| is deliberately not considered during equality comparison as 36 // it stores the pattern as supplied at construction time, before 37 // normalisation. This leads to erroneous cases of mismatch where 38 // IsolatedOriginPattern("foo.com") and IsolatedOriginPattern("foo.com/") 39 // will fail equality comparison, despite both resolving to the same origin. 40 return origin_ == other.origin_ && 41 isolate_all_subdomains_ == other.isolate_all_subdomains_ && 42 is_valid_ == other.is_valid_; 43 } 44 45 // Returns the url::Origin corresponding to the pattern supplied at 46 // construction time or via a call to Parse. In the event of parsing failure 47 // this oriqin will be opaque. origin()48 const url::Origin& origin() const { return origin_; } 49 50 // True if the supplied pattern was of the form https://[*.]foo.com, 51 // indicating all subdomains of foo.com are to be isolated. isolate_all_subdomains()52 bool isolate_all_subdomains() const { return isolate_all_subdomains_; } 53 54 // Return the original pattern used to construct this instance. pattern()55 const base::StringPiece pattern() const { return pattern_; } 56 57 // Return if this origin is valid for isolation purposes. is_valid()58 bool is_valid() const { return is_valid_; } 59 60 private: 61 friend class ChildProcessSecurityPolicyTest; 62 FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, 63 IsolatedOriginPattern); 64 65 // Checks if |pattern| is a wildcard pattern, checks the scheme is one of 66 // {http, https} and constructs a url::Origin() that can be retrieved if 67 // parsing is successful. Returns true on successful parsing. 68 bool Parse(const base::StringPiece& pattern); 69 70 std::string pattern_; 71 url::Origin origin_; 72 bool isolate_all_subdomains_; 73 bool is_valid_; 74 }; 75 76 class CONTENT_EXPORT IsolatedOriginUtil { 77 public: 78 // Checks whether |origin| matches the isolated origin specified by 79 // |isolated_origin|. Subdomains are considered to match isolated origins, 80 // so this will be true if 81 // (1) |origin| has the same scheme, host, and port as |isolated_origin|, or 82 // (2) |origin| has the same scheme and port as |isolated_origin|, and its 83 // host is a subdomain of |isolated_origin|'s host. 84 // This does not consider site URLs, which don't care about port. 85 // 86 // For example, if |isolated_origin| is https://isolated.foo.com, this will 87 // return true if |origin| is https://isolated.foo.com or 88 // https://bar.isolated.foo.com, but it will return false for an |origin| of 89 // https://unisolated.foo.com or https://foo.com. 90 static bool DoesOriginMatchIsolatedOrigin(const url::Origin& origin, 91 const url::Origin& isolated_origin); 92 93 // Check if |origin| is a valid isolated origin. Invalid isolated origins 94 // include unique origins, origins that don't have an HTTP or HTTPS scheme, 95 // and origins without a valid registry-controlled domain. IP addresses are 96 // allowed. 97 static bool IsValidIsolatedOrigin(const url::Origin& origin); 98 99 // Returns |true| if the two arguments have the same scheme and port, and 100 // |sub_origin|'s host is a strict subdomain of |base_origin|'s. 101 static bool IsStrictSubdomain(const url::Origin& sub_origin, 102 const url::Origin& base_origin); 103 }; 104 105 } // namespace content 106 107 #endif // CONTENT_BROWSER_ISOLATED_ORIGIN_UTIL_H_ 108