Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / dom / clients / manager / ClientValidation.cpp
blob61e9338e124484c590e9c3a995da3dcb9112b293
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ClientValidation.h"
9 #include "mozilla/ipc/PBackgroundSharedTypes.h"
10 #include "mozilla/StaticPrefs_security.h"
11 #include "mozilla/net/MozURL.h"
13 namespace mozilla::dom {
15 using mozilla::ipc::ContentPrincipalInfo;
16 using mozilla::ipc::PrincipalInfo;
17 using mozilla::net::MozURL;
19 bool ClientIsValidPrincipalInfo(const PrincipalInfo& aPrincipalInfo) {
20 // Ideally we would verify that the source process has permission to
21 // create a window or worker with the given principal, but we don't
22 // currently have any such restriction in place. Instead, at least
23 // verify the PrincipalInfo is an expected type and has a parsable
24 // origin/spec.
25 switch (aPrincipalInfo.type()) {
26 // Any system and null principal is acceptable.
27 case PrincipalInfo::TSystemPrincipalInfo:
28 case PrincipalInfo::TNullPrincipalInfo: {
29 return true;
32 // Validate content principals to ensure that the origin and spec are sane.
33 case PrincipalInfo::TContentPrincipalInfo: {
34 const ContentPrincipalInfo& content =
35 aPrincipalInfo.get_ContentPrincipalInfo();
37 // Verify the principal spec parses.
38 RefPtr<MozURL> specURL;
39 nsresult rv = MozURL::Init(getter_AddRefs(specURL), content.spec());
40 NS_ENSURE_SUCCESS(rv, false);
42 // Verify the principal originNoSuffix parses.
43 RefPtr<MozURL> originURL;
44 rv = MozURL::Init(getter_AddRefs(originURL), content.originNoSuffix());
45 NS_ENSURE_SUCCESS(rv, false);
47 nsAutoCString originOrigin;
48 originURL->Origin(originOrigin);
50 nsAutoCString specOrigin;
51 specURL->Origin(specOrigin);
53 // Linkable about URIs end up with a nested inner scheme of moz-safe-about
54 // which will have been captured in the originNoSuffix but the spec and
55 // its resulting specOrigin will not have this transformed scheme, so
56 // ignore the "moz-safe-" prefix when the originURL has that transformed
57 // scheme.
58 if (originURL->Scheme().Equals("moz-safe-about")) {
59 return specOrigin == originOrigin ||
60 specOrigin == Substring(originOrigin, 9 /*moz-safe-*/,
61 specOrigin.Length());
64 // For now require Clients to have a principal where both its
65 // originNoSuffix and spec have the same origin. This will
66 // exclude a variety of unusual combinations within the browser
67 // but its adequate for the features need to support right now.
68 // If necessary we could expand this function to handle more
69 // cases in the future.
71 return specOrigin == originOrigin;
73 default: {
74 break;
78 // Windows and workers should not have expanded URLs, etc.
79 return false;
82 bool ClientIsValidCreationURL(const PrincipalInfo& aPrincipalInfo,
83 const nsACString& aURL) {
84 RefPtr<MozURL> url;
85 nsresult rv = MozURL::Init(getter_AddRefs(url), aURL);
86 NS_ENSURE_SUCCESS(rv, false);
88 switch (aPrincipalInfo.type()) {
89 case PrincipalInfo::TContentPrincipalInfo: {
90 // Any origin can create an about:blank or about:srcdoc Client.
91 if (aURL.LowerCaseEqualsLiteral("about:blank") ||
92 aURL.LowerCaseEqualsLiteral("about:srcdoc")) {
93 return true;
96 const ContentPrincipalInfo& content =
97 aPrincipalInfo.get_ContentPrincipalInfo();
99 // Parse the principal origin URL as well. This ensures any MozURL
100 // parser issues effect both URLs equally.
101 RefPtr<MozURL> principalURL;
102 rv = MozURL::Init(getter_AddRefs(principalURL), content.originNoSuffix());
103 NS_ENSURE_SUCCESS(rv, false);
105 nsAutoCString origin;
106 url->Origin(origin);
108 nsAutoCString principalOrigin;
109 principalURL->Origin(principalOrigin);
111 // The vast majority of sites should simply result in the same principal
112 // and URL origin.
113 if (principalOrigin == origin) {
114 return true;
117 nsDependentCSubstring scheme = url->Scheme();
119 // Generally any origin can also open javascript: windows and workers.
120 if (scheme.LowerCaseEqualsLiteral("javascript")) {
121 return true;
124 // Linkable about URIs end up with a nested inner scheme of moz-safe-about
125 // but the url and its resulting origin will not have this transformed
126 // scheme, so ignore the "moz-safe-" prefix when the principal has that
127 // transformed scheme.
128 if (principalURL->Scheme().Equals("moz-safe-about")) {
129 return origin == principalOrigin ||
130 origin ==
131 Substring(principalOrigin, 9 /*moz-safe-*/, origin.Length());
134 // Otherwise don't support this URL type in the clients sub-system for
135 // now. This will exclude a variety of internal browser clients, but
136 // currently we don't need to support those. This function can be
137 // expanded to handle more cases as necessary.
138 return false;
140 case PrincipalInfo::TSystemPrincipalInfo: {
141 nsDependentCSubstring scheme = url->Scheme();
143 // While many types of documents can be created with a system principal,
144 // there are only a few that can reasonably become windows. We attempt
145 // to validate the list of known cases here with a simple scheme check.
146 return scheme.LowerCaseEqualsLiteral("about") ||
147 scheme.LowerCaseEqualsLiteral("chrome") ||
148 scheme.LowerCaseEqualsLiteral("resource") ||
149 scheme.LowerCaseEqualsLiteral("blob") ||
150 scheme.LowerCaseEqualsLiteral("javascript") ||
151 scheme.LowerCaseEqualsLiteral("view-source");
153 case PrincipalInfo::TNullPrincipalInfo: {
154 // A wide variety of clients can have a null principal. For example,
155 // sandboxed iframes can have a normal content URL. For now allow
156 // any parsable URL for null principals. This is relatively safe since
157 // null principals have unique origins and won't most ClientManagerService
158 // queries anyway.
159 return true;
161 default: {
162 break;
166 // Clients (windows/workers) should never have an expanded principal type.
167 return false;
170 } // namespace mozilla::dom