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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "BackgroundUtils.h"
9 #include "MainThreadUtils.h"
10 #include "mozilla/Assertions.h"
11 #include "mozilla/BasePrincipal.h"
12 #include "mozilla/ContentPrincipal.h"
13 #include "mozilla/NullPrincipal.h"
14 #include "mozilla/ipc/PBackgroundSharedTypes.h"
15 #include "mozilla/ipc/URIUtils.h"
16 #include "mozilla/net/CookieJarSettings.h"
17 #include "mozilla/net/NeckoChannelParams.h"
18 #include "ExpandedPrincipal.h"
19 #include "nsIScriptSecurityManager.h"
21 #include "nsNetUtil.h"
22 #include "mozilla/LoadInfo.h"
23 #include "nsContentUtils.h"
26 #include "mozilla/nsRedirectHistoryEntry.h"
27 #include "mozilla/dom/nsCSPUtils.h"
28 #include "mozilla/dom/nsCSPContext.h"
29 #include "mozilla/dom/BrowsingContext.h"
30 #include "mozilla/dom/CanonicalBrowsingContext.h"
31 #include "mozilla/dom/Document.h"
32 #include "mozilla/dom/WindowGlobalParent.h"
33 #include "mozilla/LoadInfo.h"
35 using namespace mozilla::dom
;
36 using namespace mozilla::net
;
42 Result
<nsCOMPtr
<nsIPrincipal
>, nsresult
> PrincipalInfoToPrincipal(
43 const PrincipalInfo
& aPrincipalInfo
) {
44 MOZ_ASSERT(NS_IsMainThread());
45 MOZ_ASSERT(aPrincipalInfo
.type() != PrincipalInfo::T__None
);
47 nsCOMPtr
<nsIScriptSecurityManager
> secMan
=
48 nsContentUtils::GetSecurityManager();
50 return Err(NS_ERROR_NULL_POINTER
);
53 nsCOMPtr
<nsIPrincipal
> principal
;
56 switch (aPrincipalInfo
.type()) {
57 case PrincipalInfo::TSystemPrincipalInfo
: {
58 rv
= secMan
->GetSystemPrincipal(getter_AddRefs(principal
));
59 if (NS_WARN_IF(NS_FAILED(rv
))) {
66 case PrincipalInfo::TNullPrincipalInfo
: {
67 const NullPrincipalInfo
& info
= aPrincipalInfo
.get_NullPrincipalInfo();
70 rv
= NS_NewURI(getter_AddRefs(uri
), info
.spec());
71 if (NS_WARN_IF(NS_FAILED(rv
))) {
75 if (!uri
->SchemeIs(NS_NULLPRINCIPAL_SCHEME
)) {
76 return Err(NS_ERROR_ILLEGAL_VALUE
);
79 principal
= NullPrincipal::Create(info
.attrs(), uri
);
83 case PrincipalInfo::TContentPrincipalInfo
: {
84 const ContentPrincipalInfo
& info
=
85 aPrincipalInfo
.get_ContentPrincipalInfo();
88 rv
= NS_NewURI(getter_AddRefs(uri
), info
.spec());
89 if (NS_WARN_IF(NS_FAILED(rv
))) {
93 principal
= BasePrincipal::CreateContentPrincipal(uri
, info
.attrs());
94 if (NS_WARN_IF(!principal
)) {
95 return Err(NS_ERROR_NULL_POINTER
);
98 // Origin must match what the_new_principal.getOrigin returns.
99 nsAutoCString originNoSuffix
;
100 rv
= principal
->GetOriginNoSuffix(originNoSuffix
);
101 if (NS_WARN_IF(NS_FAILED(rv
))) {
105 if (NS_WARN_IF(!info
.originNoSuffix().Equals(originNoSuffix
))) {
106 return Err(NS_ERROR_FAILURE
);
110 nsCOMPtr
<nsIURI
> domain
;
111 rv
= NS_NewURI(getter_AddRefs(domain
), *info
.domain());
112 if (NS_WARN_IF(NS_FAILED(rv
))) {
116 rv
= principal
->SetDomain(domain
);
117 if (NS_WARN_IF(NS_FAILED(rv
))) {
122 if (!info
.baseDomain().IsVoid()) {
123 nsAutoCString baseDomain
;
124 rv
= principal
->GetBaseDomain(baseDomain
);
125 if (NS_WARN_IF(NS_FAILED(rv
))) {
129 if (NS_WARN_IF(!info
.baseDomain().Equals(baseDomain
))) {
130 return Err(NS_ERROR_FAILURE
);
136 case PrincipalInfo::TExpandedPrincipalInfo
: {
137 const ExpandedPrincipalInfo
& info
=
138 aPrincipalInfo
.get_ExpandedPrincipalInfo();
140 nsTArray
<nsCOMPtr
<nsIPrincipal
>> allowlist
;
141 nsCOMPtr
<nsIPrincipal
> alPrincipal
;
143 for (uint32_t i
= 0; i
< info
.allowlist().Length(); i
++) {
144 auto principalOrErr
= PrincipalInfoToPrincipal(info
.allowlist()[i
]);
145 if (NS_WARN_IF(principalOrErr
.isErr())) {
146 nsresult ret
= principalOrErr
.unwrapErr();
149 // append that principal to the allowlist
150 allowlist
.AppendElement(principalOrErr
.unwrap());
153 RefPtr
<ExpandedPrincipal
> expandedPrincipal
=
154 ExpandedPrincipal::Create(allowlist
, info
.attrs());
155 if (!expandedPrincipal
) {
156 return Err(NS_ERROR_FAILURE
);
159 principal
= expandedPrincipal
;
164 return Err(NS_ERROR_FAILURE
);
168 already_AddRefed
<nsIContentSecurityPolicy
> CSPInfoToCSP(
169 const CSPInfo
& aCSPInfo
, Document
* aRequestingDoc
,
170 nsresult
* aOptionalResult
) {
171 MOZ_ASSERT(NS_IsMainThread());
173 nsresult stackResult
;
174 nsresult
& rv
= aOptionalResult
? *aOptionalResult
: stackResult
;
176 RefPtr
<nsCSPContext
> csp
= new nsCSPContext();
178 if (aRequestingDoc
) {
179 rv
= csp
->SetRequestContextWithDocument(aRequestingDoc
);
180 if (NS_WARN_IF(NS_FAILED(rv
))) {
184 auto principalOrErr
=
185 PrincipalInfoToPrincipal(aCSPInfo
.requestPrincipalInfo());
186 if (NS_WARN_IF(principalOrErr
.isErr())) {
190 nsCOMPtr
<nsIURI
> selfURI
;
191 if (!aCSPInfo
.selfURISpec().IsEmpty()) {
192 rv
= NS_NewURI(getter_AddRefs(selfURI
), aCSPInfo
.selfURISpec());
193 if (NS_WARN_IF(NS_FAILED(rv
))) {
198 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
200 rv
= csp
->SetRequestContextWithPrincipal(
201 principal
, selfURI
, aCSPInfo
.referrer(), aCSPInfo
.innerWindowID());
202 if (NS_WARN_IF(NS_FAILED(rv
))) {
206 csp
->SetSkipAllowInlineStyleCheck(aCSPInfo
.skipAllowInlineStyleCheck());
208 for (uint32_t i
= 0; i
< aCSPInfo
.policyInfos().Length(); i
++) {
209 csp
->AddIPCPolicy(aCSPInfo
.policyInfos()[i
]);
214 nsresult
CSPToCSPInfo(nsIContentSecurityPolicy
* aCSP
, CSPInfo
* aCSPInfo
) {
215 MOZ_ASSERT(NS_IsMainThread());
217 MOZ_ASSERT(aCSPInfo
);
219 if (!aCSP
|| !aCSPInfo
) {
220 return NS_ERROR_FAILURE
;
223 nsCOMPtr
<nsIPrincipal
> requestPrincipal
= aCSP
->GetRequestPrincipal();
225 PrincipalInfo requestingPrincipalInfo
;
227 PrincipalToPrincipalInfo(requestPrincipal
, &requestingPrincipalInfo
);
228 if (NS_WARN_IF(NS_FAILED(rv
))) {
232 nsCOMPtr
<nsIURI
> selfURI
= aCSP
->GetSelfURI();
233 nsAutoCString selfURISpec
;
235 selfURI
->GetSpec(selfURISpec
);
238 nsAutoString referrer
;
239 aCSP
->GetReferrer(referrer
);
241 uint64_t windowID
= aCSP
->GetInnerWindowID();
242 bool skipAllowInlineStyleCheck
= aCSP
->GetSkipAllowInlineStyleCheck();
244 nsTArray
<ContentSecurityPolicy
> policies
;
245 static_cast<nsCSPContext
*>(aCSP
)->SerializePolicies(policies
);
247 *aCSPInfo
= CSPInfo(std::move(policies
), requestingPrincipalInfo
, selfURISpec
,
248 referrer
, windowID
, skipAllowInlineStyleCheck
);
252 nsresult
PrincipalToPrincipalInfo(nsIPrincipal
* aPrincipal
,
253 PrincipalInfo
* aPrincipalInfo
,
254 bool aSkipBaseDomain
) {
255 MOZ_ASSERT(NS_IsMainThread());
256 MOZ_ASSERT(aPrincipal
);
257 MOZ_ASSERT(aPrincipalInfo
);
260 if (aPrincipal
->GetIsNullPrincipal()) {
262 rv
= aPrincipal
->GetAsciiSpec(spec
);
263 if (NS_WARN_IF(NS_FAILED(rv
))) {
268 NullPrincipalInfo(aPrincipal
->OriginAttributesRef(), spec
);
272 if (aPrincipal
->IsSystemPrincipal()) {
273 *aPrincipalInfo
= SystemPrincipalInfo();
277 // might be an expanded principal
278 auto* basePrin
= BasePrincipal::Cast(aPrincipal
);
279 if (basePrin
->Is
<ExpandedPrincipal
>()) {
280 auto* expanded
= basePrin
->As
<ExpandedPrincipal
>();
282 nsTArray
<PrincipalInfo
> allowlistInfo
;
285 for (auto& prin
: expanded
->AllowList()) {
286 rv
= PrincipalToPrincipalInfo(prin
, &info
, aSkipBaseDomain
);
287 if (NS_WARN_IF(NS_FAILED(rv
))) {
290 // append that spec to the allowlist
291 allowlistInfo
.AppendElement(info
);
294 *aPrincipalInfo
= ExpandedPrincipalInfo(aPrincipal
->OriginAttributesRef(),
295 std::move(allowlistInfo
));
300 rv
= aPrincipal
->GetAsciiSpec(spec
);
301 if (NS_WARN_IF(NS_FAILED(rv
))) {
305 nsCString originNoSuffix
;
306 rv
= aPrincipal
->GetOriginNoSuffix(originNoSuffix
);
307 if (NS_WARN_IF(NS_FAILED(rv
))) {
311 nsCOMPtr
<nsIURI
> domainUri
;
312 rv
= aPrincipal
->GetDomain(getter_AddRefs(domainUri
));
313 if (NS_WARN_IF(NS_FAILED(rv
))) {
317 Maybe
<nsCString
> domain
;
320 rv
= domainUri
->GetSpec(domain
.ref());
321 if (NS_WARN_IF(NS_FAILED(rv
))) {
326 // This attribute is not crucial.
327 nsCString baseDomain
;
328 if (aSkipBaseDomain
) {
329 baseDomain
.SetIsVoid(true);
331 if (NS_FAILED(aPrincipal
->GetBaseDomain(baseDomain
))) {
332 // No warning here. Some principal URLs do not have a base-domain.
333 baseDomain
.SetIsVoid(true);
338 ContentPrincipalInfo(aPrincipal
->OriginAttributesRef(), originNoSuffix
,
339 spec
, domain
, baseDomain
);
343 bool IsPrincipalInfoPrivate(const PrincipalInfo
& aPrincipalInfo
) {
344 if (aPrincipalInfo
.type() != ipc::PrincipalInfo::TContentPrincipalInfo
) {
348 const ContentPrincipalInfo
& info
= aPrincipalInfo
.get_ContentPrincipalInfo();
349 return !!info
.attrs().mPrivateBrowsingId
;
352 already_AddRefed
<nsIRedirectHistoryEntry
> RHEntryInfoToRHEntry(
353 const RedirectHistoryEntryInfo
& aRHEntryInfo
) {
354 auto principalOrErr
= PrincipalInfoToPrincipal(aRHEntryInfo
.principalInfo());
355 if (NS_WARN_IF(principalOrErr
.isErr())) {
359 nsCOMPtr
<nsIPrincipal
> principal
= principalOrErr
.unwrap();
360 nsCOMPtr
<nsIURI
> referrerUri
= DeserializeURI(aRHEntryInfo
.referrerUri());
362 nsCOMPtr
<nsIRedirectHistoryEntry
> entry
= new nsRedirectHistoryEntry(
363 principal
, referrerUri
, aRHEntryInfo
.remoteAddress());
365 return entry
.forget();
368 nsresult
RHEntryToRHEntryInfo(nsIRedirectHistoryEntry
* aRHEntry
,
369 RedirectHistoryEntryInfo
* aRHEntryInfo
) {
370 MOZ_ASSERT(aRHEntry
);
371 MOZ_ASSERT(aRHEntryInfo
);
374 aRHEntry
->GetRemoteAddress(aRHEntryInfo
->remoteAddress());
376 nsCOMPtr
<nsIURI
> referrerUri
;
377 rv
= aRHEntry
->GetReferrerURI(getter_AddRefs(referrerUri
));
378 NS_ENSURE_SUCCESS(rv
, rv
);
379 SerializeURI(referrerUri
, aRHEntryInfo
->referrerUri());
381 nsCOMPtr
<nsIPrincipal
> principal
;
382 rv
= aRHEntry
->GetPrincipal(getter_AddRefs(principal
));
383 NS_ENSURE_SUCCESS(rv
, rv
);
385 return PrincipalToPrincipalInfo(principal
, &aRHEntryInfo
->principalInfo());
388 nsresult
LoadInfoToLoadInfoArgs(nsILoadInfo
* aLoadInfo
,
389 Maybe
<LoadInfoArgs
>* aOptionalLoadInfoArgs
) {
391 Maybe
<PrincipalInfo
> loadingPrincipalInfo
;
392 if (nsIPrincipal
* loadingPrin
= aLoadInfo
->GetLoadingPrincipal()) {
393 loadingPrincipalInfo
.emplace();
394 rv
= PrincipalToPrincipalInfo(loadingPrin
, loadingPrincipalInfo
.ptr());
395 NS_ENSURE_SUCCESS(rv
, rv
);
398 PrincipalInfo triggeringPrincipalInfo
;
399 rv
= PrincipalToPrincipalInfo(aLoadInfo
->TriggeringPrincipal(),
400 &triggeringPrincipalInfo
);
401 NS_ENSURE_SUCCESS(rv
, rv
);
403 Maybe
<PrincipalInfo
> principalToInheritInfo
;
404 if (nsIPrincipal
* principalToInherit
= aLoadInfo
->PrincipalToInherit()) {
405 principalToInheritInfo
.emplace();
406 rv
= PrincipalToPrincipalInfo(principalToInherit
,
407 principalToInheritInfo
.ptr());
408 NS_ENSURE_SUCCESS(rv
, rv
);
411 Maybe
<PrincipalInfo
> topLevelPrincipalInfo
;
412 if (nsIPrincipal
* topLevenPrin
= aLoadInfo
->GetTopLevelPrincipal()) {
413 topLevelPrincipalInfo
.emplace();
414 rv
= PrincipalToPrincipalInfo(topLevenPrin
, topLevelPrincipalInfo
.ptr());
415 NS_ENSURE_SUCCESS(rv
, rv
);
418 Maybe
<URIParams
> optionalResultPrincipalURI
;
419 nsCOMPtr
<nsIURI
> resultPrincipalURI
;
420 Unused
<< aLoadInfo
->GetResultPrincipalURI(
421 getter_AddRefs(resultPrincipalURI
));
422 if (resultPrincipalURI
) {
423 SerializeURI(resultPrincipalURI
, optionalResultPrincipalURI
);
426 nsTArray
<RedirectHistoryEntryInfo
> redirectChainIncludingInternalRedirects
;
427 for (const nsCOMPtr
<nsIRedirectHistoryEntry
>& redirectEntry
:
428 aLoadInfo
->RedirectChainIncludingInternalRedirects()) {
429 RedirectHistoryEntryInfo
* entry
=
430 redirectChainIncludingInternalRedirects
.AppendElement();
431 rv
= RHEntryToRHEntryInfo(redirectEntry
, entry
);
432 NS_ENSURE_SUCCESS(rv
, rv
);
435 nsTArray
<RedirectHistoryEntryInfo
> redirectChain
;
436 for (const nsCOMPtr
<nsIRedirectHistoryEntry
>& redirectEntry
:
437 aLoadInfo
->RedirectChain()) {
438 RedirectHistoryEntryInfo
* entry
= redirectChain
.AppendElement();
439 rv
= RHEntryToRHEntryInfo(redirectEntry
, entry
);
440 NS_ENSURE_SUCCESS(rv
, rv
);
443 Maybe
<IPCClientInfo
> ipcClientInfo
;
444 const Maybe
<ClientInfo
>& clientInfo
= aLoadInfo
->GetClientInfo();
445 if (clientInfo
.isSome()) {
446 ipcClientInfo
.emplace(clientInfo
.ref().ToIPC());
449 Maybe
<IPCClientInfo
> ipcReservedClientInfo
;
450 const Maybe
<ClientInfo
>& reservedClientInfo
=
451 aLoadInfo
->GetReservedClientInfo();
452 if (reservedClientInfo
.isSome()) {
453 ipcReservedClientInfo
.emplace(reservedClientInfo
.ref().ToIPC());
456 Maybe
<IPCClientInfo
> ipcInitialClientInfo
;
457 const Maybe
<ClientInfo
>& initialClientInfo
=
458 aLoadInfo
->GetInitialClientInfo();
459 if (initialClientInfo
.isSome()) {
460 ipcInitialClientInfo
.emplace(initialClientInfo
.ref().ToIPC());
463 Maybe
<IPCServiceWorkerDescriptor
> ipcController
;
464 const Maybe
<ServiceWorkerDescriptor
>& controller
= aLoadInfo
->GetController();
465 if (controller
.isSome()) {
466 ipcController
.emplace(controller
.ref().ToIPC());
469 nsAutoString cspNonce
;
470 Unused
<< NS_WARN_IF(NS_FAILED(aLoadInfo
->GetCspNonce(cspNonce
)));
472 nsCOMPtr
<nsICookieJarSettings
> cookieJarSettings
;
473 rv
= aLoadInfo
->GetCookieJarSettings(getter_AddRefs(cookieJarSettings
));
474 NS_ENSURE_SUCCESS(rv
, rv
);
476 CookieJarSettingsArgs cookieJarSettingsArgs
;
477 static_cast<CookieJarSettings
*>(cookieJarSettings
.get())
478 ->Serialize(cookieJarSettingsArgs
);
480 Maybe
<CSPInfo
> maybeCspToInheritInfo
;
481 nsCOMPtr
<nsIContentSecurityPolicy
> cspToInherit
=
482 aLoadInfo
->GetCspToInherit();
484 CSPInfo cspToInheritInfo
;
485 Unused
<< NS_WARN_IF(
486 NS_FAILED(CSPToCSPInfo(cspToInherit
, &cspToInheritInfo
)));
487 maybeCspToInheritInfo
.emplace(cspToInheritInfo
);
490 nsCOMPtr
<nsIURI
> unstrippedURI
;
491 Unused
<< aLoadInfo
->GetUnstrippedURI(getter_AddRefs(unstrippedURI
));
493 *aOptionalLoadInfoArgs
= Some(LoadInfoArgs(
494 loadingPrincipalInfo
, triggeringPrincipalInfo
, principalToInheritInfo
,
495 topLevelPrincipalInfo
, optionalResultPrincipalURI
,
496 aLoadInfo
->GetSandboxedNullPrincipalID(), aLoadInfo
->GetSecurityFlags(),
497 aLoadInfo
->GetSandboxFlags(), aLoadInfo
->GetTriggeringSandboxFlags(),
498 aLoadInfo
->InternalContentPolicyType(),
499 static_cast<uint32_t>(aLoadInfo
->GetTainting()),
500 aLoadInfo
->GetBlockAllMixedContent(),
501 aLoadInfo
->GetUpgradeInsecureRequests(),
502 aLoadInfo
->GetBrowserUpgradeInsecureRequests(),
503 aLoadInfo
->GetBrowserDidUpgradeInsecureRequests(),
504 aLoadInfo
->GetBrowserWouldUpgradeInsecureRequests(),
505 aLoadInfo
->GetForceAllowDataURI(),
506 aLoadInfo
->GetAllowInsecureRedirectToDataURI(),
507 aLoadInfo
->GetSkipContentPolicyCheckForWebRequest(),
508 aLoadInfo
->GetOriginalFrameSrcLoad(),
509 aLoadInfo
->GetForceInheritPrincipalDropped(),
510 aLoadInfo
->GetInnerWindowID(), aLoadInfo
->GetBrowsingContextID(),
511 aLoadInfo
->GetFrameBrowsingContextID(),
512 aLoadInfo
->GetInitialSecurityCheckDone(),
513 aLoadInfo
->GetIsInThirdPartyContext(),
514 aLoadInfo
->GetIsThirdPartyContextToTopWindow(),
515 aLoadInfo
->GetIsFormSubmission(), aLoadInfo
->GetSendCSPViolationEvents(),
516 aLoadInfo
->GetOriginAttributes(), redirectChainIncludingInternalRedirects
,
517 redirectChain
, ipcClientInfo
, ipcReservedClientInfo
, ipcInitialClientInfo
,
518 ipcController
, aLoadInfo
->CorsUnsafeHeaders(),
519 aLoadInfo
->GetForcePreflight(), aLoadInfo
->GetIsPreflight(),
520 aLoadInfo
->GetLoadTriggeredFromExternal(),
521 aLoadInfo
->GetServiceWorkerTaintingSynthesized(),
522 aLoadInfo
->GetDocumentHasUserInteracted(),
523 aLoadInfo
->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
524 aLoadInfo
->GetNeedForCheckingAntiTrackingHeuristic(), cspNonce
,
525 aLoadInfo
->GetSkipContentSniffing(), aLoadInfo
->GetHttpsOnlyStatus(),
526 aLoadInfo
->GetHasValidUserGestureActivation(),
527 aLoadInfo
->GetAllowDeprecatedSystemRequests(),
528 aLoadInfo
->GetIsInDevToolsContext(), aLoadInfo
->GetParserCreatedScript(),
529 aLoadInfo
->GetIsFromProcessingFrameAttributes(),
530 aLoadInfo
->GetIsMediaRequest(), aLoadInfo
->GetIsMediaInitialRequest(),
531 aLoadInfo
->GetIsFromObjectOrEmbed(), cookieJarSettingsArgs
,
532 aLoadInfo
->GetRequestBlockingReason(), maybeCspToInheritInfo
,
533 aLoadInfo
->GetStoragePermission(), aLoadInfo
->GetIsMetaRefresh(),
534 aLoadInfo
->GetLoadingEmbedderPolicy(), unstrippedURI
));
539 nsresult
LoadInfoArgsToLoadInfo(
540 const Maybe
<LoadInfoArgs
>& aOptionalLoadInfoArgs
,
541 nsILoadInfo
** outLoadInfo
) {
542 return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs
, nullptr, outLoadInfo
);
544 nsresult
LoadInfoArgsToLoadInfo(
545 const Maybe
<LoadInfoArgs
>& aOptionalLoadInfoArgs
,
546 nsINode
* aCspToInheritLoadingContext
, nsILoadInfo
** outLoadInfo
) {
547 RefPtr
<LoadInfo
> loadInfo
;
549 LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs
, aCspToInheritLoadingContext
,
550 getter_AddRefs(loadInfo
));
551 NS_ENSURE_SUCCESS(rv
, rv
);
553 loadInfo
.forget(outLoadInfo
);
557 nsresult
LoadInfoArgsToLoadInfo(
558 const Maybe
<LoadInfoArgs
>& aOptionalLoadInfoArgs
, LoadInfo
** outLoadInfo
) {
559 return LoadInfoArgsToLoadInfo(aOptionalLoadInfoArgs
, nullptr, outLoadInfo
);
561 nsresult
LoadInfoArgsToLoadInfo(
562 const Maybe
<LoadInfoArgs
>& aOptionalLoadInfoArgs
,
563 nsINode
* aCspToInheritLoadingContext
, LoadInfo
** outLoadInfo
) {
564 if (aOptionalLoadInfoArgs
.isNothing()) {
565 *outLoadInfo
= nullptr;
569 const LoadInfoArgs
& loadInfoArgs
= aOptionalLoadInfoArgs
.ref();
571 nsCOMPtr
<nsIPrincipal
> loadingPrincipal
;
572 if (loadInfoArgs
.requestingPrincipalInfo().isSome()) {
573 auto loadingPrincipalOrErr
=
574 PrincipalInfoToPrincipal(loadInfoArgs
.requestingPrincipalInfo().ref());
575 if (NS_WARN_IF(loadingPrincipalOrErr
.isErr())) {
576 return loadingPrincipalOrErr
.unwrapErr();
578 loadingPrincipal
= loadingPrincipalOrErr
.unwrap();
581 auto triggeringPrincipalOrErr
=
582 PrincipalInfoToPrincipal(loadInfoArgs
.triggeringPrincipalInfo());
583 if (NS_WARN_IF(triggeringPrincipalOrErr
.isErr())) {
584 return triggeringPrincipalOrErr
.unwrapErr();
586 nsCOMPtr
<nsIPrincipal
> triggeringPrincipal
=
587 triggeringPrincipalOrErr
.unwrap();
589 nsCOMPtr
<nsIPrincipal
> principalToInherit
;
590 nsCOMPtr
<nsIPrincipal
> flattenedPrincipalToInherit
;
591 if (loadInfoArgs
.principalToInheritInfo().isSome()) {
592 auto principalToInheritOrErr
=
593 PrincipalInfoToPrincipal(loadInfoArgs
.principalToInheritInfo().ref());
594 if (NS_WARN_IF(principalToInheritOrErr
.isErr())) {
595 return principalToInheritOrErr
.unwrapErr();
597 flattenedPrincipalToInherit
= principalToInheritOrErr
.unwrap();
600 if (XRE_IsContentProcess()) {
601 auto targetBrowsingContextId
= loadInfoArgs
.frameBrowsingContextID()
602 ? loadInfoArgs
.frameBrowsingContextID()
603 : loadInfoArgs
.browsingContextID();
604 if (RefPtr
<BrowsingContext
> bc
=
605 BrowsingContext::Get(targetBrowsingContextId
)) {
606 nsCOMPtr
<nsIPrincipal
> originalTriggeringPrincipal
;
607 nsCOMPtr
<nsIPrincipal
> originalPrincipalToInherit
;
608 Tie(originalTriggeringPrincipal
, originalPrincipalToInherit
) =
609 bc
->GetTriggeringAndInheritPrincipalsForCurrentLoad();
611 if (originalTriggeringPrincipal
&&
612 originalTriggeringPrincipal
->Equals(triggeringPrincipal
)) {
613 triggeringPrincipal
= originalTriggeringPrincipal
;
615 if (originalPrincipalToInherit
&&
616 (loadInfoArgs
.securityFlags() &
617 nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL
) &&
618 originalPrincipalToInherit
->Equals(flattenedPrincipalToInherit
)) {
619 principalToInherit
= originalPrincipalToInherit
;
623 if (!principalToInherit
&& loadInfoArgs
.principalToInheritInfo().isSome()) {
624 principalToInherit
= flattenedPrincipalToInherit
;
628 nsCOMPtr
<nsIPrincipal
> topLevelPrincipal
;
629 if (loadInfoArgs
.topLevelPrincipalInfo().isSome()) {
630 auto topLevelPrincipalOrErr
=
631 PrincipalInfoToPrincipal(loadInfoArgs
.topLevelPrincipalInfo().ref());
632 if (NS_WARN_IF(topLevelPrincipalOrErr
.isErr())) {
633 return topLevelPrincipalOrErr
.unwrapErr();
635 topLevelPrincipal
= topLevelPrincipalOrErr
.unwrap();
638 nsCOMPtr
<nsIURI
> resultPrincipalURI
;
639 if (loadInfoArgs
.resultPrincipalURI().isSome()) {
640 resultPrincipalURI
= DeserializeURI(loadInfoArgs
.resultPrincipalURI());
641 NS_ENSURE_TRUE(resultPrincipalURI
, NS_ERROR_UNEXPECTED
);
644 RedirectHistoryArray redirectChainIncludingInternalRedirects
;
645 for (const RedirectHistoryEntryInfo
& entryInfo
:
646 loadInfoArgs
.redirectChainIncludingInternalRedirects()) {
647 nsCOMPtr
<nsIRedirectHistoryEntry
> redirectHistoryEntry
=
648 RHEntryInfoToRHEntry(entryInfo
);
649 NS_ENSURE_SUCCESS(rv
, rv
);
650 redirectChainIncludingInternalRedirects
.AppendElement(
651 redirectHistoryEntry
.forget());
654 RedirectHistoryArray redirectChain
;
655 for (const RedirectHistoryEntryInfo
& entryInfo
:
656 loadInfoArgs
.redirectChain()) {
657 nsCOMPtr
<nsIRedirectHistoryEntry
> redirectHistoryEntry
=
658 RHEntryInfoToRHEntry(entryInfo
);
659 NS_ENSURE_SUCCESS(rv
, rv
);
660 redirectChain
.AppendElement(redirectHistoryEntry
.forget());
663 nsTArray
<nsCOMPtr
<nsIPrincipal
>> ancestorPrincipals
;
664 nsTArray
<uint64_t> ancestorBrowsingContextIDs
;
665 if (XRE_IsParentProcess() &&
666 (nsContentUtils::InternalContentPolicyTypeToExternal(
667 loadInfoArgs
.contentPolicyType()) !=
668 ExtContentPolicy::TYPE_DOCUMENT
)) {
669 // Only fill out ancestor principals and browsing context IDs when we
670 // are deserializing LoadInfoArgs to be LoadInfo for a subresource
671 RefPtr
<BrowsingContext
> parentBC
=
672 BrowsingContext::Get(loadInfoArgs
.browsingContextID());
674 LoadInfo::ComputeAncestors(parentBC
->Canonical(), ancestorPrincipals
,
675 ancestorBrowsingContextIDs
);
679 Maybe
<ClientInfo
> clientInfo
;
680 if (loadInfoArgs
.clientInfo().isSome()) {
681 clientInfo
.emplace(ClientInfo(loadInfoArgs
.clientInfo().ref()));
684 Maybe
<ClientInfo
> reservedClientInfo
;
685 if (loadInfoArgs
.reservedClientInfo().isSome()) {
686 reservedClientInfo
.emplace(
687 ClientInfo(loadInfoArgs
.reservedClientInfo().ref()));
690 Maybe
<ClientInfo
> initialClientInfo
;
691 if (loadInfoArgs
.initialClientInfo().isSome()) {
692 initialClientInfo
.emplace(
693 ClientInfo(loadInfoArgs
.initialClientInfo().ref()));
696 // We can have an initial client info or a reserved client info, but not both.
697 MOZ_DIAGNOSTIC_ASSERT(reservedClientInfo
.isNothing() ||
698 initialClientInfo
.isNothing());
700 reservedClientInfo
.isNothing() || initialClientInfo
.isNothing(),
701 NS_ERROR_UNEXPECTED
);
703 Maybe
<ServiceWorkerDescriptor
> controller
;
704 if (loadInfoArgs
.controller().isSome()) {
706 ServiceWorkerDescriptor(loadInfoArgs
.controller().ref()));
709 nsCOMPtr
<nsICookieJarSettings
> cookieJarSettings
;
710 CookieJarSettings::Deserialize(loadInfoArgs
.cookieJarSettings(),
711 getter_AddRefs(cookieJarSettings
));
713 nsCOMPtr
<nsIContentSecurityPolicy
> cspToInherit
;
714 Maybe
<mozilla::ipc::CSPInfo
> cspToInheritInfo
=
715 loadInfoArgs
.cspToInheritInfo();
716 if (cspToInheritInfo
.isSome()) {
717 nsCOMPtr
<Document
> doc
= do_QueryInterface(aCspToInheritLoadingContext
);
718 cspToInherit
= CSPInfoToCSP(cspToInheritInfo
.ref(), doc
);
721 // Restore the loadingContext for frames using the BrowsingContext's
722 // embedder element. Note that this only works if the embedder is
723 // same-process, so won't be fission compatible.
724 nsCOMPtr
<nsINode
> loadingContext
;
725 RefPtr
<BrowsingContext
> frameBrowsingContext
=
726 BrowsingContext::Get(loadInfoArgs
.frameBrowsingContextID());
727 if (frameBrowsingContext
) {
728 loadingContext
= frameBrowsingContext
->GetEmbedderElement();
731 RefPtr
<mozilla::net::LoadInfo
> loadInfo
= new mozilla::net::LoadInfo(
732 loadingPrincipal
, triggeringPrincipal
, principalToInherit
,
733 topLevelPrincipal
, resultPrincipalURI
, cookieJarSettings
, cspToInherit
,
734 loadInfoArgs
.sandboxedNullPrincipalID(), clientInfo
, reservedClientInfo
,
735 initialClientInfo
, controller
, loadInfoArgs
.securityFlags(),
736 loadInfoArgs
.sandboxFlags(), loadInfoArgs
.triggeringSandboxFlags(),
737 loadInfoArgs
.contentPolicyType(),
738 static_cast<LoadTainting
>(loadInfoArgs
.tainting()),
739 loadInfoArgs
.blockAllMixedContent(),
740 loadInfoArgs
.upgradeInsecureRequests(),
741 loadInfoArgs
.browserUpgradeInsecureRequests(),
742 loadInfoArgs
.browserDidUpgradeInsecureRequests(),
743 loadInfoArgs
.browserWouldUpgradeInsecureRequests(),
744 loadInfoArgs
.forceAllowDataURI(),
745 loadInfoArgs
.allowInsecureRedirectToDataURI(),
746 loadInfoArgs
.skipContentPolicyCheckForWebRequest(),
747 loadInfoArgs
.originalFrameSrcLoad(),
748 loadInfoArgs
.forceInheritPrincipalDropped(), loadInfoArgs
.innerWindowID(),
749 loadInfoArgs
.browsingContextID(), loadInfoArgs
.frameBrowsingContextID(),
750 loadInfoArgs
.initialSecurityCheckDone(),
751 loadInfoArgs
.isInThirdPartyContext(),
752 loadInfoArgs
.isThirdPartyContextToTopWindow(),
753 loadInfoArgs
.isFormSubmission(), loadInfoArgs
.sendCSPViolationEvents(),
754 loadInfoArgs
.originAttributes(),
755 std::move(redirectChainIncludingInternalRedirects
),
756 std::move(redirectChain
), std::move(ancestorPrincipals
),
757 ancestorBrowsingContextIDs
, loadInfoArgs
.corsUnsafeHeaders(),
758 loadInfoArgs
.forcePreflight(), loadInfoArgs
.isPreflight(),
759 loadInfoArgs
.loadTriggeredFromExternal(),
760 loadInfoArgs
.serviceWorkerTaintingSynthesized(),
761 loadInfoArgs
.documentHasUserInteracted(),
762 loadInfoArgs
.allowListFutureDocumentsCreatedFromThisRedirectChain(),
763 loadInfoArgs
.needForCheckingAntiTrackingHeuristic(),
764 loadInfoArgs
.cspNonce(), loadInfoArgs
.skipContentSniffing(),
765 loadInfoArgs
.httpsOnlyStatus(),
766 loadInfoArgs
.hasValidUserGestureActivation(),
767 loadInfoArgs
.allowDeprecatedSystemRequests(),
768 loadInfoArgs
.isInDevToolsContext(), loadInfoArgs
.parserCreatedScript(),
769 loadInfoArgs
.storagePermission(), loadInfoArgs
.isMetaRefresh(),
770 loadInfoArgs
.requestBlockingReason(), loadingContext
,
771 loadInfoArgs
.loadingEmbedderPolicy(), loadInfoArgs
.unstrippedURI());
773 if (loadInfoArgs
.isFromProcessingFrameAttributes()) {
774 loadInfo
->SetIsFromProcessingFrameAttributes();
777 if (loadInfoArgs
.isMediaRequest()) {
778 loadInfo
->SetIsMediaRequest(true);
780 if (loadInfoArgs
.isMediaInitialRequest()) {
781 loadInfo
->SetIsMediaInitialRequest(true);
785 if (loadInfoArgs
.isFromObjectOrEmbed()) {
786 loadInfo
->SetIsFromObjectOrEmbed(true);
789 loadInfo
.forget(outLoadInfo
);
793 void LoadInfoToParentLoadInfoForwarder(
794 nsILoadInfo
* aLoadInfo
, ParentLoadInfoForwarderArgs
* aForwarderArgsOut
) {
795 Maybe
<IPCServiceWorkerDescriptor
> ipcController
;
796 Maybe
<ServiceWorkerDescriptor
> controller(aLoadInfo
->GetController());
797 if (controller
.isSome()) {
798 ipcController
.emplace(controller
.ref().ToIPC());
801 uint32_t tainting
= nsILoadInfo::TAINTING_BASIC
;
802 Unused
<< aLoadInfo
->GetTainting(&tainting
);
804 Maybe
<CookieJarSettingsArgs
> cookieJarSettingsArgs
;
806 nsCOMPtr
<nsICookieJarSettings
> cookieJarSettings
;
808 aLoadInfo
->GetCookieJarSettings(getter_AddRefs(cookieJarSettings
));
809 CookieJarSettings
* cs
=
810 static_cast<CookieJarSettings
*>(cookieJarSettings
.get());
811 if (NS_SUCCEEDED(rv
) && cookieJarSettings
&& cs
->HasBeenChanged()) {
812 CookieJarSettingsArgs args
;
814 cookieJarSettingsArgs
= Some(args
);
817 nsCOMPtr
<nsIURI
> unstrippedURI
;
818 Unused
<< aLoadInfo
->GetUnstrippedURI(getter_AddRefs(unstrippedURI
));
820 *aForwarderArgsOut
= ParentLoadInfoForwarderArgs(
821 aLoadInfo
->GetAllowInsecureRedirectToDataURI(), ipcController
, tainting
,
822 aLoadInfo
->GetSkipContentSniffing(), aLoadInfo
->GetHttpsOnlyStatus(),
823 aLoadInfo
->GetHasValidUserGestureActivation(),
824 aLoadInfo
->GetAllowDeprecatedSystemRequests(),
825 aLoadInfo
->GetIsInDevToolsContext(), aLoadInfo
->GetParserCreatedScript(),
826 aLoadInfo
->GetTriggeringSandboxFlags(),
827 aLoadInfo
->GetServiceWorkerTaintingSynthesized(),
828 aLoadInfo
->GetDocumentHasUserInteracted(),
829 aLoadInfo
->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
830 cookieJarSettingsArgs
, aLoadInfo
->GetRequestBlockingReason(),
831 aLoadInfo
->GetStoragePermission(), aLoadInfo
->GetIsMetaRefresh(),
832 aLoadInfo
->GetIsThirdPartyContextToTopWindow(),
833 aLoadInfo
->GetIsInThirdPartyContext(), unstrippedURI
);
836 nsresult
MergeParentLoadInfoForwarder(
837 ParentLoadInfoForwarderArgs
const& aForwarderArgs
, nsILoadInfo
* aLoadInfo
) {
840 rv
= aLoadInfo
->SetAllowInsecureRedirectToDataURI(
841 aForwarderArgs
.allowInsecureRedirectToDataURI());
842 NS_ENSURE_SUCCESS(rv
, rv
);
844 aLoadInfo
->ClearController();
845 auto& controller
= aForwarderArgs
.controller();
846 if (controller
.isSome()) {
847 aLoadInfo
->SetController(ServiceWorkerDescriptor(controller
.ref()));
850 if (aForwarderArgs
.serviceWorkerTaintingSynthesized()) {
851 aLoadInfo
->SynthesizeServiceWorkerTainting(
852 static_cast<LoadTainting
>(aForwarderArgs
.tainting()));
854 aLoadInfo
->MaybeIncreaseTainting(aForwarderArgs
.tainting());
857 rv
= aLoadInfo
->SetSkipContentSniffing(aForwarderArgs
.skipContentSniffing());
858 NS_ENSURE_SUCCESS(rv
, rv
);
860 rv
= aLoadInfo
->SetHttpsOnlyStatus(aForwarderArgs
.httpsOnlyStatus());
861 NS_ENSURE_SUCCESS(rv
, rv
);
863 rv
= aLoadInfo
->SetTriggeringSandboxFlags(
864 aForwarderArgs
.triggeringSandboxFlags());
865 NS_ENSURE_SUCCESS(rv
, rv
);
867 rv
= aLoadInfo
->SetHasValidUserGestureActivation(
868 aForwarderArgs
.hasValidUserGestureActivation());
869 NS_ENSURE_SUCCESS(rv
, rv
);
871 rv
= aLoadInfo
->SetAllowDeprecatedSystemRequests(
872 aForwarderArgs
.allowDeprecatedSystemRequests());
873 NS_ENSURE_SUCCESS(rv
, rv
);
875 rv
= aLoadInfo
->SetIsInDevToolsContext(aForwarderArgs
.isInDevToolsContext());
876 NS_ENSURE_SUCCESS(rv
, rv
);
878 rv
= aLoadInfo
->SetParserCreatedScript(aForwarderArgs
.parserCreatedScript());
879 NS_ENSURE_SUCCESS(rv
, rv
);
881 MOZ_ALWAYS_SUCCEEDS(aLoadInfo
->SetDocumentHasUserInteracted(
882 aForwarderArgs
.documentHasUserInteracted()));
884 aLoadInfo
->SetAllowListFutureDocumentsCreatedFromThisRedirectChain(
886 .allowListFutureDocumentsCreatedFromThisRedirectChain()));
887 MOZ_ALWAYS_SUCCEEDS(aLoadInfo
->SetRequestBlockingReason(
888 aForwarderArgs
.requestBlockingReason()));
890 const Maybe
<CookieJarSettingsArgs
>& cookieJarSettingsArgs
=
891 aForwarderArgs
.cookieJarSettings();
892 if (cookieJarSettingsArgs
.isSome()) {
893 nsCOMPtr
<nsICookieJarSettings
> cookieJarSettings
;
895 aLoadInfo
->GetCookieJarSettings(getter_AddRefs(cookieJarSettings
));
896 if (NS_SUCCEEDED(rv
) && cookieJarSettings
) {
897 static_cast<CookieJarSettings
*>(cookieJarSettings
.get())
898 ->Merge(cookieJarSettingsArgs
.ref());
902 rv
= aLoadInfo
->SetStoragePermission(aForwarderArgs
.storagePermission());
903 NS_ENSURE_SUCCESS(rv
, rv
);
905 rv
= aLoadInfo
->SetIsMetaRefresh(aForwarderArgs
.isMetaRefresh());
906 NS_ENSURE_SUCCESS(rv
, rv
);
908 rv
= aLoadInfo
->SetIsThirdPartyContextToTopWindow(
909 aForwarderArgs
.isThirdPartyContextToTopWindow());
910 NS_ENSURE_SUCCESS(rv
, rv
);
912 rv
= aLoadInfo
->SetIsInThirdPartyContext(
913 aForwarderArgs
.isInThirdPartyContext());
914 NS_ENSURE_SUCCESS(rv
, rv
);
916 rv
= aLoadInfo
->SetUnstrippedURI(aForwarderArgs
.unstrippedURI());
917 NS_ENSURE_SUCCESS(rv
, rv
);
922 void LoadInfoToChildLoadInfoForwarder(
923 nsILoadInfo
* aLoadInfo
, ChildLoadInfoForwarderArgs
* aForwarderArgsOut
) {
924 Maybe
<IPCClientInfo
> ipcReserved
;
925 Maybe
<ClientInfo
> reserved(aLoadInfo
->GetReservedClientInfo());
926 if (reserved
.isSome()) {
927 ipcReserved
.emplace(reserved
.ref().ToIPC());
930 Maybe
<IPCClientInfo
> ipcInitial
;
931 Maybe
<ClientInfo
> initial(aLoadInfo
->GetInitialClientInfo());
932 if (initial
.isSome()) {
933 ipcInitial
.emplace(initial
.ref().ToIPC());
936 Maybe
<IPCServiceWorkerDescriptor
> ipcController
;
937 Maybe
<ServiceWorkerDescriptor
> controller(aLoadInfo
->GetController());
938 if (controller
.isSome()) {
939 ipcController
.emplace(controller
.ref().ToIPC());
943 ChildLoadInfoForwarderArgs(ipcReserved
, ipcInitial
, ipcController
,
944 aLoadInfo
->GetRequestBlockingReason());
947 nsresult
MergeChildLoadInfoForwarder(
948 const ChildLoadInfoForwarderArgs
& aForwarderArgs
, nsILoadInfo
* aLoadInfo
) {
949 Maybe
<ClientInfo
> reservedClientInfo
;
950 auto& ipcReserved
= aForwarderArgs
.reservedClientInfo();
951 if (ipcReserved
.isSome()) {
952 reservedClientInfo
.emplace(ClientInfo(ipcReserved
.ref()));
955 Maybe
<ClientInfo
> initialClientInfo
;
956 auto& ipcInitial
= aForwarderArgs
.initialClientInfo();
957 if (ipcInitial
.isSome()) {
958 initialClientInfo
.emplace(ClientInfo(ipcInitial
.ref()));
961 // There should only be at most one reserved or initial ClientInfo.
962 if (NS_WARN_IF(reservedClientInfo
.isSome() && initialClientInfo
.isSome())) {
963 return NS_ERROR_FAILURE
;
966 // If we received no reserved or initial ClientInfo, then we must not
967 // already have one set. There are no use cases where this should
968 // happen and we don't have a way to clear the current value.
969 if (NS_WARN_IF(reservedClientInfo
.isNothing() &&
970 initialClientInfo
.isNothing() &&
971 (aLoadInfo
->GetReservedClientInfo().isSome() ||
972 aLoadInfo
->GetInitialClientInfo().isSome()))) {
973 return NS_ERROR_FAILURE
;
976 if (reservedClientInfo
.isSome()) {
977 // We need to override here instead of simply set the value. This
978 // allows us to change the reserved client. This is necessary when
979 // the ClientChannelHelper created a new reserved client in the
980 // child-side of the redirect.
981 aLoadInfo
->OverrideReservedClientInfoInParent(reservedClientInfo
.ref());
982 } else if (initialClientInfo
.isSome()) {
983 aLoadInfo
->SetInitialClientInfo(initialClientInfo
.ref());
986 aLoadInfo
->ClearController();
987 auto& controller
= aForwarderArgs
.controller();
988 if (controller
.isSome()) {
989 aLoadInfo
->SetController(ServiceWorkerDescriptor(controller
.ref()));
992 uint32_t blockingReason
= aForwarderArgs
.requestBlockingReason();
993 if (blockingReason
) {
994 // We only want to override when non-null, so that any earlier set non-null
995 // value is not reverted to 0.
996 aLoadInfo
->SetRequestBlockingReason(blockingReason
);
1003 } // namespace mozilla