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"
31 #include "mozilla/JSONStringWriteFuncs.h"
32 #include "mozilla/JSONWriter.h"
34 #include "nsEffectiveTLDService.h"
35 #include "nsIURIMutator.h"
36 #include "mozilla/StaticPrefs_permissions.h"
37 #include "nsIURIMutator.h"
38 #include "nsMixedContentBlocker.h"
40 #include "nsIURIFixup.h"
41 #include "mozilla/dom/StorageUtils.h"
42 #include "mozilla/StorageAccess.h"
43 #include "nsPIDOMWindow.h"
44 #include "nsIURIMutator.h"
45 #include "mozilla/PermissionManager.h"
47 #include "nsSerializationHelper.h"
50 #include "ContentPrincipalJSONHandler.h"
51 #include "ExpandedPrincipalJSONHandler.h"
52 #include "NullPrincipalJSONHandler.h"
53 #include "PrincipalJSONHandler.h"
54 #include "SubsumedPrincipalJSONHandler.h"
58 BasePrincipal::BasePrincipal(PrincipalKind aKind
,
59 const nsACString
& aOriginNoSuffix
,
60 const OriginAttributes
& aOriginAttributes
)
61 : mOriginNoSuffix(NS_Atomize(aOriginNoSuffix
)),
62 mOriginSuffix(aOriginAttributes
.CreateSuffixAtom()),
63 mOriginAttributes(aOriginAttributes
),
65 mHasExplicitDomain(false) {}
67 BasePrincipal::BasePrincipal(BasePrincipal
* aOther
,
68 const OriginAttributes
& aOriginAttributes
)
69 : mOriginNoSuffix(aOther
->mOriginNoSuffix
),
70 mOriginSuffix(aOriginAttributes
.CreateSuffixAtom()),
71 mOriginAttributes(aOriginAttributes
),
73 mHasExplicitDomain(aOther
->mHasExplicitDomain
.load()) {}
75 BasePrincipal::~BasePrincipal() = default;
78 BasePrincipal::GetOrigin(nsACString
& aOrigin
) {
79 nsresult rv
= GetOriginNoSuffix(aOrigin
);
80 NS_ENSURE_SUCCESS(rv
, rv
);
83 rv
= GetOriginSuffix(suffix
);
84 NS_ENSURE_SUCCESS(rv
, rv
);
85 aOrigin
.Append(suffix
);
90 BasePrincipal::GetWebExposedOriginSerialization(nsACString
& aOrigin
) {
92 nsCOMPtr
<nsIURI
> prinURI
;
93 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
94 if (NS_FAILED(rv
) || !prinURI
) {
95 return NS_ERROR_NOT_AVAILABLE
;
97 return nsContentUtils::GetWebExposedOriginSerialization(prinURI
, aOrigin
);
101 BasePrincipal::GetHostPort(nsACString
& aRes
) {
103 nsCOMPtr
<nsIURI
> prinURI
;
104 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
105 if (NS_FAILED(rv
) || !prinURI
) {
108 return prinURI
->GetHostPort(aRes
);
112 BasePrincipal::GetHost(nsACString
& aRes
) {
114 nsCOMPtr
<nsIURI
> prinURI
;
115 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
116 if (NS_FAILED(rv
) || !prinURI
) {
119 return prinURI
->GetHost(aRes
);
123 BasePrincipal::GetOriginNoSuffix(nsACString
& aOrigin
) {
124 mOriginNoSuffix
->ToUTF8String(aOrigin
);
129 BasePrincipal::GetSiteOrigin(nsACString
& aSiteOrigin
) {
130 nsresult rv
= GetSiteOriginNoSuffix(aSiteOrigin
);
131 NS_ENSURE_SUCCESS(rv
, rv
);
133 nsAutoCString suffix
;
134 rv
= GetOriginSuffix(suffix
);
135 NS_ENSURE_SUCCESS(rv
, rv
);
136 aSiteOrigin
.Append(suffix
);
141 BasePrincipal::GetSiteOriginNoSuffix(nsACString
& aSiteOrigin
) {
142 return GetOriginNoSuffix(aSiteOrigin
);
145 template <typename HandlerTypesT
>
146 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::ProcessInnerResult(
149 NS_WARNING("Failed to parse inner object");
150 mState
= State::Error
;
156 template <typename HandlerTypesT
>
157 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::startObject() {
158 if (mInnerHandler
.isSome()) {
159 return CallOnInner([&](auto& aInner
) { return aInner
.startObject(); });
164 mState
= State::StartObject
;
166 case State::SystemPrincipal_Key
:
167 mState
= State::SystemPrincipal_StartObject
;
170 NS_WARNING("Unexpected object value");
171 mState
= State::Error
;
178 template <typename HandlerTypesT
>
179 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::propertyName(
180 const JS::Latin1Char
* name
, size_t length
) {
181 if (mInnerHandler
.isSome()) {
183 [&](auto& aInner
) { return aInner
.propertyName(name
, length
); });
187 case State::StartObject
: {
190 nsPrintfCString("Unexpected property name length: %zu", length
)
192 mState
= State::Error
;
196 char key
= char(name
[0]);
198 case BasePrincipal::NullPrincipalKey
:
199 mState
= State::NullPrincipal_Inner
;
200 mInnerHandler
.emplace(VariantType
<NullPrincipalJSONHandler
>());
202 case BasePrincipal::ContentPrincipalKey
:
203 mState
= State::ContentPrincipal_Inner
;
204 mInnerHandler
.emplace(VariantType
<ContentPrincipalJSONHandler
>());
206 case BasePrincipal::SystemPrincipalKey
:
207 mState
= State::SystemPrincipal_Key
;
210 if constexpr (CanContainExpandedPrincipal
) {
211 if (key
== BasePrincipal::ExpandedPrincipalKey
) {
212 mState
= State::ExpandedPrincipal_Inner
;
213 mInnerHandler
.emplace(
214 VariantType
<ExpandedPrincipalJSONHandler
>());
219 nsPrintfCString("Unexpected property name: '%c'", key
).get());
220 mState
= State::Error
;
226 NS_WARNING("Unexpected property name");
227 mState
= State::Error
;
234 template <typename HandlerTypesT
>
235 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::endObject() {
236 if (mInnerHandler
.isSome()) {
237 return CallOnInner([&](auto& aInner
) {
238 if (!aInner
.endObject()) {
241 if (aInner
.HasAccepted()) {
242 this->mPrincipal
= aInner
.mPrincipal
.forget();
243 MOZ_ASSERT(this->mPrincipal
);
244 mInnerHandler
.reset();
251 case State::SystemPrincipal_StartObject
:
252 mState
= State::SystemPrincipal_EndObject
;
254 case State::SystemPrincipal_EndObject
:
256 BasePrincipal::Cast(nsContentUtils::GetSystemPrincipal());
257 mState
= State::EndObject
;
259 case State::NullPrincipal_Inner
:
260 mState
= State::EndObject
;
262 case State::ContentPrincipal_Inner
:
263 mState
= State::EndObject
;
266 if constexpr (CanContainExpandedPrincipal
) {
267 if (mState
== State::ExpandedPrincipal_Inner
) {
268 mState
= State::EndObject
;
272 NS_WARNING("Unexpected end of object");
273 mState
= State::Error
;
280 template <typename HandlerTypesT
>
281 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::startArray() {
282 if constexpr (CanContainExpandedPrincipal
) {
283 if (mInnerHandler
.isSome()) {
284 return CallOnInner([&](auto& aInner
) { return aInner
.startArray(); });
288 NS_WARNING("Unexpected array value");
289 mState
= State::Error
;
293 template <typename HandlerTypesT
>
294 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::endArray() {
295 if constexpr (CanContainExpandedPrincipal
) {
296 if (mInnerHandler
.isSome()) {
297 return CallOnInner([&](auto& aInner
) { return aInner
.endArray(); });
301 NS_WARNING("Unexpected array value");
302 mState
= State::Error
;
306 template <typename HandlerTypesT
>
307 bool ContainerPrincipalJSONHandler
<HandlerTypesT
>::stringValue(
308 const JS::Latin1Char
* str
, size_t length
) {
309 if (mInnerHandler
.isSome()) {
311 [&](auto& aInner
) { return aInner
.stringValue(str
, length
); });
314 NS_WARNING("Unexpected string value");
315 mState
= State::Error
;
319 template class ContainerPrincipalJSONHandler
<PrincipalJSONHandlerTypes
>;
320 template class ContainerPrincipalJSONHandler
<SubsumedPrincipalJSONHandlerTypes
>;
322 // Takes a JSON string and parses it turning it into a principal of the
323 // corresponding type
325 // Given a content principal:
329 // ---------------------------------------------------------
331 // {"1": {"0": "https://mozilla.com", "2": "^privateBrowsingId=1"}}
333 // | ----------------------------- |
335 // PrincipalKind | | |
336 // | ----------------------------
337 // SerializableKeys |
340 already_AddRefed
<BasePrincipal
> BasePrincipal::FromJSON(
341 const nsACString
& aJSON
) {
342 PrincipalJSONHandler handler
;
344 if (!JS::ParseJSONWithHandler(
345 reinterpret_cast<const JS::Latin1Char
*>(aJSON
.BeginReading()),
346 aJSON
.Length(), &handler
)) {
348 nsPrintfCString("Unable to parse: %s", aJSON
.BeginReading()).get());
350 "Unable to parse string as JSON to deserialize as a principal");
354 return handler
.Get();
357 // Returns a JSON representation of the principal.
358 // Calling BasePrincipal::FromJSON will deserialize the JSON into
359 // the corresponding principal type.
360 nsresult
BasePrincipal::ToJSON(nsACString
& aJSON
) {
361 MOZ_ASSERT(aJSON
.IsEmpty(), "ToJSON only supports an empty result input");
364 // NOTE: JSONWriter emits raw UTF-8 code units for non-ASCII range.
365 JSONStringRefWriteFunc
func(aJSON
);
366 JSONWriter
writer(func
, JSONWriter::CollectionStyle::SingleLineStyle
);
368 nsresult rv
= ToJSON(writer
);
369 NS_ENSURE_SUCCESS(rv
, rv
);
374 nsresult
BasePrincipal::ToJSON(JSONWriter
& aWriter
) {
375 static_assert(eKindMax
< ArrayLength(JSONEnumKeyStrings
));
377 aWriter
.Start(JSONWriter::CollectionStyle::SingleLineStyle
);
379 nsresult rv
= WriteJSONProperties(aWriter
);
380 NS_ENSURE_SUCCESS(rv
, rv
);
387 nsresult
BasePrincipal::WriteJSONProperties(JSONWriter
& aWriter
) {
388 aWriter
.StartObjectProperty(JSONEnumKeyStrings
[Kind()],
389 JSONWriter::CollectionStyle::SingleLineStyle
);
391 nsresult rv
= WriteJSONInnerProperties(aWriter
);
392 NS_ENSURE_SUCCESS(rv
, rv
);
399 nsresult
BasePrincipal::WriteJSONInnerProperties(JSONWriter
& aWriter
) {
403 bool BasePrincipal::FastSubsumesIgnoringFPD(
404 nsIPrincipal
* aOther
, DocumentDomainConsideration aConsideration
) {
407 if (Kind() == eContentPrincipal
&&
408 !dom::ChromeUtils::IsOriginAttributesEqualIgnoringFPD(
409 mOriginAttributes
, Cast(aOther
)->mOriginAttributes
)) {
413 return SubsumesInternal(aOther
, aConsideration
);
416 bool BasePrincipal::Subsumes(nsIPrincipal
* aOther
,
417 DocumentDomainConsideration aConsideration
) {
419 MOZ_ASSERT_IF(Kind() == eContentPrincipal
, mOriginSuffix
);
421 // Expanded principals handle origin attributes for each of their
422 // sub-principals individually, null principals do only simple checks for
423 // pointer equality, and system principals are immune to origin attributes
424 // checks, so only do this check for content principals.
425 if (Kind() == eContentPrincipal
&&
426 mOriginSuffix
!= Cast(aOther
)->mOriginSuffix
) {
430 return SubsumesInternal(aOther
, aConsideration
);
434 BasePrincipal::Equals(nsIPrincipal
* aOther
, bool* aResult
) {
435 NS_ENSURE_ARG_POINTER(aOther
);
437 *aResult
= FastEquals(aOther
);
443 BasePrincipal::EqualsForPermission(nsIPrincipal
* aOther
, bool aExactHost
,
446 NS_ENSURE_ARG_POINTER(aOther
);
447 NS_ENSURE_ARG_POINTER(aResult
);
449 auto* other
= Cast(aOther
);
450 if (Kind() != other
->Kind()) {
451 // Principals of different kinds can't be equal.
455 if (Kind() == eSystemPrincipal
) {
456 *aResult
= this == other
;
460 if (Kind() == eNullPrincipal
) {
461 // We don't store permissions for NullPrincipals.
465 MOZ_ASSERT(Kind() == eExpandedPrincipal
|| Kind() == eContentPrincipal
);
467 // Certain origin attributes should not be used to isolate permissions.
468 // Create a stripped copy of both OA sets to compare.
469 mozilla::OriginAttributes ourAttrs
= mOriginAttributes
;
470 PermissionManager::MaybeStripOriginAttributes(false, ourAttrs
);
471 mozilla::OriginAttributes theirAttrs
= aOther
->OriginAttributesRef();
472 PermissionManager::MaybeStripOriginAttributes(false, theirAttrs
);
474 if (ourAttrs
!= theirAttrs
) {
478 if (mOriginNoSuffix
== other
->mOriginNoSuffix
) {
483 // If we are matching with an exact host, we're done now - the permissions
484 // don't match otherwise, we need to start comparing subdomains!
489 nsCOMPtr
<nsIURI
> ourURI
;
490 nsresult rv
= GetURI(getter_AddRefs(ourURI
));
491 NS_ENSURE_SUCCESS(rv
, rv
);
492 // Some principal types may indicate success, but still return nullptr for
494 NS_ENSURE_TRUE(ourURI
, NS_ERROR_FAILURE
);
496 nsCOMPtr
<nsIURI
> otherURI
;
497 rv
= other
->GetURI(getter_AddRefs(otherURI
));
498 NS_ENSURE_SUCCESS(rv
, rv
);
499 NS_ENSURE_TRUE(otherURI
, NS_ERROR_FAILURE
);
502 nsAutoCString otherScheme
;
503 rv
= otherURI
->GetScheme(otherScheme
);
504 NS_ENSURE_SUCCESS(rv
, rv
);
506 nsAutoCString ourScheme
;
507 rv
= ourURI
->GetScheme(ourScheme
);
508 NS_ENSURE_SUCCESS(rv
, rv
);
510 if (otherScheme
!= ourScheme
) {
516 rv
= otherURI
->GetPort(&otherPort
);
517 NS_ENSURE_SUCCESS(rv
, rv
);
520 rv
= ourURI
->GetPort(&ourPort
);
521 NS_ENSURE_SUCCESS(rv
, rv
);
523 if (otherPort
!= ourPort
) {
527 // Check if the host or any subdomain of their host matches.
528 nsAutoCString otherHost
;
529 rv
= otherURI
->GetHost(otherHost
);
530 if (NS_FAILED(rv
) || otherHost
.IsEmpty()) {
534 nsAutoCString ourHost
;
535 rv
= ourURI
->GetHost(ourHost
);
536 if (NS_FAILED(rv
) || ourHost
.IsEmpty()) {
540 nsCOMPtr
<nsIEffectiveTLDService
> tldService
=
541 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID
);
543 NS_ERROR("Should have a tld service!");
544 return NS_ERROR_FAILURE
;
547 // This loop will not loop forever, as GetNextSubDomain will eventually fail
548 // with NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS.
549 while (otherHost
!= ourHost
) {
550 rv
= tldService
->GetNextSubDomain(otherHost
, otherHost
);
552 if (rv
== NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
) {
564 BasePrincipal::EqualsConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
565 NS_ENSURE_ARG_POINTER(aOther
);
567 *aResult
= FastEqualsConsideringDomain(aOther
);
573 BasePrincipal::EqualsURI(nsIURI
* aOtherURI
, bool* aResult
) {
575 nsCOMPtr
<nsIURI
> prinURI
;
576 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
577 if (NS_FAILED(rv
) || !prinURI
) {
580 return prinURI
->EqualsExceptRef(aOtherURI
, aResult
);
584 BasePrincipal::Subsumes(nsIPrincipal
* aOther
, bool* aResult
) {
585 NS_ENSURE_ARG_POINTER(aOther
);
587 *aResult
= FastSubsumes(aOther
);
593 BasePrincipal::SubsumesConsideringDomain(nsIPrincipal
* aOther
, bool* aResult
) {
594 NS_ENSURE_ARG_POINTER(aOther
);
596 *aResult
= FastSubsumesConsideringDomain(aOther
);
602 BasePrincipal::SubsumesConsideringDomainIgnoringFPD(nsIPrincipal
* aOther
,
604 NS_ENSURE_ARG_POINTER(aOther
);
606 *aResult
= FastSubsumesConsideringDomainIgnoringFPD(aOther
);
612 BasePrincipal::CheckMayLoad(nsIURI
* aURI
, bool aAllowIfInheritsPrincipal
) {
613 AssertIsOnMainThread();
614 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, false, 0);
618 BasePrincipal::CheckMayLoadWithReporting(nsIURI
* aURI
,
619 bool aAllowIfInheritsPrincipal
,
620 uint64_t aInnerWindowID
) {
621 AssertIsOnMainThread();
622 return CheckMayLoadHelper(aURI
, aAllowIfInheritsPrincipal
, true,
626 nsresult
BasePrincipal::CheckMayLoadHelper(nsIURI
* aURI
,
627 bool aAllowIfInheritsPrincipal
,
629 uint64_t aInnerWindowID
) {
630 AssertIsOnMainThread(); // Accesses non-threadsafe URI flags and the
631 // non-threadsafe ExtensionPolicyService
632 NS_ENSURE_ARG_POINTER(aURI
);
634 aReport
|| aInnerWindowID
== 0,
635 "Why do we have an inner window id if we're not supposed to report?");
637 // Check the internal method first, which allows us to quickly approve loads
638 // for the System Principal.
639 if (MayLoadInternal(aURI
)) {
644 if (aAllowIfInheritsPrincipal
) {
645 // If the caller specified to allow loads of URIs that inherit
646 // our principal, allow the load if this URI inherits its principal.
647 bool doesInheritSecurityContext
;
648 rv
= NS_URIChainHasFlags(aURI
,
649 nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
650 &doesInheritSecurityContext
);
651 if (NS_SUCCEEDED(rv
) && doesInheritSecurityContext
) {
656 // Web Accessible Resources in MV2 Extensions are marked with
657 // URI_FETCHABLE_BY_ANYONE
658 bool fetchableByAnyone
;
659 rv
= NS_URIChainHasFlags(aURI
, nsIProtocolHandler::URI_FETCHABLE_BY_ANYONE
,
661 if (NS_SUCCEEDED(rv
) && fetchableByAnyone
) {
665 // Get the principal uri for the last flag check or error.
666 nsCOMPtr
<nsIURI
> prinURI
;
667 rv
= GetURI(getter_AddRefs(prinURI
));
668 if (!(NS_SUCCEEDED(rv
) && prinURI
)) {
669 return NS_ERROR_DOM_BAD_URI
;
672 // If MV3 Extension uris are web accessible by this principal it is allowed to
674 bool maybeWebAccessible
= false;
675 NS_URIChainHasFlags(aURI
, nsIProtocolHandler::WEBEXT_URI_WEB_ACCESSIBLE
,
676 &maybeWebAccessible
);
677 NS_ENSURE_SUCCESS(rv
, rv
);
678 if (maybeWebAccessible
) {
679 bool isWebAccessible
= false;
680 rv
= ExtensionPolicyService::GetSingleton().SourceMayLoadExtensionURI(
681 prinURI
, aURI
, &isWebAccessible
);
682 if (NS_SUCCEEDED(rv
) && isWebAccessible
) {
688 nsScriptSecurityManager::ReportError(
689 "CheckSameOriginError", prinURI
, aURI
,
690 mOriginAttributes
.mPrivateBrowsingId
> 0, aInnerWindowID
);
693 return NS_ERROR_DOM_BAD_URI
;
697 BasePrincipal::IsThirdPartyURI(nsIURI
* aURI
, bool* aRes
) {
698 if (IsSystemPrincipal() || (AddonPolicyCore() && AddonAllowsLoad(aURI
))) {
704 // If we do not have a URI its always 3rd party.
705 nsCOMPtr
<nsIURI
> prinURI
;
706 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
707 if (NS_FAILED(rv
) || !prinURI
) {
710 ThirdPartyUtil
* thirdPartyUtil
= ThirdPartyUtil::GetInstance();
711 return thirdPartyUtil
->IsThirdPartyURI(prinURI
, aURI
, aRes
);
715 BasePrincipal::IsThirdPartyPrincipal(nsIPrincipal
* aPrin
, bool* aRes
) {
717 nsCOMPtr
<nsIURI
> prinURI
;
718 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
719 if (NS_FAILED(rv
) || !prinURI
) {
722 return aPrin
->IsThirdPartyURI(prinURI
, aRes
);
726 BasePrincipal::IsThirdPartyChannel(nsIChannel
* aChan
, bool* aRes
) {
727 AssertIsOnMainThread();
728 if (IsSystemPrincipal()) {
729 // Nothing is 3rd party to the system principal.
734 nsCOMPtr
<nsIURI
> prinURI
;
735 GetURI(getter_AddRefs(prinURI
));
736 ThirdPartyUtil
* thirdPartyUtil
= ThirdPartyUtil::GetInstance();
737 return thirdPartyUtil
->IsThirdPartyChannel(aChan
, prinURI
, aRes
);
741 BasePrincipal::IsSameOrigin(nsIURI
* aURI
, bool* aRes
) {
743 nsCOMPtr
<nsIURI
> prinURI
;
744 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
745 if (NS_FAILED(rv
) || !prinURI
) {
746 // Note that expanded and system principals return here, because they have
750 *aRes
= nsScriptSecurityManager::SecurityCompareURIs(prinURI
, aURI
);
755 BasePrincipal::IsL10nAllowed(nsIURI
* aURI
, bool* aRes
) {
756 AssertIsOnMainThread(); // URI_DANGEROUS_TO_LOAD is not threadsafe to query.
759 if (nsContentUtils::IsErrorPage(aURI
)) {
764 // The system principal is always allowed.
765 if (IsSystemPrincipal()) {
770 nsCOMPtr
<nsIURI
> uri
;
771 nsresult rv
= GetURI(getter_AddRefs(uri
));
772 NS_ENSURE_SUCCESS(rv
, NS_OK
);
776 // Allow access to uris that cannot be loaded by web content.
777 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_DANGEROUS_TO_LOAD
,
779 NS_ENSURE_SUCCESS(rv
, NS_OK
);
785 // UI resources also get access.
786 rv
= NS_URIChainHasFlags(uri
, nsIProtocolHandler::URI_IS_UI_RESOURCE
,
788 NS_ENSURE_SUCCESS(rv
, NS_OK
);
794 auto policy
= AddonPolicyCore();
795 *aRes
= (policy
&& policy
->IsPrivileged());
800 BasePrincipal::AllowsRelaxStrictFileOriginPolicy(nsIURI
* aURI
, bool* aRes
) {
802 nsCOMPtr
<nsIURI
> prinURI
;
803 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
804 if (NS_FAILED(rv
) || !prinURI
) {
807 *aRes
= NS_RelaxStrictFileOriginPolicy(aURI
, prinURI
);
812 BasePrincipal::GetPrefLightCacheKey(nsIURI
* aURI
, bool aWithCredentials
,
813 const OriginAttributes
& aOriginAttributes
,
814 nsACString
& _retval
) {
816 constexpr auto space
= " "_ns
;
818 nsCOMPtr
<nsIURI
> uri
;
819 nsresult rv
= GetURI(getter_AddRefs(uri
));
820 NS_ENSURE_SUCCESS(rv
, rv
);
822 nsAutoCString scheme
, host
, port
;
824 uri
->GetScheme(scheme
);
826 port
.AppendInt(NS_GetRealPort(uri
));
829 if (aWithCredentials
) {
830 _retval
.AssignLiteral("cred");
832 _retval
.AssignLiteral("nocred");
836 rv
= aURI
->GetSpec(spec
);
837 NS_ENSURE_SUCCESS(rv
, rv
);
839 nsAutoCString originAttributesSuffix
;
840 aOriginAttributes
.CreateSuffix(originAttributesSuffix
);
842 _retval
.Append(space
+ scheme
+ space
+ host
+ space
+ port
+ space
+ spec
+
843 space
+ originAttributesSuffix
);
849 BasePrincipal::HasFirstpartyStorageAccess(mozIDOMWindow
* aCheckWindow
,
850 uint32_t* aRejectedReason
,
852 AssertIsOnMainThread();
853 *aRejectedReason
= 0;
854 *aOutAllowed
= false;
856 nsPIDOMWindowInner
* win
= nsPIDOMWindowInner::From(aCheckWindow
);
857 nsCOMPtr
<nsIURI
> uri
;
858 nsresult rv
= GetURI(getter_AddRefs(uri
));
862 *aOutAllowed
= ShouldAllowAccessFor(win
, uri
, aRejectedReason
);
867 BasePrincipal::GetIsNullPrincipal(bool* aResult
) {
868 *aResult
= Kind() == eNullPrincipal
;
873 BasePrincipal::GetIsContentPrincipal(bool* aResult
) {
874 *aResult
= Kind() == eContentPrincipal
;
879 BasePrincipal::GetIsExpandedPrincipal(bool* aResult
) {
880 *aResult
= Kind() == eExpandedPrincipal
;
885 BasePrincipal::GetAsciiSpec(nsACString
& aSpec
) {
887 nsCOMPtr
<nsIURI
> prinURI
;
888 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
889 if (NS_FAILED(rv
) || !prinURI
) {
892 return prinURI
->GetAsciiSpec(aSpec
);
896 BasePrincipal::GetSpec(nsACString
& aSpec
) {
898 nsCOMPtr
<nsIURI
> prinURI
;
899 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
900 if (NS_FAILED(rv
) || !prinURI
) {
903 return prinURI
->GetSpec(aSpec
);
907 BasePrincipal::GetAsciiHost(nsACString
& aHost
) {
909 nsCOMPtr
<nsIURI
> prinURI
;
910 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
911 if (NS_FAILED(rv
) || !prinURI
) {
914 return prinURI
->GetAsciiHost(aHost
);
918 BasePrincipal::GetExposablePrePath(nsACString
& aPrepath
) {
920 nsCOMPtr
<nsIURI
> prinURI
;
921 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
922 if (NS_FAILED(rv
) || !prinURI
) {
926 nsCOMPtr
<nsIURI
> exposableURI
= net::nsIOService::CreateExposableURI(prinURI
);
927 return exposableURI
->GetDisplayPrePath(aPrepath
);
931 BasePrincipal::GetExposableSpec(nsACString
& aSpec
) {
933 nsCOMPtr
<nsIURI
> prinURI
;
934 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
935 if (NS_FAILED(rv
) || !prinURI
) {
938 nsCOMPtr
<nsIURI
> clone
;
939 rv
= NS_MutateURI(prinURI
)
944 NS_ENSURE_SUCCESS(rv
, rv
);
945 return clone
->GetAsciiSpec(aSpec
);
949 BasePrincipal::GetPrePath(nsACString
& aPath
) {
951 nsCOMPtr
<nsIURI
> prinURI
;
952 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
953 if (NS_FAILED(rv
) || !prinURI
) {
956 return prinURI
->GetPrePath(aPath
);
960 BasePrincipal::GetFilePath(nsACString
& aPath
) {
962 nsCOMPtr
<nsIURI
> prinURI
;
963 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
964 if (NS_FAILED(rv
) || !prinURI
) {
967 return prinURI
->GetFilePath(aPath
);
971 BasePrincipal::GetIsSystemPrincipal(bool* aResult
) {
972 *aResult
= IsSystemPrincipal();
977 BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult
) {
978 *aResult
= AddonPolicyCore() || ContentScriptAddonPolicyCore();
982 NS_IMETHODIMP
BasePrincipal::GetIsOnion(bool* aIsOnion
) {
984 nsCOMPtr
<nsIURI
> prinURI
;
985 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
986 if (NS_FAILED(rv
) || !prinURI
) {
991 rv
= prinURI
->GetHost(host
);
995 *aIsOnion
= StringEndsWith(host
, ".onion"_ns
);
999 NS_IMETHODIMP
BasePrincipal::GetIsIpAddress(bool* aIsIpAddress
) {
1000 *aIsIpAddress
= false;
1002 nsCOMPtr
<nsIURI
> prinURI
;
1003 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1004 if (NS_FAILED(rv
) || !prinURI
) {
1009 rv
= prinURI
->GetHost(host
);
1010 if (NS_FAILED(rv
)) {
1015 memset(&prAddr
, 0, sizeof(prAddr
));
1017 if (PR_StringToNetAddr(host
.get(), &prAddr
) == PR_SUCCESS
) {
1018 *aIsIpAddress
= true;
1024 NS_IMETHODIMP
BasePrincipal::GetIsLocalIpAddress(bool* aIsIpAddress
) {
1025 *aIsIpAddress
= false;
1027 nsCOMPtr
<nsIURI
> prinURI
;
1028 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1029 if (NS_FAILED(rv
) || !prinURI
) {
1033 nsCOMPtr
<nsIIOService
> ioService
= do_GetIOService(&rv
);
1034 if (NS_FAILED(rv
) || !ioService
) {
1037 rv
= ioService
->HostnameIsLocalIPAddress(prinURI
, aIsIpAddress
);
1038 if (NS_FAILED(rv
)) {
1039 *aIsIpAddress
= false;
1045 BasePrincipal::GetScheme(nsACString
& aScheme
) {
1048 nsCOMPtr
<nsIURI
> prinURI
;
1049 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1050 if (NS_FAILED(rv
) || !prinURI
) {
1054 return prinURI
->GetScheme(aScheme
);
1058 BasePrincipal::SchemeIs(const char* aScheme
, bool* aResult
) {
1060 nsCOMPtr
<nsIURI
> prinURI
;
1061 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1062 if (NS_WARN_IF(NS_FAILED(rv
)) || !prinURI
) {
1065 *aResult
= prinURI
->SchemeIs(aScheme
);
1070 BasePrincipal::IsURIInPrefList(const char* aPref
, bool* aResult
) {
1071 AssertIsOnMainThread();
1073 nsCOMPtr
<nsIURI
> prinURI
;
1074 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1075 if (NS_FAILED(rv
) || !prinURI
) {
1078 *aResult
= nsContentUtils::IsURIInPrefList(prinURI
, aPref
);
1083 BasePrincipal::IsURIInList(const nsACString
& aList
, bool* aResult
) {
1085 nsCOMPtr
<nsIURI
> prinURI
;
1087 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1088 if (NS_FAILED(rv
) || !prinURI
) {
1092 *aResult
= nsContentUtils::IsURIInList(prinURI
, nsCString(aList
));
1097 BasePrincipal::IsContentAccessibleAboutURI(bool* aResult
) {
1100 nsCOMPtr
<nsIURI
> prinURI
;
1101 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1102 if (NS_FAILED(rv
) || !prinURI
) {
1106 if (!prinURI
->SchemeIs("about")) {
1110 *aResult
= NS_IsContentAccessibleAboutURI(prinURI
);
1115 BasePrincipal::GetIsOriginPotentiallyTrustworthy(bool* aResult
) {
1116 AssertIsOnMainThread();
1119 nsCOMPtr
<nsIURI
> uri
;
1120 nsresult rv
= GetURI(getter_AddRefs(uri
));
1121 if (NS_FAILED(rv
) || !uri
) {
1125 *aResult
= nsMixedContentBlocker::IsPotentiallyTrustworthyOrigin(uri
);
1130 BasePrincipal::GetIsLoopbackHost(bool* aRes
) {
1131 AssertIsOnMainThread();
1134 nsresult rv
= GetHost(host
);
1135 // Swallow potential failure as this method is infallible.
1136 if (NS_FAILED(rv
)) {
1140 *aRes
= nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(host
);
1145 BasePrincipal::GetAboutModuleFlags(uint32_t* flags
) {
1146 AssertIsOnMainThread();
1148 nsCOMPtr
<nsIURI
> prinURI
;
1149 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1150 if (NS_FAILED(rv
) || !prinURI
) {
1151 return NS_ERROR_NOT_AVAILABLE
;
1153 if (!prinURI
->SchemeIs("about")) {
1157 nsCOMPtr
<nsIAboutModule
> aboutModule
;
1158 rv
= NS_GetAboutModule(prinURI
, getter_AddRefs(aboutModule
));
1159 if (NS_FAILED(rv
) || !aboutModule
) {
1162 return aboutModule
->GetURIFlags(prinURI
, flags
);
1166 BasePrincipal::GetOriginAttributes(JSContext
* aCx
,
1167 JS::MutableHandle
<JS::Value
> aVal
) {
1168 if (NS_WARN_IF(!ToJSValue(aCx
, mOriginAttributes
, aVal
))) {
1169 return NS_ERROR_FAILURE
;
1175 BasePrincipal::GetOriginSuffix(nsACString
& aOriginAttributes
) {
1176 MOZ_ASSERT(mOriginSuffix
);
1177 mOriginSuffix
->ToUTF8String(aOriginAttributes
);
1182 BasePrincipal::GetUserContextId(uint32_t* aUserContextId
) {
1183 *aUserContextId
= UserContextId();
1188 BasePrincipal::GetPrivateBrowsingId(uint32_t* aPrivateBrowsingId
) {
1189 *aPrivateBrowsingId
= PrivateBrowsingId();
1194 BasePrincipal::GetIsInIsolatedMozBrowserElement(
1195 bool* aIsInIsolatedMozBrowserElement
) {
1196 *aIsInIsolatedMozBrowserElement
= IsInIsolatedMozBrowserElement();
1200 nsresult
BasePrincipal::GetAddonPolicy(
1201 extensions::WebExtensionPolicy
** aResult
) {
1202 AssertIsOnMainThread();
1203 RefPtr
<extensions::WebExtensionPolicy
> policy(AddonPolicy());
1204 policy
.forget(aResult
);
1208 nsresult
BasePrincipal::GetContentScriptAddonPolicy(
1209 extensions::WebExtensionPolicy
** aResult
) {
1210 RefPtr
<extensions::WebExtensionPolicy
> policy(ContentScriptAddonPolicy());
1211 policy
.forget(aResult
);
1215 extensions::WebExtensionPolicy
* BasePrincipal::AddonPolicy() {
1216 AssertIsOnMainThread();
1217 RefPtr
<extensions::WebExtensionPolicyCore
> core
= AddonPolicyCore();
1218 return core
? core
->GetMainThreadPolicy() : nullptr;
1221 RefPtr
<extensions::WebExtensionPolicyCore
> BasePrincipal::AddonPolicyCore() {
1222 if (Is
<ContentPrincipal
>()) {
1223 return As
<ContentPrincipal
>()->AddonPolicyCore();
1228 bool BasePrincipal::AddonHasPermission(const nsAtom
* aPerm
) {
1229 if (auto policy
= AddonPolicyCore()) {
1230 return policy
->HasPermission(aPerm
);
1235 nsIPrincipal
* BasePrincipal::PrincipalToInherit(nsIURI
* aRequestedURI
) {
1236 if (Is
<ExpandedPrincipal
>()) {
1237 return As
<ExpandedPrincipal
>()->PrincipalToInherit(aRequestedURI
);
1242 bool BasePrincipal::OverridesCSP(nsIPrincipal
* aDocumentPrincipal
) {
1243 MOZ_ASSERT(aDocumentPrincipal
);
1245 // Expanded principals override CSP if and only if they subsume the document
1247 if (mKind
== eExpandedPrincipal
) {
1248 return FastSubsumes(aDocumentPrincipal
);
1250 // Extension principals always override the CSP of non-extension principals.
1251 // This is primarily for the sake of their stylesheets, which are usually
1252 // loaded from channels and cannot have expanded principals.
1253 return (AddonPolicyCore() &&
1254 !BasePrincipal::Cast(aDocumentPrincipal
)->AddonPolicyCore());
1257 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1258 nsIURI
* aURI
, const OriginAttributes
& aAttrs
, nsIURI
* aInitialDomain
) {
1261 nsAutoCString originNoSuffix
;
1263 ContentPrincipal::GenerateOriginNoSuffixFromURI(aURI
, originNoSuffix
);
1264 if (NS_FAILED(rv
)) {
1265 // If the generation of the origin fails, we still want to have a valid
1266 // principal. Better to return a null principal here.
1267 return NullPrincipal::Create(aAttrs
);
1270 return CreateContentPrincipal(aURI
, aAttrs
, originNoSuffix
, aInitialDomain
);
1273 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1274 nsIURI
* aURI
, const OriginAttributes
& aAttrs
,
1275 const nsACString
& aOriginNoSuffix
, nsIURI
* aInitialDomain
) {
1277 MOZ_ASSERT(!aOriginNoSuffix
.IsEmpty());
1279 // If the URI is supposed to inherit the security context of whoever loads it,
1280 // we shouldn't make a content principal for it.
1281 bool inheritsPrincipal
;
1282 nsresult rv
= NS_URIChainHasFlags(
1283 aURI
, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT
,
1284 &inheritsPrincipal
);
1285 if (NS_FAILED(rv
) || inheritsPrincipal
) {
1286 return NullPrincipal::Create(aAttrs
);
1289 // Check whether the URI knows what its principal is supposed to be.
1290 #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE)
1291 nsCOMPtr
<nsIURIWithSpecialOrigin
> uriWithSpecialOrigin
=
1292 do_QueryInterface(aURI
);
1293 if (uriWithSpecialOrigin
) {
1294 nsCOMPtr
<nsIURI
> origin
;
1295 rv
= uriWithSpecialOrigin
->GetOrigin(getter_AddRefs(origin
));
1296 if (NS_WARN_IF(NS_FAILED(rv
))) {
1300 OriginAttributes attrs
;
1301 RefPtr
<BasePrincipal
> principal
=
1302 CreateContentPrincipal(origin
, attrs
, aInitialDomain
);
1303 return principal
.forget();
1307 nsCOMPtr
<nsIPrincipal
> blobPrincipal
;
1308 if (dom::BlobURLProtocolHandler::GetBlobURLPrincipal(
1309 aURI
, getter_AddRefs(blobPrincipal
))) {
1310 MOZ_ASSERT(blobPrincipal
);
1311 MOZ_ASSERT(!aInitialDomain
,
1312 "an initial domain for a blob URI makes no sense");
1313 RefPtr
<BasePrincipal
> principal
= Cast(blobPrincipal
);
1314 return principal
.forget();
1317 // Mint a content principal.
1318 RefPtr
<ContentPrincipal
> principal
=
1319 new ContentPrincipal(aURI
, aAttrs
, aOriginNoSuffix
, aInitialDomain
);
1320 return principal
.forget();
1323 already_AddRefed
<BasePrincipal
> BasePrincipal::CreateContentPrincipal(
1324 const nsACString
& aOrigin
) {
1325 MOZ_ASSERT(!StringBeginsWith(aOrigin
, "["_ns
),
1326 "CreateContentPrincipal does not support System and Expanded "
1330 !StringBeginsWith(aOrigin
, nsLiteralCString(NS_NULLPRINCIPAL_SCHEME
":")),
1331 "CreateContentPrincipal does not support NullPrincipal");
1333 nsAutoCString originNoSuffix
;
1334 OriginAttributes attrs
;
1335 if (!attrs
.PopulateFromOrigin(aOrigin
, originNoSuffix
)) {
1339 nsCOMPtr
<nsIURI
> uri
;
1340 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), originNoSuffix
);
1341 NS_ENSURE_SUCCESS(rv
, nullptr);
1343 return BasePrincipal::CreateContentPrincipal(uri
, attrs
);
1346 already_AddRefed
<BasePrincipal
> BasePrincipal::CloneForcingOriginAttributes(
1347 const OriginAttributes
& aOriginAttributes
) {
1348 if (NS_WARN_IF(!IsContentPrincipal())) {
1352 nsAutoCString originNoSuffix
;
1353 nsresult rv
= GetOriginNoSuffix(originNoSuffix
);
1354 NS_ENSURE_SUCCESS(rv
, nullptr);
1356 nsCOMPtr
<nsIURI
> uri
;
1357 MOZ_ALWAYS_SUCCEEDS(GetURI(getter_AddRefs(uri
)));
1359 // XXX: This does not copy over the domain. Should it?
1360 RefPtr
<ContentPrincipal
> copy
=
1361 new ContentPrincipal(uri
, aOriginAttributes
, originNoSuffix
, nullptr);
1362 return copy
.forget();
1365 extensions::WebExtensionPolicy
* BasePrincipal::ContentScriptAddonPolicy() {
1366 AssertIsOnMainThread();
1367 RefPtr
<extensions::WebExtensionPolicyCore
> core
=
1368 ContentScriptAddonPolicyCore();
1369 return core
? core
->GetMainThreadPolicy() : nullptr;
1372 RefPtr
<extensions::WebExtensionPolicyCore
>
1373 BasePrincipal::ContentScriptAddonPolicyCore() {
1374 if (!Is
<ExpandedPrincipal
>()) {
1378 auto* expanded
= As
<ExpandedPrincipal
>();
1379 for (const auto& prin
: expanded
->AllowList()) {
1380 if (RefPtr
<extensions::WebExtensionPolicyCore
> policy
=
1381 BasePrincipal::Cast(prin
)->AddonPolicyCore()) {
1389 bool BasePrincipal::AddonAllowsLoad(nsIURI
* aURI
,
1390 bool aExplicit
/* = false */) {
1391 if (Is
<ExpandedPrincipal
>()) {
1392 return As
<ExpandedPrincipal
>()->AddonAllowsLoad(aURI
, aExplicit
);
1394 if (auto policy
= AddonPolicyCore()) {
1395 return policy
->CanAccessURI(aURI
, aExplicit
);
1401 BasePrincipal::GetLocalStorageQuotaKey(nsACString
& aKey
) {
1404 nsCOMPtr
<nsIURI
> uri
;
1405 nsresult rv
= GetURI(getter_AddRefs(uri
));
1406 NS_ENSURE_SUCCESS(rv
, rv
);
1407 NS_ENSURE_TRUE(uri
, NS_ERROR_UNEXPECTED
);
1409 // The special handling of the file scheme should be consistent with
1410 // GetStorageOriginKey.
1412 nsAutoCString baseDomain
;
1413 rv
= uri
->GetAsciiHost(baseDomain
);
1414 NS_ENSURE_SUCCESS(rv
, rv
);
1416 if (baseDomain
.IsEmpty() && uri
->SchemeIs("file")) {
1417 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(uri
, &rv
);
1418 NS_ENSURE_SUCCESS(rv
, rv
);
1420 rv
= url
->GetDirectory(baseDomain
);
1421 NS_ENSURE_SUCCESS(rv
, rv
);
1423 nsCOMPtr
<nsIEffectiveTLDService
> eTLDService(
1424 do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID
, &rv
));
1425 NS_ENSURE_SUCCESS(rv
, rv
);
1427 nsAutoCString eTLDplusOne
;
1428 rv
= eTLDService
->GetBaseDomain(uri
, 0, eTLDplusOne
);
1429 if (NS_SUCCEEDED(rv
)) {
1430 baseDomain
= eTLDplusOne
;
1431 } else if (rv
== NS_ERROR_HOST_IS_IP_ADDRESS
||
1432 rv
== NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
) {
1435 NS_ENSURE_SUCCESS(rv
, rv
);
1438 OriginAttributesRef().CreateSuffix(aKey
);
1440 nsAutoCString subdomainsDBKey
;
1441 rv
= dom::StorageUtils::CreateReversedDomain(baseDomain
, subdomainsDBKey
);
1442 NS_ENSURE_SUCCESS(rv
, rv
);
1445 aKey
.Append(subdomainsDBKey
);
1451 BasePrincipal::GetNextSubDomainPrincipal(
1452 nsIPrincipal
** aNextSubDomainPrincipal
) {
1453 nsCOMPtr
<nsIURI
> uri
;
1454 nsresult rv
= GetURI(getter_AddRefs(uri
));
1455 if (NS_FAILED(rv
) || !uri
) {
1460 rv
= uri
->GetHost(host
);
1461 if (NS_FAILED(rv
) || host
.IsEmpty()) {
1465 nsCString subDomain
;
1466 rv
= nsEffectiveTLDService::GetInstance()->GetNextSubDomain(host
, subDomain
);
1468 if (NS_FAILED(rv
) || subDomain
.IsEmpty()) {
1472 nsCOMPtr
<nsIURI
> subDomainURI
;
1473 rv
= NS_MutateURI(uri
).SetHost(subDomain
).Finalize(subDomainURI
);
1474 if (NS_FAILED(rv
) || !subDomainURI
) {
1477 // Copy the attributes over
1478 mozilla::OriginAttributes attrs
= OriginAttributesRef();
1480 if (!StaticPrefs::permissions_isolateBy_userContext()) {
1481 // Disable userContext for permissions.
1482 attrs
.StripAttributes(mozilla::OriginAttributes::STRIP_USER_CONTEXT_ID
);
1484 RefPtr
<nsIPrincipal
> principal
=
1485 mozilla::BasePrincipal::CreateContentPrincipal(subDomainURI
, attrs
);
1490 principal
.forget(aNextSubDomainPrincipal
);
1495 BasePrincipal::GetStorageOriginKey(nsACString
& aOriginKey
) {
1496 aOriginKey
.Truncate();
1498 nsCOMPtr
<nsIURI
> uri
;
1499 nsresult rv
= GetURI(getter_AddRefs(uri
));
1500 NS_ENSURE_SUCCESS(rv
, rv
);
1501 NS_ENSURE_TRUE(uri
, NS_ERROR_UNEXPECTED
);
1503 // The special handling of the file scheme should be consistent with
1504 // GetLocalStorageQuotaKey.
1506 nsAutoCString domainOrigin
;
1507 rv
= uri
->GetAsciiHost(domainOrigin
);
1508 NS_ENSURE_SUCCESS(rv
, rv
);
1510 if (domainOrigin
.IsEmpty()) {
1511 // For the file:/// protocol use the exact directory as domain.
1512 if (uri
->SchemeIs("file")) {
1513 nsCOMPtr
<nsIURL
> url
= do_QueryInterface(uri
, &rv
);
1514 NS_ENSURE_SUCCESS(rv
, rv
);
1515 rv
= url
->GetDirectory(domainOrigin
);
1516 NS_ENSURE_SUCCESS(rv
, rv
);
1520 // Append reversed domain
1521 nsAutoCString reverseDomain
;
1522 rv
= dom::StorageUtils::CreateReversedDomain(domainOrigin
, reverseDomain
);
1523 NS_ENSURE_SUCCESS(rv
, rv
);
1525 aOriginKey
.Append(reverseDomain
);
1528 nsAutoCString scheme
;
1529 rv
= uri
->GetScheme(scheme
);
1530 NS_ENSURE_SUCCESS(rv
, rv
);
1532 aOriginKey
.Append(':');
1533 aOriginKey
.Append(scheme
);
1535 // Append port if any
1536 int32_t port
= NS_GetRealPort(uri
);
1538 aOriginKey
.Append(nsPrintfCString(":%d", port
));
1545 BasePrincipal::GetIsScriptAllowedByPolicy(bool* aIsScriptAllowedByPolicy
) {
1546 AssertIsOnMainThread();
1547 *aIsScriptAllowedByPolicy
= false;
1548 nsCOMPtr
<nsIURI
> prinURI
;
1549 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1550 if (NS_FAILED(rv
) || !prinURI
) {
1553 nsIScriptSecurityManager
* ssm
= nsContentUtils::GetSecurityManager();
1555 return NS_ERROR_UNEXPECTED
;
1557 return ssm
->PolicyAllowsScript(prinURI
, aIsScriptAllowedByPolicy
);
1560 bool SiteIdentifier::Equals(const SiteIdentifier
& aOther
) const {
1561 MOZ_ASSERT(IsInitialized());
1562 MOZ_ASSERT(aOther
.IsInitialized());
1563 return mPrincipal
->FastEquals(aOther
.mPrincipal
);
1567 BasePrincipal::CreateReferrerInfo(mozilla::dom::ReferrerPolicy aReferrerPolicy
,
1568 nsIReferrerInfo
** _retval
) {
1569 nsCOMPtr
<nsIURI
> prinURI
;
1570 RefPtr
<dom::ReferrerInfo
> info
;
1571 nsresult rv
= GetURI(getter_AddRefs(prinURI
));
1572 if (NS_FAILED(rv
) || !prinURI
) {
1573 info
= new dom::ReferrerInfo(nullptr);
1574 info
.forget(_retval
);
1577 info
= new dom::ReferrerInfo(prinURI
, aReferrerPolicy
);
1578 info
.forget(_retval
);
1583 BasePrincipal::GetPrecursorPrincipal(nsIPrincipal
** aPrecursor
) {
1584 *aPrecursor
= nullptr;
1588 NS_IMPL_ADDREF(BasePrincipal::Deserializer
)
1589 NS_IMPL_RELEASE(BasePrincipal::Deserializer
)
1591 NS_INTERFACE_MAP_BEGIN(BasePrincipal::Deserializer
)
1592 NS_INTERFACE_MAP_ENTRY(nsISupports
)
1593 NS_INTERFACE_MAP_ENTRY(nsISerializable
)
1595 return mPrincipal
->QueryInterface(aIID
, aInstancePtr
);
1597 NS_INTERFACE_MAP_END
1600 BasePrincipal::Deserializer::Write(nsIObjectOutputStream
* aStream
) {
1601 // Read is used still for legacy principals
1602 MOZ_RELEASE_ASSERT(false, "Old style serialization is removed");
1607 void BasePrincipal::WriteJSONProperty(JSONWriter
& aWriter
,
1608 const Span
<const char>& aKey
,
1609 const nsCString
& aValue
) {
1610 aWriter
.StringProperty(aKey
, aValue
);
1613 } // namespace mozilla