1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 sw=2 et 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 "mozilla/BasePrincipal.h"
9 #include "nsDocShell.h"
11 #include "ExpandedPrincipal.h"
12 #include "nsNetUtil.h"
13 #include "nsContentUtils.h"
14 #include "nsIOService.h"
15 #include "nsIURIWithSpecialOrigin.h"
16 #include "nsScriptSecurityManager.h"
17 #include "nsServiceManagerUtils.h"
18 #include "nsAboutProtocolUtils.h"
19 #include "ThirdPartyUtil.h"
20 #include "mozilla/ContentPrincipal.h"
21 #include "mozilla/ExtensionPolicyService.h"
22 #include "mozilla/NullPrincipal.h"
23 #include "mozilla/dom/BlobURLProtocolHandler.h"
24 #include "mozilla/dom/ChromeUtils.h"
25 #include "mozilla/dom/ReferrerInfo.h"
26 #include "mozilla/dom/ToJSValue.h"
27 #include "mozilla/dom/nsMixedContentBlocker.h"
28 #include "mozilla/Components.h"
29 #include "mozilla/dom/StorageUtils.h"
30 #include "mozilla/dom/StorageUtils.h"
32 #include "nsEffectiveTLDService.h"
33 #include "nsIURIMutator.h"
34 #include "mozilla/StaticPrefs_permissions.h"
35 #include "nsIURIMutator.h"
36 #include "nsMixedContentBlocker.h"
38 #include "nsIURIFixup.h"
39 #include "mozilla/dom/StorageUtils.h"
40 #include "mozilla/StorageAccess.h"
41 #include "nsPIDOMWindow.h"
42 #include "nsIURIMutator.h"
43 #include "mozilla/PermissionManager.h"
45 #include "json/json.h"
46 #include "nsSerializationHelper.h"
50 const char* BasePrincipal::JSONEnumKeyStrings
[4] = {
57 BasePrincipal::BasePrincipal(PrincipalKind aKind
,
58 const nsACString
& aOriginNoSuffix
,
59 const OriginAttributes
& aOriginAttributes
)
60 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix
)),
61 mOriginSuffix(aOriginAttributes
.CreateSuffixAtom()),
62 mOriginAttributes(aOriginAttributes
),
64 mHasExplicitDomain(false) {}
66 BasePrincipal::BasePrincipal(BasePrincipal
* aOther
,
67 const OriginAttributes
& aOriginAttributes
)
68 : mOriginNoSuffix(aOther
->mOriginNoSuffix
),
69 mOriginSuffix(aOriginAttributes
.CreateSuffixAtom()),
70 mOriginAttributes(aOriginAttributes
),
72 mHasExplicitDomain(aOther
->mHasExplicitDomain
.load()) {}
74 BasePrincipal::~BasePrincipal() = default;
77 BasePrincipal::GetOrigin(nsACString
& aOrigin
) {
78 nsresult rv
= GetOriginNoSuffix(aOrigin
);
79 NS_ENSURE_SUCCESS(rv
, rv
);
82 rv
= GetOriginSuffix(suffix
);
83 NS_ENSURE_SUCCESS(rv
, rv
);
84 aOrigin
.Append(suffix
);
89 BasePrincipal::GetAsciiOrigin(nsACString
& aOrigin
) {
91 nsCOMPtr
<nsIURI
> prinURI
;
92 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
93 if (NS_FAILED(rv
) || !prinURI
) {
94 return NS_ERROR_NOT_AVAILABLE
;
96 return nsContentUtils::GetASCIIOrigin(prinURI
, aOrigin
);
100 BasePrincipal::GetHostPort(nsACString
& aRes
) {
102 nsCOMPtr
<nsIURI
> prinURI
;
103 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
104 if (NS_FAILED(rv
) || !prinURI
) {
107 return prinURI
->GetHostPort(aRes
);
111 BasePrincipal::GetHost(nsACString
& aRes
) {
113 nsCOMPtr
<nsIURI
> prinURI
;
114 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
115 if (NS_FAILED(rv
) || !prinURI
) {
118 return prinURI
->GetHost(aRes
);
122 BasePrincipal::GetOriginNoSuffix(nsACString
& aOrigin
) {
123 mOriginNoSuffix
->ToUTF8String(aOrigin
);
128 BasePrincipal::GetSiteOrigin(nsACString
& aSiteOrigin
) {
129 nsresult rv
= GetSiteOriginNoSuffix(aSiteOrigin
);
130 NS_ENSURE_SUCCESS(rv
, rv
);
132 nsAutoCString suffix
;
133 rv
= GetOriginSuffix(suffix
);
134 NS_ENSURE_SUCCESS(rv
, rv
);
135 aSiteOrigin
.Append(suffix
);
140 BasePrincipal::GetSiteOriginNoSuffix(nsACString
& aSiteOrigin
) {
141 return GetOriginNoSuffix(aSiteOrigin
);
144 // Returns the inner Json::value of the serialized principal
145 // Example input and return values:
147 // {"0":{"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}} ->
148 // {"0":"moz-nullprincipal:{56cac540-864d-47e7-8e25-1614eab5155e}"}
150 // Content principal:
151 // {"1":{"0":"https://mozilla.com"}} -> {"0":"https://mozilla.com"}
153 // Expanded principal:
154 // {"2":{"0":"<base64principal1>,<base64principal2>"}} ->
155 // {"0":"<base64principal1>,<base64principal2>"}
159 // The aKey passed in also returns the corresponding PrincipalKind enum
161 // Warning: The Json::Value* pointer is into the aRoot object
162 static const Json::Value
* GetPrincipalObject(const Json::Value
& aRoot
,
163 int& aOutPrincipalKind
) {
164 const Json::Value::Members members
= aRoot
.getMemberNames();
165 // We only support one top level key in the object
166 if (members
.size() != 1) {
169 // members[0] here is the "0", "1", "2", "3" principalKind
170 // that is the top level of the serialized JSON principal
171 const std::string stringPrincipalKind
= members
[0];
173 // Next we take the string value from the JSON
174 // and convert it into the int for the BasePrincipal::PrincipalKind enum
176 // Verify that the key is within the valid range
177 int principalKind
= std::stoi(stringPrincipalKind
);
178 MOZ_ASSERT(BasePrincipal::eNullPrincipal
== 0,
179 "We need to rely on 0 being a bounds check for the first "
181 if (principalKind
< 0 || principalKind
> BasePrincipal::eKindMax
) {
184 MOZ_ASSERT(principalKind
== BasePrincipal::eNullPrincipal
||
185 principalKind
== BasePrincipal::eContentPrincipal
||
186 principalKind
== BasePrincipal::eExpandedPrincipal
||
187 principalKind
== BasePrincipal::eSystemPrincipal
);
188 aOutPrincipalKind
= principalKind
;
190 if (!aRoot
[stringPrincipalKind
].isObject()) {
194 // Return the inner value of the principal object
195 return &aRoot
[stringPrincipalKind
];
198 // Accepts the JSON inner object without the wrapping principalKind
199 // (See GetPrincipalObject for the inner object response examples)
200 // Creates an array of KeyVal objects that are all defined on the principal
201 // Each principal type (null, content, expanded) has a KeyVal that stores the
202 // fields of the JSON
204 // This simplifies deserializing elsewhere as we do the checking for presence
205 // and string values here for the complete set of serializable keys that the
206 // corresponding principal supports.
208 // The KeyVal object has the following fields:
209 // - valueWasSerialized: is true if the deserialized JSON contained a string
211 // - value: The string that was serialized for this key
212 // - key: an SerializableKeys enum value specific to the principal.
213 // For example content principal is an enum of: eURI, eDomain,
217 // Given an inner content principal:
218 // {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}
220 // ----------------------------- |
222 // Key ----------------------
226 // They Key "0" corresponds to ContentPrincipal::eURI
227 // They Key "1" corresponds to ContentPrincipal::eSuffix
228 template <typename T
>
229 static nsTArray
<typename
T::KeyVal
> GetJSONKeys(const Json::Value
* aInput
) {
230 int size
= T::eMax
+ 1;
231 nsTArray
<typename
T::KeyVal
> fields
;
232 for (int i
= 0; i
!= size
; i
++) {
233 typename
T::KeyVal
* field
= fields
.AppendElement();
234 // field->valueWasSerialized returns if the field was found in the
235 // deserialized code. This simplifies the consumers from having to check
237 field
->valueWasSerialized
= false;
238 field
->key
= static_cast<typename
T::SerializableKeys
>(i
);
239 const std::string key
= std::to_string(field
->key
);
240 if (aInput
->isMember(key
)) {
241 const Json::Value
& val
= (*aInput
)[key
];
242 if (val
.isString()) {
243 field
->value
.Append(nsDependentCString(val
.asCString()));
244 field
->valueWasSerialized
= true;
251 // Takes a JSON string and parses it turning it into a principal of the
252 // corresponding type
254 // Given a content principal:
258 // ---------------------------------------------------------
260 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
262 // | ----------------------------- |
264 // PrincipalKind | | |
265 // | ----------------------------
266 // SerializableKeys |
269 // The string is first deserialized with jsoncpp to get the Json::Value of the
270 // object. The inner JSON object is parsed with GetPrincipalObject which returns
271 // a KeyVal array of the inner object's fields. PrincipalKind is returned by
272 // GetPrincipalObject which is then used to decide which principal
273 // implementation of FromProperties to call. The corresponding FromProperties
274 // call takes the KeyVal fields and turns it into a principal.
275 already_AddRefed
<BasePrincipal
> BasePrincipal::FromJSON(
276 const nsACString
& aJSON
) {
278 Json::CharReaderBuilder builder
;
279 std::unique_ptr
<Json::CharReader
> const reader(builder
.newCharReader());
281 reader
->parse(aJSON
.BeginReading(), aJSON
.EndReading(), &root
, nullptr);
284 "Unable to parse string as JSON to deserialize as a principal");
288 return FromJSON(root
);
291 // Checks if an ExpandedPrincipal is using the legacy format, where
292 // sub-principals are Base64 encoded.
294 // Given a legacy expanded principal:
297 // {"2": {"0": "eyIxIjp7IjAiOiJodHRwczovL2EuY29tLyJ9fQ=="}}
299 // | ---------- Value
305 // The value is a CSV list of Base64 encoded prinipcals. The new format for this
308 // Subsumed principals
310 // ------------------------------------
312 // {"2": {"0": [{"1": {"0": https://mozilla.com"}}]}}
314 // -------------- Value
318 // It is possible to tell these apart by checking the type of the property noted
319 // in both diagrams with an asterisk. In the legacy format the type will be a
320 // string and in the new format it will be an array.
321 static bool IsLegacyFormat(const Json::Value
& aValue
) {
322 const auto& specs
= std::to_string(ExpandedPrincipal::eSpecs
);
323 return aValue
.isMember(specs
) && aValue
[specs
].isString();
327 already_AddRefed
<BasePrincipal
> BasePrincipal::FromJSON(
328 const Json::Value
& aJSON
) {
329 int principalKind
= -1;
330 const Json::Value
* value
= GetPrincipalObject(aJSON
, principalKind
);
333 fprintf(stderr
, "Unexpected JSON principal %s\n",
334 aJSON
.toStyledString().c_str());
336 MOZ_ASSERT(false, "Unexpected JSON to deserialize as a principal");
340 MOZ_ASSERT(principalKind
!= -1,
341 "PrincipalKind should always be >=0 by this point");
343 if (principalKind
== eSystemPrincipal
) {
344 RefPtr
<BasePrincipal
> principal
=
345 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
346 return principal
.forget();
349 if (principalKind
== eNullPrincipal
) {
350 nsTArray
<NullPrincipal::KeyVal
> res
= GetJSONKeys
<NullPrincipal
>(value
);
351 return NullPrincipal::FromProperties(res
);
354 if (principalKind
== eContentPrincipal
) {
355 nsTArray
<ContentPrincipal::KeyVal
> res
=
356 GetJSONKeys
<ContentPrincipal
>(value
);
357 return ContentPrincipal::FromProperties(res
);
360 if (principalKind
== eExpandedPrincipal
) {
361 // Check if expanded principals is stored in the new or the old format. See
362 // comment for `IsLegacyFormat`.
363 if (IsLegacyFormat(*value
)) {
364 nsTArray
<ExpandedPrincipal::KeyVal
> res
=
365 GetJSONKeys
<ExpandedPrincipal
>(value
);
366 return ExpandedPrincipal::FromProperties(res
);
369 return ExpandedPrincipal::FromProperties(*value
);
372 MOZ_RELEASE_ASSERT(false, "Unexpected enum to deserialize as a principal");
375 nsresult
BasePrincipal::PopulateJSONObject(Json::Value
& aObject
) {
379 // Returns a JSON representation of the principal.
380 // Calling BasePrincipal::FromJSON will deserialize the JSON into
381 // the corresponding principal type.
382 nsresult
BasePrincipal::ToJSON(nsACString
& aJSON
) {
383 MOZ_ASSERT(aJSON
.IsEmpty(), "ToJSON only supports an empty result input");
386 Json::Value root
= Json::objectValue
;
387 nsresult rv
= ToJSON(root
);
388 NS_ENSURE_SUCCESS(rv
, rv
);
390 static StaticAutoPtr
<Json::StreamWriterBuilder
> sJSONBuilderForPrincipals
;
391 if (!sJSONBuilderForPrincipals
) {
392 sJSONBuilderForPrincipals
= new Json::StreamWriterBuilder();
393 (*sJSONBuilderForPrincipals
)["indentation"] = "";
394 (*sJSONBuilderForPrincipals
)["emitUTF8"] = true;
395 ClearOnShutdown(&sJSONBuilderForPrincipals
);
397 std::string result
= Json::writeString(*sJSONBuilderForPrincipals
, root
);
398 aJSON
.Append(result
);
399 if (aJSON
.Length() == 0) {
400 MOZ_ASSERT(false, "JSON writer failed to output a principal serialization");
401 return NS_ERROR_UNEXPECTED
;
407 nsresult
BasePrincipal::ToJSON(Json::Value
& aObject
) {
408 static_assert(eKindMax
< ArrayLength(JSONEnumKeyStrings
));
409 nsresult rv
= PopulateJSONObject(
410 (aObject
[Json::StaticString(JSONEnumKeyStrings
[Kind()])] =
412 NS_ENSURE_SUCCESS(rv
, rv
);
417 bool BasePrincipal::FastSubsumesIgnoringFPD(
418 nsIPrincipal
* aOther
, DocumentDomainConsideration aConsideration
) {
421 if (Kind() == eContentPrincipal
&&
422 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
423 mOriginAttributes
, Cast(aOther
)->mOriginAttributes
)) {
427 return SubsumesInternal(aOther
, aConsideration
);
430 bool BasePrincipal::Subsumes(nsIPrincipal
* aOther
,
431 DocumentDomainConsideration aConsideration
) {
433 MOZ_ASSERT_IF(Kind() == eContentPrincipal
, mOriginSuffix
);
435 // Expanded principals handle origin attributes for each of their
436 // sub-principals individually, null principals do only simple checks for
437 // pointer equality, and system principals are immune to origin attributes
438 // checks, so only do this check for content principals.
439 if (Kind() == eContentPrincipal
&&
440 mOriginSuffix
!= Cast(aOther
)->mOriginSuffix
) {
444 return SubsumesInternal(aOther
, aConsideration
);
448 BasePrincipal::Equals(nsIPrincipal
* aOther
, bool* aResult
) {
449 NS_ENSURE_ARG_POINTER(aOther
);
451 *aResult
= FastEquals(aOther
);
457 BasePrincipal::EqualsForPermission(nsIPrincipal
* aOther
, bool aExactHost
,
460 NS_ENSURE_ARG_POINTER(aOther
);
461 NS_ENSURE_ARG_POINTER(aResult
);
463 auto* other
= Cast(aOther
);
464 if (Kind() != other
->Kind()) {
465 // Principals of different kinds can't be equal.
469 if (Kind() == eSystemPrincipal
) {
470 *aResult
= this == other
;
474 if (Kind() == eNullPrincipal
) {
475 // We don't store permissions for NullPrincipals.
479 MOZ_ASSERT(Kind() == eExpandedPrincipal
|| Kind() == eContentPrincipal
);
481 // Certain origin attributes should not be used to isolate permissions.
482 // Create a stripped copy of both OA sets to compare.
483 mozilla::OriginAttributes ourAttrs
= mOriginAttributes
;
484 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs
);
485 mozilla::OriginAttributes theirAttrs
= aOther
->OriginAttributesRef();
486 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs
);
488 if (ourAttrs
!= theirAttrs
) {
492 if (mOriginNoSuffix
== other
->mOriginNoSuffix
) {
497 // If we are matching with an exact host, we're done now - the permissions
498 // don't match otherwise, we need to start comparing subdomains!
503 nsCOMPtr
<nsIURI
> ourURI
;
504 nsresult rv
= GetURI(getter_AddRefs(ourURI
));
505 NS_ENSURE_SUCCESS(rv
, rv
);
506 // Some principal types may indicate success, but still return nullptr for
508 NS_ENSURE_TRUE(ourURI
, NS_ERROR_FAILURE
);
510 nsCOMPtr
<nsIURI
> otherURI
;
511 rv
= other
->GetURI(getter_AddRefs(otherURI
));
512 NS_ENSURE_SUCCESS(rv
, rv
);
513 NS_ENSURE_TRUE(otherURI
, NS_ERROR_FAILURE
);
516 nsAutoCString otherScheme
;
517 rv
= otherURI
->GetScheme(otherScheme
);
518 NS_ENSURE_SUCCESS(rv
, rv
);
520 nsAutoCString ourScheme
;
521 rv
= ourURI
->GetScheme(ourScheme
);
522 NS_ENSURE_SUCCESS(rv
, rv
);
524 if (otherScheme
!= ourScheme
) {
530 rv
= otherURI
->GetPort(&otherPort
);
531 NS_ENSURE_SUCCESS(rv
, rv
);
534 rv
= ourURI
->GetPort(&ourPort
);
535 NS_ENSURE_SUCCESS(rv
, rv
);
537 if (otherPort
!= ourPort
) {
541 // Check if the host or any subdomain of their host matches.
542 nsAutoCString otherHost
;
543 rv
= otherURI
->GetHost(otherHost
);
544 if (NS_FAILED(rv
) || otherHost
.IsEmpty()) {
548 nsAutoCString ourHost
;
549 rv
= ourURI
->GetHost(ourHost
);
550 if (NS_FAILED(rv
) || ourHost
.IsEmpty()) {
554 nsCOMPtr
<nsIEffectiveTLDService
> tldService
=
555 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID
);
557 NS_ERROR("Should have a tld service!");
558 return NS_ERROR_FAILURE
;
561 // This loop will not loop forever, as GetNextSubDomain will eventually fail
562 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
563 while (otherHost
!= ourHost
) {
564 rv
= tldService
->GetNextSubDomain(otherHost
, otherHost
);
566 if (rv
== NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
) {
578 BasePrincipal::EqualsConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
579 NS_ENSURE_ARG_POINTER(aOther
);
581 *aResult
= FastEqualsConsideringDomain(aOther
);
587 BasePrincipal::EqualsURI(nsIURI
* aOtherURI
, bool* aResult
) {
589 nsCOMPtr
<nsIURI
> prinURI
;
590 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
591 if (NS_FAILED(rv
) || !prinURI
) {
594 return prinURI
->EqualsExceptRef(aOtherURI
, aResult
);
598 BasePrincipal::Subsumes(nsIPrincipal
* aOther
, bool* aResult
) {
599 NS_ENSURE_ARG_POINTER(aOther
);
601 *aResult
= FastSubsumes(aOther
);
607 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
608 NS_ENSURE_ARG_POINTER(aOther
);
610 *aResult
= FastSubsumesConsideringDomain(aOther
);
616 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal
* aOther
,
618 NS_ENSURE_ARG_POINTER(aOther
);
620 *aResult
= FastSubsumesConsideringDomainIgnoringFPD(aOther
);
626 BasePrincipal::CheckMayLoad(nsIURI
* aURI
, bool aAllowIfInheritsPrincipal
) {
627 AssertIsOnMainThread();
628 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, false, 0);
632 BasePrincipal::CheckMayLoadWithReporting(nsIURI
* aURI
,
633 bool aAllowIfInheritsPrincipal
,
634 uint64_t aInnerWindowID
) {
635 AssertIsOnMainThread();
636 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, true,
640 nsresult
BasePrincipal::CheckMayLoadHelper(nsIURI
* aURI
,
641 bool aAllowIfInheritsPrincipal
,
643 uint64_t aInnerWindowID
) {
644 AssertIsOnMainThread(); // Accesses non-threadsafe URI flags and the
645 // non-threadsafe ExtensionPolicyService
646 NS_ENSURE_ARG_POINTER(aURI
);
648 aReport
|| aInnerWindowID
== 0,
649 "Why do we have an inner window id if we're not supposed to report?");
651 // Check the internal method first, which allows us to quickly approve loads
652 // for the System Principal.
653 if (MayLoadInternal(aURI
)) {
658 if (aAllowIfInheritsPrincipal
) {
659 // If the caller specified to allow loads of URIs that inherit
660 // our principal, allow the load if this URI inherits its principal.
661 bool doesInheritSecurityContext
;
662 rv
= NS_URIChainHasFlags(aURI
,
663 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
664 &doesInheritSecurityContext
);
665 if (NS_SUCCEEDED(rv
) && doesInheritSecurityContext
) {
670 // Web Accessible Resources in MV2 Extensions are marked with
671 // URI_FETCHABLE_BY_ANYONE
672 bool fetchableByAnyone
;
673 rv
= NS_URIChainHasFlags(aURI
, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE
,
675 if (NS_SUCCEEDED(rv
) && fetchableByAnyone
) {
679 // Get the principal uri for the last flag check or error.
680 nsCOMPtr
<nsIURI
> prinURI
;
681 rv
= GetURI(getter_AddRefs(prinURI
));
682 if (!(NS_SUCCEEDED(rv
) && prinURI
)) {
683 return NS_ERROR_DOM_BAD_URI
;
686 // If MV3 Extension uris are web accessible by this principal it is allowed to
688 bool maybeWebAccessible
= false;
689 NS_URIChainHasFlags(aURI
, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE
,
690 &maybeWebAccessible
);
691 NS_ENSURE_SUCCESS(rv
, rv
);
692 if (maybeWebAccessible
) {
693 bool isWebAccessible
= false;
694 rv
= ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
695 prinURI
, aURI
, &isWebAccessible
);
696 if (NS_SUCCEEDED(rv
) && isWebAccessible
) {
702 nsScriptSecurityManager::ReportError(
703 "CheckSameOriginError", prinURI
, aURI
,
704 mOriginAttributes
.mPrivateBrowsingId
> 0, aInnerWindowID
);
707 return NS_ERROR_DOM_BAD_URI
;
711 BasePrincipal::IsThirdPartyURI(nsIURI
* aURI
, bool* aRes
) {
712 if (IsSystemPrincipal() || (AddonPolicyCore() && AddonAllowsLoad(aURI
))) {
718 // If we do not have a URI its always 3rd party.
719 nsCOMPtr
<nsIURI
> prinURI
;
720 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
721 if (NS_FAILED(rv
) || !prinURI
) {
724 ThirdPartyUtil
* thirdPartyUtil
= ThirdPartyUtil::GetInstance();
725 return thirdPartyUtil
->IsThirdPartyURI(prinURI
, aURI
, aRes
);
729 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal
* aPrin
, bool* aRes
) {
731 nsCOMPtr
<nsIURI
> prinURI
;
732 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
733 if (NS_FAILED(rv
) || !prinURI
) {
736 return aPrin
->IsThirdPartyURI(prinURI
, aRes
);
740 BasePrincipal::IsThirdPartyChannel(nsIChannel
* aChan
, bool* aRes
) {
741 AssertIsOnMainThread();
742 if (IsSystemPrincipal()) {
743 // Nothing is 3rd party to the system principal.
748 nsCOMPtr
<nsIURI
> prinURI
;
749 GetURI(getter_AddRefs(prinURI
));
750 ThirdPartyUtil
* thirdPartyUtil
= ThirdPartyUtil::GetInstance();
751 return thirdPartyUtil
->IsThirdPartyChannel(aChan
, prinURI
, aRes
);
755 BasePrincipal::IsSameOrigin(nsIURI
* aURI
, bool* aRes
) {
757 nsCOMPtr
<nsIURI
> prinURI
;
758 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
759 if (NS_FAILED(rv
) || !prinURI
) {
760 // Note that expanded and system principals return here, because they have
764 *aRes
= nsScriptSecurityManager::SecurityCompareURIs(prinURI
, aURI
);
769 BasePrincipal::IsL10nAllowed(nsIURI
* aURI
, bool* aRes
) {
770 AssertIsOnMainThread(); // URI_DANGEROUS_TO_LOAD is not threadsafe to query.
773 if (nsContentUtils::IsErrorPage(aURI
)) {
778 // The system principal is always allowed.
779 if (IsSystemPrincipal()) {
784 nsCOMPtr
<nsIURI
> uri
;
785 nsresult rv
= GetURI(getter_AddRefs(uri
));
786 NS_ENSURE_SUCCESS(rv
, NS_OK
);
790 // Allow access to uris that cannot be loaded by web content.
791 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD
,
793 NS_ENSURE_SUCCESS(rv
, NS_OK
);
799 // UI resources also get access.
800 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_IS_UI_RESOURCE
,
802 NS_ENSURE_SUCCESS(rv
, NS_OK
);
808 auto policy
= AddonPolicyCore();
809 *aRes
= (policy
&& policy
->IsPrivileged());
814 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI
* aURI
, bool* aRes
) {
816 nsCOMPtr
<nsIURI
> prinURI
;
817 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
818 if (NS_FAILED(rv
) || !prinURI
) {
821 *aRes
= NS_RelaxStrictFileOriginPolicy(aURI
, prinURI
);
826 BasePrincipal::GetPrefLightCacheKey(nsIURI
* aURI
, bool aWithCredentials
,
827 const OriginAttributes
& aOriginAttributes
,
828 nsACString
& _retval
) {
830 constexpr auto space
= " "_ns
;
832 nsCOMPtr
<nsIURI
> uri
;
833 nsresult rv
= GetURI(getter_AddRefs(uri
));
834 NS_ENSURE_SUCCESS(rv
, rv
);
836 nsAutoCString scheme
, host
, port
;
838 uri
->GetScheme(scheme
);
840 port
.AppendInt(NS_GetRealPort(uri
));
843 if (aWithCredentials
) {
844 _retval
.AssignLiteral("cred");
846 _retval
.AssignLiteral("nocred");
850 rv
= aURI
->GetSpec(spec
);
851 NS_ENSURE_SUCCESS(rv
, rv
);
853 nsAutoCString originAttributesSuffix
;
854 aOriginAttributes
.CreateSuffix(originAttributesSuffix
);
856 _retval
.Append(space
+ scheme
+ space
+ host
+ space
+ port
+ space
+ spec
+
857 space
+ originAttributesSuffix
);
863 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow
* aCheckWindow
,
864 uint32_t* aRejectedReason
,
866 AssertIsOnMainThread();
867 *aRejectedReason
= 0;
868 *aOutAllowed
= false;
870 nsPIDOMWindowInner
* win
= nsPIDOMWindowInner::From(aCheckWindow
);
871 nsCOMPtr
<nsIURI
> uri
;
872 nsresult rv
= GetURI(getter_AddRefs(uri
));
876 *aOutAllowed
= ShouldAllowAccessFor(win
, uri
, aRejectedReason
);
881 BasePrincipal::GetIsNullPrincipal(bool* aResult
) {
882 *aResult
= Kind() == eNullPrincipal
;
887 BasePrincipal::GetIsContentPrincipal(bool* aResult
) {
888 *aResult
= Kind() == eContentPrincipal
;
893 BasePrincipal::GetIsExpandedPrincipal(bool* aResult
) {
894 *aResult
= Kind() == eExpandedPrincipal
;
899 BasePrincipal::GetAsciiSpec(nsACString
& aSpec
) {
901 nsCOMPtr
<nsIURI
> prinURI
;
902 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
903 if (NS_FAILED(rv
) || !prinURI
) {
906 return prinURI
->GetAsciiSpec(aSpec
);
910 BasePrincipal::GetSpec(nsACString
& aSpec
) {
912 nsCOMPtr
<nsIURI
> prinURI
;
913 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
914 if (NS_FAILED(rv
) || !prinURI
) {
917 return prinURI
->GetSpec(aSpec
);
921 BasePrincipal::GetAsciiHost(nsACString
& aHost
) {
923 nsCOMPtr
<nsIURI
> prinURI
;
924 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
925 if (NS_FAILED(rv
) || !prinURI
) {
928 return prinURI
->GetAsciiHost(aHost
);
932 BasePrincipal::GetExposablePrePath(nsACString
& aPrepath
) {
934 nsCOMPtr
<nsIURI
> prinURI
;
935 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
936 if (NS_FAILED(rv
) || !prinURI
) {
940 nsCOMPtr
<nsIURI
> exposableURI
= net::nsIOService::CreateExposableURI(prinURI
);
941 return exposableURI
->GetDisplayPrePath(aPrepath
);
945 BasePrincipal::GetExposableSpec(nsACString
& aSpec
) {
947 nsCOMPtr
<nsIURI
> prinURI
;
948 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
949 if (NS_FAILED(rv
) || !prinURI
) {
952 nsCOMPtr
<nsIURI
> clone
;
953 rv
= NS_MutateURI(prinURI
)
958 NS_ENSURE_SUCCESS(rv
, rv
);
959 return clone
->GetAsciiSpec(aSpec
);
963 BasePrincipal::GetPrePath(nsACString
& aPath
) {
965 nsCOMPtr
<nsIURI
> prinURI
;
966 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
967 if (NS_FAILED(rv
) || !prinURI
) {
970 return prinURI
->GetPrePath(aPath
);
974 BasePrincipal::GetFilePath(nsACString
& aPath
) {
976 nsCOMPtr
<nsIURI
> prinURI
;
977 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
978 if (NS_FAILED(rv
) || !prinURI
) {
981 return prinURI
->GetFilePath(aPath
);
985 BasePrincipal::GetIsSystemPrincipal(bool* aResult
) {
986 *aResult
= IsSystemPrincipal();
991 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult
) {
992 *aResult
= AddonPolicyCore() || ContentScriptAddonPolicyCore();
996 NS_IMETHODIMP
BasePrincipal::GetIsOnion(bool* aIsOnion
) {
998 nsCOMPtr
<nsIURI
> prinURI
;
999 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1000 if (NS_FAILED(rv
) || !prinURI
) {
1005 rv
= prinURI
->GetHost(host
);
1006 if (NS_FAILED(rv
)) {
1009 *aIsOnion
= StringEndsWith(host
, ".onion"_ns
);
1013 NS_IMETHODIMP
BasePrincipal::GetIsIpAddress(bool* aIsIpAddress
) {
1014 *aIsIpAddress
= false;
1016 nsCOMPtr
<nsIURI
> prinURI
;
1017 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1018 if (NS_FAILED(rv
) || !prinURI
) {
1023 rv
= prinURI
->GetHost(host
);
1024 if (NS_FAILED(rv
)) {
1029 memset(&prAddr
, 0, sizeof(prAddr
));
1031 if (PR_StringToNetAddr(host
.get(), &prAddr
) == PR_SUCCESS
) {
1032 *aIsIpAddress
= true;
1038 NS_IMETHODIMP
BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress
) {
1039 *aIsIpAddress
= false;
1041 nsCOMPtr
<nsIURI
> prinURI
;
1042 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1043 if (NS_FAILED(rv
) || !prinURI
) {
1047 nsCOMPtr
<nsIIOService
> ioService
= do_GetIOService(&rv
);
1048 if (NS_FAILED(rv
) || !ioService
) {
1051 rv
= ioService
->HostnameIsLocalIPAddress(prinURI
, aIsIpAddress
);
1052 if (NS_FAILED(rv
)) {
1053 *aIsIpAddress
= false;
1059 BasePrincipal::GetScheme(nsACString
& aScheme
) {
1062 nsCOMPtr
<nsIURI
> prinURI
;
1063 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1064 if (NS_FAILED(rv
) || !prinURI
) {
1068 return prinURI
->GetScheme(aScheme
);
1072 BasePrincipal::SchemeIs(const char* aScheme
, bool* aResult
) {
1074 nsCOMPtr
<nsIURI
> prinURI
;
1075 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1076 if (NS_WARN_IF(NS_FAILED(rv
)) || !prinURI
) {
1079 *aResult
= prinURI
->SchemeIs(aScheme
);
1084 BasePrincipal::IsURIInPrefList(const char* aPref
, bool* aResult
) {
1085 AssertIsOnMainThread();
1087 nsCOMPtr
<nsIURI
> prinURI
;
1088 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1089 if (NS_FAILED(rv
) || !prinURI
) {
1092 *aResult
= nsContentUtils::IsURIInPrefList(prinURI
, aPref
);
1097 BasePrincipal::IsURIInList(const nsACString
& aList
, bool* aResult
) {
1099 nsCOMPtr
<nsIURI
> prinURI
;
1101 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1102 if (NS_FAILED(rv
) || !prinURI
) {
1106 *aResult
= nsContentUtils::IsURIInList(prinURI
, nsCString(aList
));
1111 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult
) {
1112 AssertIsOnMainThread();
1115 nsCOMPtr
<nsIURI
> uri
;
1116 nsresult rv
= GetURI(getter_AddRefs(uri
));
1117 if (NS_FAILED(rv
) || !uri
) {
1121 *aResult
= nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri
);
1126 BasePrincipal::GetIsLoopbackHost(bool* aRes
) {
1127 AssertIsOnMainThread();
1130 nsresult rv
= GetHost(host
);
1131 // Swallow potential failure as this method is infallible.
1132 NS_ENSURE_SUCCESS(rv
, NS_OK
);
1134 *aRes
= nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host
);
1139 BasePrincipal::GetAboutModuleFlags(uint32_t* flags
) {
1140 AssertIsOnMainThread();
1142 nsCOMPtr
<nsIURI
> prinURI
;
1143 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1144 if (NS_FAILED(rv
) || !prinURI
) {
1145 return NS_ERROR_NOT_AVAILABLE
;
1147 if (!prinURI
->SchemeIs("about")) {
1151 nsCOMPtr
<nsIAboutModule
> aboutModule
;
1152 rv
= NS_GetAboutModule(prinURI
, getter_AddRefs(aboutModule
));
1153 if (NS_FAILED(rv
) || !aboutModule
) {
1156 return aboutModule
->GetURIFlags(prinURI
, flags
);
1160 BasePrincipal::GetOriginAttributes(JSContext
* aCx
,
1161 JS::MutableHandle
<JS::Value
> aVal
) {
1162 if (NS_WARN_IF(!ToJSValue(aCx
, mOriginAttributes
, aVal
))) {
1163 return NS_ERROR_FAILURE
;
1169 BasePrincipal::GetOriginSuffix(nsACString
& aOriginAttributes
) {
1170 MOZ_ASSERT(mOriginSuffix
);
1171 mOriginSuffix
->ToUTF8String(aOriginAttributes
);
1176 BasePrincipal::GetUserContextId(uint32_t* aUserContextId
) {
1177 *aUserContextId
= UserContextId();
1182 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId
) {
1183 *aPrivateBrowsingId
= PrivateBrowsingId();
1188 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1189 bool* aIsInIsolatedMozBrowserElement
) {
1190 *aIsInIsolatedMozBrowserElement
= IsInIsolatedMozBrowserElement();
1194 nsresult
BasePrincipal::GetAddonPolicy(
1195 extensions::WebExtensionPolicy
** aResult
) {
1196 AssertIsOnMainThread();
1197 RefPtr
<extensions::WebExtensionPolicy
> policy(AddonPolicy());
1198 policy
.forget(aResult
);
1202 nsresult
BasePrincipal::GetContentScriptAddonPolicy(
1203 extensions::WebExtensionPolicy
** aResult
) {
1204 RefPtr
<extensions::WebExtensionPolicy
> policy(ContentScriptAddonPolicy());
1205 policy
.forget(aResult
);
1209 extensions::WebExtensionPolicy
* BasePrincipal::AddonPolicy() {
1210 AssertIsOnMainThread();
1211 RefPtr
<extensions::WebExtensionPolicyCore
> core
= AddonPolicyCore();
1212 return core
? core
->GetMainThreadPolicy() : nullptr;
1215 RefPtr
<extensions::WebExtensionPolicyCore
> BasePrincipal::AddonPolicyCore() {
1216 if (Is
<ContentPrincipal
>()) {
1217 return As
<ContentPrincipal
>()->AddonPolicyCore();
1222 bool BasePrincipal::AddonHasPermission(const nsAtom
* aPerm
) {
1223 if (auto policy
= AddonPolicyCore()) {
1224 return policy
->HasPermission(aPerm
);
1229 nsIPrincipal
* BasePrincipal::PrincipalToInherit(nsIURI
* aRequestedURI
) {
1230 if (Is
<ExpandedPrincipal
>()) {
1231 return As
<ExpandedPrincipal
>()->PrincipalToInherit(aRequestedURI
);
1236 bool BasePrincipal::OverridesCSP(nsIPrincipal
* aDocumentPrincipal
) {
1237 MOZ_ASSERT(aDocumentPrincipal
);
1239 // Expanded principals override CSP if and only if they subsume the document
1241 if (mKind
== eExpandedPrincipal
) {
1242 return FastSubsumes(aDocumentPrincipal
);
1244 // Extension principals always override the CSP of non-extension principals.
1245 // This is primarily for the sake of their stylesheets, which are usually
1246 // loaded from channels and cannot have expanded principals.
1247 return (AddonPolicyCore() &&
1248 !BasePrincipal::Cast(aDocumentPrincipal
)->AddonPolicyCore());
1251 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1252 nsIURI
* aURI
, const OriginAttributes
& aAttrs
, nsIURI
* aInitialDomain
) {
1255 nsAutoCString originNoSuffix
;
1257 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI
, originNoSuffix
);
1258 if (NS_FAILED(rv
)) {
1259 // If the generation of the origin fails, we still want to have a valid
1260 // principal. Better to return a null principal here.
1261 return NullPrincipal::Create(aAttrs
);
1264 return CreateContentPrincipal(aURI
, aAttrs
, originNoSuffix
, aInitialDomain
);
1267 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1268 nsIURI
* aURI
, const OriginAttributes
& aAttrs
,
1269 const nsACString
& aOriginNoSuffix
, nsIURI
* aInitialDomain
) {
1271 MOZ_ASSERT(!aOriginNoSuffix
.IsEmpty());
1273 // If the URI is supposed to inherit the security context of whoever loads it,
1274 // we shouldn't make a content principal for it.
1275 bool inheritsPrincipal
;
1276 nsresult rv
= NS_URIChainHasFlags(
1277 aURI
, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
1278 &inheritsPrincipal
);
1279 if (NS_FAILED(rv
) || inheritsPrincipal
) {
1280 return NullPrincipal::Create(aAttrs
);
1283 // Check whether the URI knows what its principal is supposed to be.
1284 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1285 nsCOMPtr
<nsIURIWithSpecialOrigin
> uriWithSpecialOrigin
=
1286 do_QueryInterface(aURI
);
1287 if (uriWithSpecialOrigin
) {
1288 nsCOMPtr
<nsIURI
> origin
;
1289 rv
= uriWithSpecialOrigin
->GetOrigin(getter_AddRefs(origin
));
1290 if (NS_WARN_IF(NS_FAILED(rv
))) {
1294 OriginAttributes attrs
;
1295 RefPtr
<BasePrincipal
> principal
=
1296 CreateContentPrincipal(origin
, attrs
, aInitialDomain
);
1297 return principal
.forget();
1301 nsCOMPtr
<nsIPrincipal
> blobPrincipal
;
1302 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1303 aURI
, getter_AddRefs(blobPrincipal
))) {
1304 MOZ_ASSERT(blobPrincipal
);
1305 MOZ_ASSERT(!aInitialDomain
,
1306 "an initial domain for a blob URI makes no sense");
1307 RefPtr
<BasePrincipal
> principal
= Cast(blobPrincipal
);
1308 return principal
.forget();
1311 // Mint a content principal.
1312 RefPtr
<ContentPrincipal
> principal
=
1313 new ContentPrincipal(aURI
, aAttrs
, aOriginNoSuffix
, aInitialDomain
);
1314 return principal
.forget();
1317 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1318 const nsACString
& aOrigin
) {
1319 MOZ_ASSERT(!StringBeginsWith(aOrigin
, "["_ns
),
1320 "CreateContentPrincipal does not support System and Expanded "
1324 !StringBeginsWith(aOrigin
, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME
":")),
1325 "CreateContentPrincipal does not support NullPrincipal");
1327 nsAutoCString originNoSuffix
;
1328 OriginAttributes attrs
;
1329 if (!attrs
.PopulateFromOrigin(aOrigin
, originNoSuffix
)) {
1333 nsCOMPtr
<nsIURI
> uri
;
1334 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), originNoSuffix
);
1335 NS_ENSURE_SUCCESS(rv
, nullptr);
1337 return BasePrincipal::CreateContentPrincipal(uri
, attrs
);
1340 already_AddRefed
<BasePrincipal
> BasePrincipal::CloneForcingOriginAttributes(
1341 const OriginAttributes
& aOriginAttributes
) {
1342 if (NS_WARN_IF(!IsContentPrincipal())) {
1346 nsAutoCString originNoSuffix
;
1347 nsresult rv
= GetOriginNoSuffix(originNoSuffix
);
1348 NS_ENSURE_SUCCESS(rv
, nullptr);
1350 nsCOMPtr
<nsIURI
> uri
;
1351 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri
)));
1353 // XXX: This does not copy over the domain. Should it?
1354 RefPtr
<ContentPrincipal
> copy
=
1355 new ContentPrincipal(uri
, aOriginAttributes
, originNoSuffix
, nullptr);
1356 return copy
.forget();
1359 extensions::WebExtensionPolicy
* BasePrincipal::ContentScriptAddonPolicy() {
1360 AssertIsOnMainThread();
1361 RefPtr
<extensions::WebExtensionPolicyCore
> core
=
1362 ContentScriptAddonPolicyCore();
1363 return core
? core
->GetMainThreadPolicy() : nullptr;
1366 RefPtr
<extensions::WebExtensionPolicyCore
>
1367 BasePrincipal::ContentScriptAddonPolicyCore() {
1368 if (!Is
<ExpandedPrincipal
>()) {
1372 auto* expanded
= As
<ExpandedPrincipal
>();
1373 for (const auto& prin
: expanded
->AllowList()) {
1374 if (RefPtr
<extensions::WebExtensionPolicyCore
> policy
=
1375 BasePrincipal::Cast(prin
)->AddonPolicyCore()) {
1383 bool BasePrincipal::AddonAllowsLoad(nsIURI
* aURI
,
1384 bool aExplicit
/* = false */) {
1385 if (Is
<ExpandedPrincipal
>()) {
1386 return As
<ExpandedPrincipal
>()->AddonAllowsLoad(aURI
, aExplicit
);
1388 if (auto policy
= AddonPolicyCore()) {
1389 return policy
->CanAccessURI(aURI
, aExplicit
);
1395 BasePrincipal::GetLocalStorageQuotaKey(nsACString
& aKey
) {
1398 nsCOMPtr
<nsIURI
> uri
;
1399 nsresult rv
= GetURI(getter_AddRefs(uri
));
1400 NS_ENSURE_SUCCESS(rv
, rv
);
1401 NS_ENSURE_TRUE(uri
, NS_ERROR_UNEXPECTED
);
1403 // The special handling of the file scheme should be consistent with
1404 // GetStorageOriginKey.
1406 nsAutoCString baseDomain
;
1407 rv
= uri
->GetAsciiHost(baseDomain
);
1408 NS_ENSURE_SUCCESS(rv
, rv
);
1410 if (baseDomain
.IsEmpty() && uri
->SchemeIs("file")) {
1411 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(uri
, &rv
);
1412 NS_ENSURE_SUCCESS(rv
, rv
);
1414 rv
= url
->GetDirectory(baseDomain
);
1415 NS_ENSURE_SUCCESS(rv
, rv
);
1417 nsCOMPtr
<nsIEffectiveTLDService
> eTLDService(
1418 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID
, &rv
));
1419 NS_ENSURE_SUCCESS(rv
, rv
);
1421 nsAutoCString eTLDplusOne
;
1422 rv
= eTLDService
->GetBaseDomain(uri
, 0, eTLDplusOne
);
1423 if (NS_SUCCEEDED(rv
)) {
1424 baseDomain
= eTLDplusOne
;
1425 } else if (rv
== NS_ERROR_HOST_IS_IP_ADDRESS
||
1426 rv
== NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
) {
1429 NS_ENSURE_SUCCESS(rv
, rv
);
1432 OriginAttributesRef().CreateSuffix(aKey
);
1434 nsAutoCString subdomainsDBKey
;
1435 rv
= dom::StorageUtils::CreateReversedDomain(baseDomain
, subdomainsDBKey
);
1436 NS_ENSURE_SUCCESS(rv
, rv
);
1439 aKey
.Append(subdomainsDBKey
);
1445 BasePrincipal::GetNextSubDomainPrincipal(
1446 nsIPrincipal
** aNextSubDomainPrincipal
) {
1447 nsCOMPtr
<nsIURI
> uri
;
1448 nsresult rv
= GetURI(getter_AddRefs(uri
));
1449 if (NS_FAILED(rv
) || !uri
) {
1454 rv
= uri
->GetHost(host
);
1455 if (NS_FAILED(rv
) || host
.IsEmpty()) {
1459 nsCString subDomain
;
1460 rv
= nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host
, subDomain
);
1462 if (NS_FAILED(rv
) || subDomain
.IsEmpty()) {
1466 nsCOMPtr
<nsIURI
> subDomainURI
;
1467 rv
= NS_MutateURI(uri
).SetHost(subDomain
).Finalize(subDomainURI
);
1468 if (NS_FAILED(rv
) || !subDomainURI
) {
1471 // Copy the attributes over
1472 mozilla::OriginAttributes attrs
= OriginAttributesRef();
1474 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1475 // Disable userContext for permissions.
1476 attrs
.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID
);
1478 RefPtr
<nsIPrincipal
> principal
=
1479 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI
, attrs
);
1484 principal
.forget(aNextSubDomainPrincipal
);
1489 BasePrincipal::GetStorageOriginKey(nsACString
& aOriginKey
) {
1490 aOriginKey
.Truncate();
1492 nsCOMPtr
<nsIURI
> uri
;
1493 nsresult rv
= GetURI(getter_AddRefs(uri
));
1494 NS_ENSURE_SUCCESS(rv
, rv
);
1495 NS_ENSURE_TRUE(uri
, NS_ERROR_UNEXPECTED
);
1497 // The special handling of the file scheme should be consistent with
1498 // GetLocalStorageQuotaKey.
1500 nsAutoCString domainOrigin
;
1501 rv
= uri
->GetAsciiHost(domainOrigin
);
1502 NS_ENSURE_SUCCESS(rv
, rv
);
1504 if (domainOrigin
.IsEmpty()) {
1505 // For the file:/// protocol use the exact directory as domain.
1506 if (uri
->SchemeIs("file")) {
1507 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(uri
, &rv
);
1508 NS_ENSURE_SUCCESS(rv
, rv
);
1509 rv
= url
->GetDirectory(domainOrigin
);
1510 NS_ENSURE_SUCCESS(rv
, rv
);
1514 // Append reversed domain
1515 nsAutoCString reverseDomain
;
1516 rv
= dom::StorageUtils::CreateReversedDomain(domainOrigin
, reverseDomain
);
1517 NS_ENSURE_SUCCESS(rv
, rv
);
1519 aOriginKey
.Append(reverseDomain
);
1522 nsAutoCString scheme
;
1523 rv
= uri
->GetScheme(scheme
);
1524 NS_ENSURE_SUCCESS(rv
, rv
);
1526 aOriginKey
.Append(':');
1527 aOriginKey
.Append(scheme
);
1529 // Append port if any
1530 int32_t port
= NS_GetRealPort(uri
);
1532 aOriginKey
.Append(nsPrintfCString(":%d", port
));
1539 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy
) {
1540 AssertIsOnMainThread();
1541 *aIsScriptAllowedByPolicy
= false;
1542 nsCOMPtr
<nsIURI
> prinURI
;
1543 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1544 if (NS_FAILED(rv
) || !prinURI
) {
1547 nsIScriptSecurityManager
* ssm
= nsContentUtils::GetSecurityManager();
1549 return NS_ERROR_UNEXPECTED
;
1551 return ssm
->PolicyAllowsScript(prinURI
, aIsScriptAllowedByPolicy
);
1554 bool SiteIdentifier::Equals(const SiteIdentifier
& aOther
) const {
1555 MOZ_ASSERT(IsInitialized());
1556 MOZ_ASSERT(aOther
.IsInitialized());
1557 return mPrincipal
->FastEquals(aOther
.mPrincipal
);
1561 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy
,
1562 nsIReferrerInfo
** _retval
) {
1563 nsCOMPtr
<nsIURI
> prinURI
;
1564 RefPtr
<dom::ReferrerInfo
> info
;
1565 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1566 if (NS_FAILED(rv
) || !prinURI
) {
1567 info
= new dom::ReferrerInfo(nullptr);
1568 info
.forget(_retval
);
1571 info
= new dom::ReferrerInfo(prinURI
, aReferrerPolicy
);
1572 info
.forget(_retval
);
1577 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal
** aPrecursor
) {
1578 *aPrecursor
= nullptr;
1582 NS_IMPL_ADDREF(BasePrincipal::Deserializer
)
1583 NS_IMPL_RELEASE(BasePrincipal::Deserializer
)
1585 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer
)
1586 NS_INTERFACE_MAP_ENTRY(nsISupports
)
1587 NS_INTERFACE_MAP_ENTRY(nsISerializable
)
1589 return mPrincipal
->QueryInterface(aIID
, aInstancePtr
);
1591 NS_INTERFACE_MAP_END
1594 BasePrincipal::Deserializer::Write(nsIObjectOutputStream
* aStream
) {
1595 // Read is used still for legacy principals
1596 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1601 void BasePrincipal::SetJSONValue(Json::Value
& aObject
, const char* aKey
,
1602 const nsCString
& aValue
) {
1603 aObject
[Json::StaticString(aKey
)] =
1604 Json::Value(aValue
.BeginReading(), aValue
.EndReading());
1607 } // namespace mozilla