1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "mozilla/LoadInfo.h"
8 
9 #include "mozilla/Assertions.h"
10 #include "mozilla/dom/ClientIPCTypes.h"
11 #include "mozilla/dom/ClientSource.h"
12 #include "mozilla/dom/PerformanceStorage.h"
13 #include "mozilla/dom/TabChild.h"
14 #include "mozilla/dom/ToJSValue.h"
15 #include "mozIThirdPartyUtil.h"
16 #include "nsFrameLoader.h"
17 #include "nsIContentSecurityPolicy.h"
18 #include "nsIDocShell.h"
19 #include "nsIDocument.h"
20 #include "nsIDOMDocument.h"
21 #include "nsIFrameLoader.h"
22 #include "nsIInterfaceRequestorUtils.h"
23 #include "nsISupportsImpl.h"
24 #include "nsISupportsUtils.h"
25 #include "nsContentUtils.h"
26 #include "nsDocShell.h"
27 #include "nsGlobalWindow.h"
28 #include "NullPrincipal.h"
29 #include "nsRedirectHistoryEntry.h"
30 #include "LoadInfo.h"
31 
32 using namespace mozilla::dom;
33 
34 namespace mozilla {
35 namespace net {
36 
FindTopOuterWindowID(nsPIDOMWindowOuter * aOuter)37 static uint64_t FindTopOuterWindowID(nsPIDOMWindowOuter* aOuter) {
38   nsCOMPtr<nsPIDOMWindowOuter> outer = aOuter;
39   while (nsCOMPtr<nsPIDOMWindowOuter> parent =
40              outer->GetScriptableParentOrNull()) {
41     outer = parent;
42   }
43   return outer->WindowID();
44 }
45 
LoadInfo(nsIPrincipal * aLoadingPrincipal,nsIPrincipal * aTriggeringPrincipal,nsINode * aLoadingContext,nsSecurityFlags aSecurityFlags,nsContentPolicyType aContentPolicyType,const Maybe<mozilla::dom::ClientInfo> & aLoadingClientInfo,const Maybe<mozilla::dom::ServiceWorkerDescriptor> & aController)46 LoadInfo::LoadInfo(
47     nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
48     nsINode* aLoadingContext, nsSecurityFlags aSecurityFlags,
49     nsContentPolicyType aContentPolicyType,
50     const Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
51     const Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController)
52     : mLoadingPrincipal(aLoadingContext ? aLoadingContext->NodePrincipal()
53                                         : aLoadingPrincipal),
54       mTriggeringPrincipal(aTriggeringPrincipal ? aTriggeringPrincipal
55                                                 : mLoadingPrincipal.get()),
56       mPrincipalToInherit(nullptr),
57       mClientInfo(aLoadingClientInfo),
58       mController(aController),
59       mLoadingContext(do_GetWeakReference(aLoadingContext)),
60       mContextForTopLevelLoad(nullptr),
61       mSecurityFlags(aSecurityFlags),
62       mInternalContentPolicyType(aContentPolicyType),
63       mTainting(LoadTainting::Basic),
64       mUpgradeInsecureRequests(false),
65       mBrowserUpgradeInsecureRequests(false),
66       mVerifySignedContent(false),
67       mEnforceSRI(false),
68       mAllowDocumentToBeAgnosticToCSP(false),
69       mForceAllowDataURI(false),
70       mAllowInsecureRedirectToDataURI(false),
71       mOriginalFrameSrcLoad(false),
72       mForceInheritPrincipalDropped(false),
73       mInnerWindowID(0),
74       mOuterWindowID(0),
75       mParentOuterWindowID(0),
76       mTopOuterWindowID(0),
77       mFrameOuterWindowID(0),
78       mEnforceSecurity(false),
79       mInitialSecurityCheckDone(false),
80       mIsThirdPartyContext(false),
81       mIsDocshellReload(false),
82       mForcePreflight(false),
83       mIsPreflight(false),
84       mLoadTriggeredFromExternal(false),
85       mServiceWorkerTaintingSynthesized(false),
86       mIsFromProcessingFrameAttributes(false) {
87   MOZ_ASSERT(mLoadingPrincipal);
88   MOZ_ASSERT(mTriggeringPrincipal);
89 
90 #ifdef DEBUG
91   // TYPE_DOCUMENT loads initiated by javascript tests will go through
92   // nsIOService and use the wrong constructor.  Don't enforce the
93   // !TYPE_DOCUMENT check in those cases
94   bool skipContentTypeCheck = false;
95   skipContentTypeCheck =
96       Preferences::GetBool("network.loadinfo.skip_type_assertion");
97 #endif
98 
99   // This constructor shouldn't be used for TYPE_DOCUMENT loads that don't
100   // have a loadingPrincipal
101   MOZ_ASSERT(skipContentTypeCheck ||
102              mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT);
103 
104   // We should only get an explicit controller for subresource requests.
105   MOZ_DIAGNOSTIC_ASSERT(aController.isNothing() ||
106                         !nsContentUtils::IsNonSubresourceInternalPolicyType(
107                             mInternalContentPolicyType));
108 
109   // TODO(bug 1259873): Above, we initialize mIsThirdPartyContext to false
110   // meaning that consumers of LoadInfo that don't pass a context or pass a
111   // context from which we can't find a window will default to assuming that
112   // they're 1st party. It would be nice if we could default "safe" and assume
113   // that we are 3rd party until proven otherwise.
114 
115   // if consumers pass both, aLoadingContext and aLoadingPrincipal
116   // then the loadingPrincipal must be the same as the node's principal
117   MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal ||
118              aLoadingContext->NodePrincipal() == aLoadingPrincipal);
119 
120   // if the load is sandboxed, we can not also inherit the principal
121   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
122     mForceInheritPrincipalDropped =
123         (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
124     mSecurityFlags &= ~nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
125   }
126 
127   if (aLoadingContext) {
128     // Ensure that all network requests for a window client have the ClientInfo
129     // properly set.  Workers must currently pass the loading ClientInfo
130     // explicitly. We allow main thread requests to explicitly pass the value as
131     // well.
132     if (mClientInfo.isNothing()) {
133       mClientInfo = aLoadingContext->OwnerDoc()->GetClientInfo();
134     }
135 
136     // For subresource loads set the service worker based on the calling
137     // context's controller.  Workers must currently pass the controller in
138     // explicitly.  We allow main thread requests to explicitly pass the value
139     // as well, but otherwise extract from the loading context here.
140     if (mController.isNothing() &&
141         !nsContentUtils::IsNonSubresourceInternalPolicyType(
142             mInternalContentPolicyType)) {
143       mController = aLoadingContext->OwnerDoc()->GetController();
144     }
145 
146     nsCOMPtr<nsPIDOMWindowOuter> contextOuter =
147         aLoadingContext->OwnerDoc()->GetWindow();
148     if (contextOuter) {
149       ComputeIsThirdPartyContext(contextOuter);
150       mOuterWindowID = contextOuter->WindowID();
151       nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
152       mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
153       mTopOuterWindowID = FindTopOuterWindowID(contextOuter);
154     }
155 
156     mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
157     mAncestorPrincipals = aLoadingContext->OwnerDoc()->AncestorPrincipals();
158     mAncestorOuterWindowIDs =
159         aLoadingContext->OwnerDoc()->AncestorOuterWindowIDs();
160     MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() ==
161                           mAncestorOuterWindowIDs.Length());
162 
163     // When the element being loaded is a frame, we choose the frame's window
164     // for the window ID and the frame element's window as the parent
165     // window. This is the behavior that Chrome exposes to add-ons.
166     // NB: If the frameLoaderOwner doesn't have a frame loader, then the load
167     // must be coming from an object (such as a plugin) that's loaded into it
168     // instead of a document being loaded. In that case, treat this object like
169     // any other non-document-loading element.
170     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner =
171         do_QueryInterface(aLoadingContext);
172     nsCOMPtr<nsIFrameLoader> fl =
173         frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
174     if (fl) {
175       nsCOMPtr<nsIDocShell> docShell;
176       if (NS_SUCCEEDED(fl->GetDocShell(getter_AddRefs(docShell))) && docShell) {
177         nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell);
178         if (outerWindow) {
179           mFrameOuterWindowID = outerWindow->WindowID();
180         }
181       }
182     }
183 
184     // if the document forces all requests to be upgraded from http to https,
185     // then we should do that for all requests. If it only forces preloads to be
186     // upgraded then we should enforce upgrade insecure requests only for
187     // preloads.
188     mUpgradeInsecureRequests =
189         aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(false) ||
190         (nsContentUtils::IsPreloadType(mInternalContentPolicyType) &&
191          aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(true));
192 
193     uint32_t externalType = nsContentUtils::InternalContentPolicyTypeToExternal(
194         mInternalContentPolicyType);
195     if (nsContentUtils::IsUpgradableDisplayType(externalType)) {
196       nsCOMPtr<nsIURI> uri;
197       mLoadingPrincipal->GetURI(getter_AddRefs(uri));
198       if (uri) {
199         // Checking https not secure context as http://localhost can't be
200         // upgraded
201         bool isHttpsScheme;
202         nsresult rv = uri->SchemeIs("https", &isHttpsScheme);
203         if (NS_SUCCEEDED(rv) && isHttpsScheme) {
204           mBrowserUpgradeInsecureRequests = true;
205         }
206       }
207     }
208     // if owner doc has content signature, we enforce SRI
209     nsCOMPtr<nsIChannel> channel = aLoadingContext->OwnerDoc()->GetChannel();
210     if (channel) {
211       nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
212       if (loadInfo) {
213         mEnforceSRI = loadInfo->GetVerifySignedContent();
214       }
215     }
216   }
217 
218   // If CSP requires SRI (require-sri-for), then store that information
219   // in the loadInfo so we can enforce SRI before loading the subresource.
220   if (!mEnforceSRI) {
221     // do not look into the CSP if already true:
222     // a CSP saying that SRI isn't needed should not
223     // overrule GetVerifySignedContent
224     if (aLoadingPrincipal) {
225       nsCOMPtr<nsIContentSecurityPolicy> csp;
226       aLoadingPrincipal->GetCsp(getter_AddRefs(csp));
227       uint32_t externalType =
228           nsContentUtils::InternalContentPolicyTypeToExternal(
229               aContentPolicyType);
230       // csp could be null if loading principal is system principal
231       if (csp) {
232         csp->RequireSRIForType(externalType, &mEnforceSRI);
233       }
234       // if CSP is delivered via a meta tag, it's speculatively available
235       // as 'preloadCSP'. If we are preloading a script or style, we have
236       // to apply that speculative 'preloadCSP' for such loads.
237       if (!mEnforceSRI && nsContentUtils::IsPreloadType(aContentPolicyType)) {
238         nsCOMPtr<nsIContentSecurityPolicy> preloadCSP;
239         aLoadingPrincipal->GetPreloadCsp(getter_AddRefs(preloadCSP));
240         if (preloadCSP) {
241           preloadCSP->RequireSRIForType(externalType, &mEnforceSRI);
242         }
243       }
244     }
245   }
246 
247   mOriginAttributes = mLoadingPrincipal->OriginAttributesRef();
248 
249   // We need to do this after inheriting the document's origin attributes
250   // above, in case the loading principal ends up being the system principal.
251   if (aLoadingContext) {
252     nsCOMPtr<nsILoadContext> loadContext =
253         aLoadingContext->OwnerDoc()->GetLoadContext();
254     nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
255     if (loadContext && docShell &&
256         docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
257       bool usePrivateBrowsing;
258       nsresult rv = loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
259       if (NS_SUCCEEDED(rv)) {
260         mOriginAttributes.SyncAttributesWithPrivateBrowsing(usePrivateBrowsing);
261       }
262     }
263   }
264 
265   // For chrome docshell, the mPrivateBrowsingId remains 0 even its
266   // UsePrivateBrowsing() is true, so we only update the mPrivateBrowsingId in
267   // origin attributes if the type of the docshell is content.
268   if (aLoadingContext) {
269     nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
270     if (docShell) {
271       if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
272         MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
273                    "chrome docshell shouldn't have mPrivateBrowsingId set.");
274       }
275     }
276   }
277 }
278 
279 /* Constructor takes an outer window, but no loadingNode or loadingPrincipal.
280  * This constructor should only be used for TYPE_DOCUMENT loads, since they
281  * have a null loadingNode and loadingPrincipal.
282  */
LoadInfo(nsPIDOMWindowOuter * aOuterWindow,nsIPrincipal * aTriggeringPrincipal,nsISupports * aContextForTopLevelLoad,nsSecurityFlags aSecurityFlags)283 LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
284                    nsIPrincipal* aTriggeringPrincipal,
285                    nsISupports* aContextForTopLevelLoad,
286                    nsSecurityFlags aSecurityFlags)
287     : mLoadingPrincipal(nullptr),
288       mTriggeringPrincipal(aTriggeringPrincipal),
289       mPrincipalToInherit(nullptr),
290       mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad)),
291       mSecurityFlags(aSecurityFlags),
292       mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT),
293       mTainting(LoadTainting::Basic),
294       mUpgradeInsecureRequests(false),
295       mBrowserUpgradeInsecureRequests(false),
296       mVerifySignedContent(false),
297       mEnforceSRI(false),
298       mAllowDocumentToBeAgnosticToCSP(false),
299       mForceAllowDataURI(false),
300       mAllowInsecureRedirectToDataURI(false),
301       mOriginalFrameSrcLoad(false),
302       mForceInheritPrincipalDropped(false),
303       mInnerWindowID(0),
304       mOuterWindowID(0),
305       mParentOuterWindowID(0),
306       mTopOuterWindowID(0),
307       mFrameOuterWindowID(0),
308       mEnforceSecurity(false),
309       mInitialSecurityCheckDone(false),
310       mIsThirdPartyContext(false)  // NB: TYPE_DOCUMENT implies not third-party.
311       ,
312       mIsDocshellReload(false),
313       mForcePreflight(false),
314       mIsPreflight(false),
315       mLoadTriggeredFromExternal(false),
316       mServiceWorkerTaintingSynthesized(false),
317       mIsFromProcessingFrameAttributes(false) {
318   // Top-level loads are never third-party
319   // Grab the information we can out of the window.
320   MOZ_ASSERT(aOuterWindow);
321   MOZ_ASSERT(mTriggeringPrincipal);
322 
323   // if the load is sandboxed, we can not also inherit the principal
324   if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
325     mForceInheritPrincipalDropped =
326         (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
327     mSecurityFlags &= ~nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
328   }
329 
330   // NB: Ignore the current inner window since we're navigating away from it.
331   mOuterWindowID = aOuterWindow->WindowID();
332 
333   // TODO We can have a parent without a frame element in some cases dealing
334   // with the hidden window.
335   nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
336   mParentOuterWindowID = parent ? parent->WindowID() : 0;
337   mTopOuterWindowID = FindTopOuterWindowID(aOuterWindow);
338 
339   // get the docshell from the outerwindow, and then get the originattributes
340   nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
341   MOZ_ASSERT(docShell);
342   mOriginAttributes = nsDocShell::Cast(docShell)->GetOriginAttributes();
343   mAncestorPrincipals = nsDocShell::Cast(docShell)->AncestorPrincipals();
344   mAncestorOuterWindowIDs =
345       nsDocShell::Cast(docShell)->AncestorOuterWindowIDs();
346   MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() ==
347                         mAncestorOuterWindowIDs.Length());
348 
349 #ifdef DEBUG
350   if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
351     MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
352                "chrome docshell shouldn't have mPrivateBrowsingId set.");
353   }
354 #endif
355 }
356 
LoadInfo(const LoadInfo & rhs)357 LoadInfo::LoadInfo(const LoadInfo& rhs)
358     : mLoadingPrincipal(rhs.mLoadingPrincipal),
359       mTriggeringPrincipal(rhs.mTriggeringPrincipal),
360       mPrincipalToInherit(rhs.mPrincipalToInherit),
361       mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal),
362       mResultPrincipalURI(rhs.mResultPrincipalURI),
363       mClientInfo(rhs.mClientInfo)
364       // mReservedClientSource must be handled specially during redirect
365       // mReservedClientInfo must be handled specially during redirect
366       // mInitialClientInfo must be handled specially during redirect
367       ,
368       mController(rhs.mController),
369       mPerformanceStorage(rhs.mPerformanceStorage),
370       mLoadingContext(rhs.mLoadingContext),
371       mContextForTopLevelLoad(rhs.mContextForTopLevelLoad),
372       mSecurityFlags(rhs.mSecurityFlags),
373       mInternalContentPolicyType(rhs.mInternalContentPolicyType),
374       mTainting(rhs.mTainting),
375       mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests),
376       mBrowserUpgradeInsecureRequests(rhs.mBrowserUpgradeInsecureRequests),
377       mVerifySignedContent(rhs.mVerifySignedContent),
378       mEnforceSRI(rhs.mEnforceSRI),
379       mAllowDocumentToBeAgnosticToCSP(rhs.mAllowDocumentToBeAgnosticToCSP),
380       mForceAllowDataURI(rhs.mForceAllowDataURI),
381       mAllowInsecureRedirectToDataURI(rhs.mAllowInsecureRedirectToDataURI),
382       mOriginalFrameSrcLoad(rhs.mOriginalFrameSrcLoad),
383       mForceInheritPrincipalDropped(rhs.mForceInheritPrincipalDropped),
384       mInnerWindowID(rhs.mInnerWindowID),
385       mOuterWindowID(rhs.mOuterWindowID),
386       mParentOuterWindowID(rhs.mParentOuterWindowID),
387       mTopOuterWindowID(rhs.mTopOuterWindowID),
388       mFrameOuterWindowID(rhs.mFrameOuterWindowID),
389       mEnforceSecurity(rhs.mEnforceSecurity),
390       mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone),
391       mIsThirdPartyContext(rhs.mIsThirdPartyContext),
392       mIsDocshellReload(rhs.mIsDocshellReload),
393       mOriginAttributes(rhs.mOriginAttributes),
394       mRedirectChainIncludingInternalRedirects(
395           rhs.mRedirectChainIncludingInternalRedirects),
396       mRedirectChain(rhs.mRedirectChain),
397       mAncestorPrincipals(rhs.mAncestorPrincipals),
398       mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs),
399       mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders),
400       mForcePreflight(rhs.mForcePreflight),
401       mIsPreflight(rhs.mIsPreflight),
402       mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal),
403       mServiceWorkerTaintingSynthesized(rhs.mServiceWorkerTaintingSynthesized),
404       mIsFromProcessingFrameAttributes(rhs.mIsFromProcessingFrameAttributes) {}
405 
LoadInfo(nsIPrincipal * aLoadingPrincipal,nsIPrincipal * aTriggeringPrincipal,nsIPrincipal * aPrincipalToInherit,nsIPrincipal * aSandboxedLoadingPrincipal,nsIURI * aResultPrincipalURI,const Maybe<ClientInfo> & aClientInfo,const Maybe<ClientInfo> & aReservedClientInfo,const Maybe<ClientInfo> & aInitialClientInfo,const Maybe<ServiceWorkerDescriptor> & aController,nsSecurityFlags aSecurityFlags,nsContentPolicyType aContentPolicyType,LoadTainting aTainting,bool aUpgradeInsecureRequests,bool aBrowserUpgradeInsecureRequests,bool aVerifySignedContent,bool aEnforceSRI,bool aAllowDocumentToBeAgnosticToCSP,bool aForceAllowDataURI,bool aAllowInsecureRedirectToDataURI,bool aForceInheritPrincipalDropped,uint64_t aInnerWindowID,uint64_t aOuterWindowID,uint64_t aParentOuterWindowID,uint64_t aTopOuterWindowID,uint64_t aFrameOuterWindowID,bool aEnforceSecurity,bool aInitialSecurityCheckDone,bool aIsThirdPartyContext,bool aIsDocshellReload,const OriginAttributes & aOriginAttributes,RedirectHistoryArray & aRedirectChainIncludingInternalRedirects,RedirectHistoryArray & aRedirectChain,nsTArray<nsCOMPtr<nsIPrincipal>> && aAncestorPrincipals,const nsTArray<uint64_t> & aAncestorOuterWindowIDs,const nsTArray<nsCString> & aCorsUnsafeHeaders,bool aForcePreflight,bool aIsPreflight,bool aLoadTriggeredFromExternal,bool aServiceWorkerTaintingSynthesized)406 LoadInfo::LoadInfo(
407     nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
408     nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aSandboxedLoadingPrincipal,
409     nsIURI* aResultPrincipalURI, const Maybe<ClientInfo>& aClientInfo,
410     const Maybe<ClientInfo>& aReservedClientInfo,
411     const Maybe<ClientInfo>& aInitialClientInfo,
412     const Maybe<ServiceWorkerDescriptor>& aController,
413     nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
414     LoadTainting aTainting, bool aUpgradeInsecureRequests,
415     bool aBrowserUpgradeInsecureRequests, bool aVerifySignedContent,
416     bool aEnforceSRI, bool aAllowDocumentToBeAgnosticToCSP,
417     bool aForceAllowDataURI, bool aAllowInsecureRedirectToDataURI,
418     bool aForceInheritPrincipalDropped, uint64_t aInnerWindowID,
419     uint64_t aOuterWindowID, uint64_t aParentOuterWindowID,
420     uint64_t aTopOuterWindowID, uint64_t aFrameOuterWindowID,
421     bool aEnforceSecurity, bool aInitialSecurityCheckDone,
422     bool aIsThirdPartyContext, bool aIsDocshellReload,
423     const OriginAttributes& aOriginAttributes,
424     RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
425     RedirectHistoryArray& aRedirectChain,
426     nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
427     const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
428     const nsTArray<nsCString>& aCorsUnsafeHeaders, bool aForcePreflight,
429     bool aIsPreflight, bool aLoadTriggeredFromExternal,
430     bool aServiceWorkerTaintingSynthesized)
431     : mLoadingPrincipal(aLoadingPrincipal),
432       mTriggeringPrincipal(aTriggeringPrincipal),
433       mPrincipalToInherit(aPrincipalToInherit),
434       mResultPrincipalURI(aResultPrincipalURI),
435       mClientInfo(aClientInfo),
436       mReservedClientInfo(aReservedClientInfo),
437       mInitialClientInfo(aInitialClientInfo),
438       mController(aController),
439       mSecurityFlags(aSecurityFlags),
440       mInternalContentPolicyType(aContentPolicyType),
441       mTainting(aTainting),
442       mUpgradeInsecureRequests(aUpgradeInsecureRequests),
443       mBrowserUpgradeInsecureRequests(aBrowserUpgradeInsecureRequests),
444       mVerifySignedContent(aVerifySignedContent),
445       mEnforceSRI(aEnforceSRI),
446       mAllowDocumentToBeAgnosticToCSP(aAllowDocumentToBeAgnosticToCSP),
447       mForceAllowDataURI(aForceAllowDataURI),
448       mAllowInsecureRedirectToDataURI(aAllowInsecureRedirectToDataURI),
449       mOriginalFrameSrcLoad(false),
450       mForceInheritPrincipalDropped(aForceInheritPrincipalDropped),
451       mInnerWindowID(aInnerWindowID),
452       mOuterWindowID(aOuterWindowID),
453       mParentOuterWindowID(aParentOuterWindowID),
454       mTopOuterWindowID(aTopOuterWindowID),
455       mFrameOuterWindowID(aFrameOuterWindowID),
456       mEnforceSecurity(aEnforceSecurity),
457       mInitialSecurityCheckDone(aInitialSecurityCheckDone),
458       mIsThirdPartyContext(aIsThirdPartyContext),
459       mIsDocshellReload(aIsDocshellReload),
460       mOriginAttributes(aOriginAttributes),
461       mAncestorPrincipals(Move(aAncestorPrincipals)),
462       mAncestorOuterWindowIDs(aAncestorOuterWindowIDs),
463       mCorsUnsafeHeaders(aCorsUnsafeHeaders),
464       mForcePreflight(aForcePreflight),
465       mIsPreflight(aIsPreflight),
466       mLoadTriggeredFromExternal(aLoadTriggeredFromExternal),
467       mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized),
468       mIsFromProcessingFrameAttributes(false) {
469   // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
470   MOZ_ASSERT(mLoadingPrincipal ||
471              aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
472   MOZ_ASSERT(mTriggeringPrincipal);
473 
474   mRedirectChainIncludingInternalRedirects.SwapElements(
475       aRedirectChainIncludingInternalRedirects);
476 
477   mRedirectChain.SwapElements(aRedirectChain);
478 }
479 
~LoadInfo()480 LoadInfo::~LoadInfo() {}
481 
ComputeIsThirdPartyContext(nsPIDOMWindowOuter * aOuterWindow)482 void LoadInfo::ComputeIsThirdPartyContext(nsPIDOMWindowOuter* aOuterWindow) {
483   nsContentPolicyType type =
484       nsContentUtils::InternalContentPolicyTypeToExternal(
485           mInternalContentPolicyType);
486   if (type == nsIContentPolicy::TYPE_DOCUMENT) {
487     // Top-level loads are never third-party.
488     mIsThirdPartyContext = false;
489     return;
490   }
491 
492   nsCOMPtr<mozIThirdPartyUtil> util(do_GetService(THIRDPARTYUTIL_CONTRACTID));
493   if (NS_WARN_IF(!util)) {
494     return;
495   }
496 
497   util->IsThirdPartyWindow(aOuterWindow, nullptr, &mIsThirdPartyContext);
498 }
499 
NS_IMPL_ISUPPORTS(LoadInfo,nsILoadInfo)500 NS_IMPL_ISUPPORTS(LoadInfo, nsILoadInfo)
501 
502 already_AddRefed<nsILoadInfo> LoadInfo::Clone() const {
503   RefPtr<LoadInfo> copy(new LoadInfo(*this));
504   return copy.forget();
505 }
506 
CloneWithNewSecFlags(nsSecurityFlags aSecurityFlags) const507 already_AddRefed<nsILoadInfo> LoadInfo::CloneWithNewSecFlags(
508     nsSecurityFlags aSecurityFlags) const {
509   RefPtr<LoadInfo> copy(new LoadInfo(*this));
510   copy->mSecurityFlags = aSecurityFlags;
511   return copy.forget();
512 }
513 
CloneForNewRequest() const514 already_AddRefed<nsILoadInfo> LoadInfo::CloneForNewRequest() const {
515   RefPtr<LoadInfo> copy(new LoadInfo(*this));
516   copy->mEnforceSecurity = false;
517   copy->mInitialSecurityCheckDone = false;
518   copy->mRedirectChainIncludingInternalRedirects.Clear();
519   copy->mRedirectChain.Clear();
520   copy->mResultPrincipalURI = nullptr;
521   return copy.forget();
522 }
523 
524 NS_IMETHODIMP
GetLoadingPrincipal(nsIPrincipal ** aLoadingPrincipal)525 LoadInfo::GetLoadingPrincipal(nsIPrincipal** aLoadingPrincipal) {
526   NS_IF_ADDREF(*aLoadingPrincipal = mLoadingPrincipal);
527   return NS_OK;
528 }
529 
LoadingPrincipal()530 nsIPrincipal* LoadInfo::LoadingPrincipal() { return mLoadingPrincipal; }
531 
532 NS_IMETHODIMP
GetTriggeringPrincipal(nsIPrincipal ** aTriggeringPrincipal)533 LoadInfo::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal) {
534   NS_ADDREF(*aTriggeringPrincipal = mTriggeringPrincipal);
535   return NS_OK;
536 }
537 
TriggeringPrincipal()538 nsIPrincipal* LoadInfo::TriggeringPrincipal() { return mTriggeringPrincipal; }
539 
540 NS_IMETHODIMP
GetPrincipalToInherit(nsIPrincipal ** aPrincipalToInherit)541 LoadInfo::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) {
542   NS_IF_ADDREF(*aPrincipalToInherit = mPrincipalToInherit);
543   return NS_OK;
544 }
545 
546 NS_IMETHODIMP
SetPrincipalToInherit(nsIPrincipal * aPrincipalToInherit)547 LoadInfo::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) {
548   MOZ_ASSERT(aPrincipalToInherit, "must be a valid principal to inherit");
549   mPrincipalToInherit = aPrincipalToInherit;
550   return NS_OK;
551 }
552 
PrincipalToInherit()553 nsIPrincipal* LoadInfo::PrincipalToInherit() { return mPrincipalToInherit; }
554 
FindPrincipalToInherit(nsIChannel * aChannel)555 nsIPrincipal* LoadInfo::FindPrincipalToInherit(nsIChannel* aChannel) {
556   if (mPrincipalToInherit) {
557     return mPrincipalToInherit;
558   }
559 
560   nsCOMPtr<nsIURI> uri = mResultPrincipalURI;
561   if (!uri) {
562     Unused << aChannel->GetOriginalURI(getter_AddRefs(uri));
563   }
564 
565   auto prin = BasePrincipal::Cast(mTriggeringPrincipal);
566   return prin->PrincipalToInherit(uri);
567 }
568 
569 NS_IMETHODIMP
GetSandboxedLoadingPrincipal(nsIPrincipal ** aPrincipal)570 LoadInfo::GetSandboxedLoadingPrincipal(nsIPrincipal** aPrincipal) {
571   if (!(mSecurityFlags & nsILoadInfo::SEC_SANDBOXED)) {
572     *aPrincipal = nullptr;
573     return NS_OK;
574   }
575 
576   if (!mSandboxedLoadingPrincipal) {
577     if (mLoadingPrincipal) {
578       mSandboxedLoadingPrincipal =
579           NullPrincipal::CreateWithInheritedAttributes(mLoadingPrincipal);
580     } else {
581       OriginAttributes attrs(mOriginAttributes);
582       mSandboxedLoadingPrincipal = NullPrincipal::Create(attrs);
583     }
584   }
585   MOZ_ASSERT(mSandboxedLoadingPrincipal);
586 
587   nsCOMPtr<nsIPrincipal> copy(mSandboxedLoadingPrincipal);
588   copy.forget(aPrincipal);
589   return NS_OK;
590 }
591 
592 NS_IMETHODIMP
GetLoadingDocument(nsIDOMDocument ** aResult)593 LoadInfo::GetLoadingDocument(nsIDOMDocument** aResult) {
594   nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext);
595   if (node) {
596     nsCOMPtr<nsIDOMDocument> context = do_QueryInterface(node->OwnerDoc());
597     context.forget(aResult);
598   }
599   return NS_OK;
600 }
601 
LoadingNode()602 nsINode* LoadInfo::LoadingNode() {
603   nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext);
604   return node;
605 }
606 
ContextForTopLevelLoad()607 nsISupports* LoadInfo::ContextForTopLevelLoad() {
608   // Most likely you want to query LoadingNode() instead of
609   // ContextForTopLevelLoad() if this assertion fires.
610   MOZ_ASSERT(mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
611              "should only query this context for top level document loads");
612   nsCOMPtr<nsISupports> context = do_QueryReferent(mContextForTopLevelLoad);
613   return context;
614 }
615 
616 NS_IMETHODIMP
GetSecurityFlags(nsSecurityFlags * aResult)617 LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult) {
618   *aResult = mSecurityFlags;
619   return NS_OK;
620 }
621 
622 NS_IMETHODIMP
GetSecurityMode(uint32_t * aFlags)623 LoadInfo::GetSecurityMode(uint32_t* aFlags) {
624   *aFlags =
625       (mSecurityFlags & (nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
626                          nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED |
627                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
628                          nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL |
629                          nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS));
630   return NS_OK;
631 }
632 
633 NS_IMETHODIMP
GetIsInThirdPartyContext(bool * aIsInThirdPartyContext)634 LoadInfo::GetIsInThirdPartyContext(bool* aIsInThirdPartyContext) {
635   *aIsInThirdPartyContext = mIsThirdPartyContext;
636   return NS_OK;
637 }
638 
639 static const uint32_t sCookiePolicyMask =
640     nsILoadInfo::SEC_COOKIES_DEFAULT | nsILoadInfo::SEC_COOKIES_INCLUDE |
641     nsILoadInfo::SEC_COOKIES_SAME_ORIGIN | nsILoadInfo::SEC_COOKIES_OMIT;
642 
643 NS_IMETHODIMP
GetCookiePolicy(uint32_t * aResult)644 LoadInfo::GetCookiePolicy(uint32_t* aResult) {
645   uint32_t policy = mSecurityFlags & sCookiePolicyMask;
646   if (policy == nsILoadInfo::SEC_COOKIES_DEFAULT) {
647     policy = (mSecurityFlags & SEC_REQUIRE_CORS_DATA_INHERITS)
648                  ? nsILoadInfo::SEC_COOKIES_SAME_ORIGIN
649                  : nsILoadInfo::SEC_COOKIES_INCLUDE;
650   }
651 
652   *aResult = policy;
653   return NS_OK;
654 }
655 
SetIncludeCookiesSecFlag()656 void LoadInfo::SetIncludeCookiesSecFlag() {
657   MOZ_ASSERT(!mEnforceSecurity, "Request should not have been opened yet");
658   MOZ_ASSERT((mSecurityFlags & sCookiePolicyMask) ==
659              nsILoadInfo::SEC_COOKIES_DEFAULT);
660   mSecurityFlags =
661       (mSecurityFlags & ~sCookiePolicyMask) | nsILoadInfo::SEC_COOKIES_INCLUDE;
662 }
663 
664 NS_IMETHODIMP
GetForceInheritPrincipal(bool * aInheritPrincipal)665 LoadInfo::GetForceInheritPrincipal(bool* aInheritPrincipal) {
666   *aInheritPrincipal =
667       (mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
668   return NS_OK;
669 }
670 
671 NS_IMETHODIMP
GetForceInheritPrincipalOverruleOwner(bool * aInheritPrincipal)672 LoadInfo::GetForceInheritPrincipalOverruleOwner(bool* aInheritPrincipal) {
673   *aInheritPrincipal =
674       (mSecurityFlags &
675        nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER);
676   return NS_OK;
677 }
678 
679 NS_IMETHODIMP
GetLoadingSandboxed(bool * aLoadingSandboxed)680 LoadInfo::GetLoadingSandboxed(bool* aLoadingSandboxed) {
681   *aLoadingSandboxed = (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED);
682   return NS_OK;
683 }
684 
685 NS_IMETHODIMP
GetAboutBlankInherits(bool * aResult)686 LoadInfo::GetAboutBlankInherits(bool* aResult) {
687   *aResult = (mSecurityFlags & nsILoadInfo::SEC_ABOUT_BLANK_INHERITS);
688   return NS_OK;
689 }
690 
691 NS_IMETHODIMP
GetAllowChrome(bool * aResult)692 LoadInfo::GetAllowChrome(bool* aResult) {
693   *aResult = (mSecurityFlags & nsILoadInfo::SEC_ALLOW_CHROME);
694   return NS_OK;
695 }
696 
697 NS_IMETHODIMP
GetDisallowScript(bool * aResult)698 LoadInfo::GetDisallowScript(bool* aResult) {
699   *aResult = (mSecurityFlags & nsILoadInfo::SEC_DISALLOW_SCRIPT);
700   return NS_OK;
701 }
702 
703 NS_IMETHODIMP
GetDontFollowRedirects(bool * aResult)704 LoadInfo::GetDontFollowRedirects(bool* aResult) {
705   *aResult = (mSecurityFlags & nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS);
706   return NS_OK;
707 }
708 
709 NS_IMETHODIMP
GetLoadErrorPage(bool * aResult)710 LoadInfo::GetLoadErrorPage(bool* aResult) {
711   *aResult = (mSecurityFlags & nsILoadInfo::SEC_LOAD_ERROR_PAGE);
712   return NS_OK;
713 }
714 
715 NS_IMETHODIMP
GetIsDocshellReload(bool * aResult)716 LoadInfo::GetIsDocshellReload(bool* aResult) {
717   *aResult = mIsDocshellReload;
718   return NS_OK;
719 }
720 
721 NS_IMETHODIMP
SetIsDocshellReload(bool aValue)722 LoadInfo::SetIsDocshellReload(bool aValue) {
723   mIsDocshellReload = aValue;
724   return NS_OK;
725 }
726 
727 NS_IMETHODIMP
GetExternalContentPolicyType(nsContentPolicyType * aResult)728 LoadInfo::GetExternalContentPolicyType(nsContentPolicyType* aResult) {
729   *aResult = nsContentUtils::InternalContentPolicyTypeToExternal(
730       mInternalContentPolicyType);
731   return NS_OK;
732 }
733 
InternalContentPolicyType()734 nsContentPolicyType LoadInfo::InternalContentPolicyType() {
735   return mInternalContentPolicyType;
736 }
737 
738 NS_IMETHODIMP
GetUpgradeInsecureRequests(bool * aResult)739 LoadInfo::GetUpgradeInsecureRequests(bool* aResult) {
740   *aResult = mUpgradeInsecureRequests;
741   return NS_OK;
742 }
743 
744 NS_IMETHODIMP
GetBrowserUpgradeInsecureRequests(bool * aResult)745 LoadInfo::GetBrowserUpgradeInsecureRequests(bool* aResult) {
746   *aResult = mBrowserUpgradeInsecureRequests;
747   return NS_OK;
748 }
749 
750 NS_IMETHODIMP
SetVerifySignedContent(bool aVerifySignedContent)751 LoadInfo::SetVerifySignedContent(bool aVerifySignedContent) {
752   MOZ_ASSERT(mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
753              "can only verify content for TYPE_DOCUMENT");
754   mVerifySignedContent = aVerifySignedContent;
755   return NS_OK;
756 }
757 
758 NS_IMETHODIMP
GetVerifySignedContent(bool * aResult)759 LoadInfo::GetVerifySignedContent(bool* aResult) {
760   *aResult = mVerifySignedContent;
761   return NS_OK;
762 }
763 
764 NS_IMETHODIMP
SetEnforceSRI(bool aEnforceSRI)765 LoadInfo::SetEnforceSRI(bool aEnforceSRI) {
766   mEnforceSRI = aEnforceSRI;
767   return NS_OK;
768 }
769 
770 NS_IMETHODIMP
GetEnforceSRI(bool * aResult)771 LoadInfo::GetEnforceSRI(bool* aResult) {
772   *aResult = mEnforceSRI;
773   return NS_OK;
774 }
775 
776 NS_IMETHODIMP
SetForceAllowDataURI(bool aForceAllowDataURI)777 LoadInfo::SetForceAllowDataURI(bool aForceAllowDataURI) {
778   MOZ_ASSERT(!mForceAllowDataURI ||
779                  mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
780              "can only allow data URI navigation for TYPE_DOCUMENT");
781   mForceAllowDataURI = aForceAllowDataURI;
782   return NS_OK;
783 }
784 
785 NS_IMETHODIMP
GetForceAllowDataURI(bool * aForceAllowDataURI)786 LoadInfo::GetForceAllowDataURI(bool* aForceAllowDataURI) {
787   *aForceAllowDataURI = mForceAllowDataURI;
788   return NS_OK;
789 }
790 
791 NS_IMETHODIMP
SetAllowInsecureRedirectToDataURI(bool aAllowInsecureRedirectToDataURI)792 LoadInfo::SetAllowInsecureRedirectToDataURI(
793     bool aAllowInsecureRedirectToDataURI) {
794   mAllowInsecureRedirectToDataURI = aAllowInsecureRedirectToDataURI;
795   return NS_OK;
796 }
797 
798 NS_IMETHODIMP
GetAllowInsecureRedirectToDataURI(bool * aAllowInsecureRedirectToDataURI)799 LoadInfo::GetAllowInsecureRedirectToDataURI(
800     bool* aAllowInsecureRedirectToDataURI) {
801   *aAllowInsecureRedirectToDataURI = mAllowInsecureRedirectToDataURI;
802   return NS_OK;
803 }
804 
805 NS_IMETHODIMP
SetOriginalFrameSrcLoad(bool aOriginalFrameSrcLoad)806 LoadInfo::SetOriginalFrameSrcLoad(bool aOriginalFrameSrcLoad) {
807   mOriginalFrameSrcLoad = aOriginalFrameSrcLoad;
808   return NS_OK;
809 }
810 
811 NS_IMETHODIMP
GetOriginalFrameSrcLoad(bool * aOriginalFrameSrcLoad)812 LoadInfo::GetOriginalFrameSrcLoad(bool* aOriginalFrameSrcLoad) {
813   *aOriginalFrameSrcLoad = mOriginalFrameSrcLoad;
814   return NS_OK;
815 }
816 
817 NS_IMETHODIMP
GetForceInheritPrincipalDropped(bool * aResult)818 LoadInfo::GetForceInheritPrincipalDropped(bool* aResult) {
819   *aResult = mForceInheritPrincipalDropped;
820   return NS_OK;
821 }
822 
823 NS_IMETHODIMP
GetInnerWindowID(uint64_t * aResult)824 LoadInfo::GetInnerWindowID(uint64_t* aResult) {
825   *aResult = mInnerWindowID;
826   return NS_OK;
827 }
828 
829 NS_IMETHODIMP
GetOuterWindowID(uint64_t * aResult)830 LoadInfo::GetOuterWindowID(uint64_t* aResult) {
831   *aResult = mOuterWindowID;
832   return NS_OK;
833 }
834 
835 NS_IMETHODIMP
GetParentOuterWindowID(uint64_t * aResult)836 LoadInfo::GetParentOuterWindowID(uint64_t* aResult) {
837   *aResult = mParentOuterWindowID;
838   return NS_OK;
839 }
840 
841 NS_IMETHODIMP
GetTopOuterWindowID(uint64_t * aResult)842 LoadInfo::GetTopOuterWindowID(uint64_t* aResult) {
843   *aResult = mTopOuterWindowID;
844   return NS_OK;
845 }
846 
847 NS_IMETHODIMP
GetFrameOuterWindowID(uint64_t * aResult)848 LoadInfo::GetFrameOuterWindowID(uint64_t* aResult) {
849   *aResult = mFrameOuterWindowID;
850   return NS_OK;
851 }
852 
853 NS_IMETHODIMP
GetScriptableOriginAttributes(JSContext * aCx,JS::MutableHandle<JS::Value> aOriginAttributes)854 LoadInfo::GetScriptableOriginAttributes(
855     JSContext* aCx, JS::MutableHandle<JS::Value> aOriginAttributes) {
856   if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aOriginAttributes))) {
857     return NS_ERROR_FAILURE;
858   }
859   return NS_OK;
860 }
861 
862 NS_IMETHODIMP
ResetPrincipalToInheritToNullPrincipal()863 LoadInfo::ResetPrincipalToInheritToNullPrincipal() {
864   // take the originAttributes from the LoadInfo and create
865   // a new NullPrincipal using those origin attributes.
866   nsCOMPtr<nsIPrincipal> newNullPrincipal =
867       NullPrincipal::Create(mOriginAttributes);
868 
869   mPrincipalToInherit = newNullPrincipal;
870 
871   // setting SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER will overrule
872   // any non null owner set on the channel and will return the principal
873   // form the loadinfo instead.
874   mSecurityFlags |= SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER;
875 
876   return NS_OK;
877 }
878 
879 NS_IMETHODIMP
SetAllowDocumentToBeAgnosticToCSP(bool aAllowDocumentToBeAgnosticToCSP)880 LoadInfo::SetAllowDocumentToBeAgnosticToCSP(
881     bool aAllowDocumentToBeAgnosticToCSP) {
882   if (mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) {
883     MOZ_ASSERT(false, "not available for loads other than TYPE_DOCUMENT");
884     return NS_ERROR_UNEXPECTED;
885   }
886   mAllowDocumentToBeAgnosticToCSP = aAllowDocumentToBeAgnosticToCSP;
887   return NS_OK;
888 }
889 
890 NS_IMETHODIMP
GetAllowDocumentToBeAgnosticToCSP(bool * aAllowDocumentToBeAgnosticToCSP)891 LoadInfo::GetAllowDocumentToBeAgnosticToCSP(
892     bool* aAllowDocumentToBeAgnosticToCSP) {
893   *aAllowDocumentToBeAgnosticToCSP = mAllowDocumentToBeAgnosticToCSP;
894   return NS_OK;
895 }
896 
897 NS_IMETHODIMP
SetScriptableOriginAttributes(JSContext * aCx,JS::Handle<JS::Value> aOriginAttributes)898 LoadInfo::SetScriptableOriginAttributes(
899     JSContext* aCx, JS::Handle<JS::Value> aOriginAttributes) {
900   OriginAttributes attrs;
901   if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
902     return NS_ERROR_INVALID_ARG;
903   }
904 
905   mOriginAttributes = attrs;
906   return NS_OK;
907 }
908 
GetOriginAttributes(mozilla::OriginAttributes * aOriginAttributes)909 nsresult LoadInfo::GetOriginAttributes(
910     mozilla::OriginAttributes* aOriginAttributes) {
911   NS_ENSURE_ARG(aOriginAttributes);
912   *aOriginAttributes = mOriginAttributes;
913   return NS_OK;
914 }
915 
SetOriginAttributes(const mozilla::OriginAttributes & aOriginAttributes)916 nsresult LoadInfo::SetOriginAttributes(
917     const mozilla::OriginAttributes& aOriginAttributes) {
918   mOriginAttributes = aOriginAttributes;
919   return NS_OK;
920 }
921 
922 NS_IMETHODIMP
SetEnforceSecurity(bool aEnforceSecurity)923 LoadInfo::SetEnforceSecurity(bool aEnforceSecurity) {
924   // Indicates whether the channel was openend using AsyncOpen2. Once set
925   // to true, it must remain true throughout the lifetime of the channel.
926   // Setting it to anything else than true will be discarded.
927   MOZ_ASSERT(aEnforceSecurity, "aEnforceSecurity must be true");
928   mEnforceSecurity = mEnforceSecurity || aEnforceSecurity;
929   return NS_OK;
930 }
931 
932 NS_IMETHODIMP
GetEnforceSecurity(bool * aResult)933 LoadInfo::GetEnforceSecurity(bool* aResult) {
934   *aResult = mEnforceSecurity;
935   return NS_OK;
936 }
937 
938 NS_IMETHODIMP
SetInitialSecurityCheckDone(bool aInitialSecurityCheckDone)939 LoadInfo::SetInitialSecurityCheckDone(bool aInitialSecurityCheckDone) {
940   // Indicates whether the channel was ever evaluated by the
941   // ContentSecurityManager. Once set to true, this flag must
942   // remain true throughout the lifetime of the channel.
943   // Setting it to anything else than true will be discarded.
944   MOZ_ASSERT(aInitialSecurityCheckDone,
945              "aInitialSecurityCheckDone must be true");
946   mInitialSecurityCheckDone =
947       mInitialSecurityCheckDone || aInitialSecurityCheckDone;
948   return NS_OK;
949 }
950 
951 NS_IMETHODIMP
GetInitialSecurityCheckDone(bool * aResult)952 LoadInfo::GetInitialSecurityCheckDone(bool* aResult) {
953   *aResult = mInitialSecurityCheckDone;
954   return NS_OK;
955 }
956 
957 NS_IMETHODIMP
AppendRedirectHistoryEntry(nsIRedirectHistoryEntry * aEntry,bool aIsInternalRedirect)958 LoadInfo::AppendRedirectHistoryEntry(nsIRedirectHistoryEntry* aEntry,
959                                      bool aIsInternalRedirect) {
960   NS_ENSURE_ARG(aEntry);
961   MOZ_ASSERT(NS_IsMainThread());
962 
963   mRedirectChainIncludingInternalRedirects.AppendElement(aEntry);
964   if (!aIsInternalRedirect) {
965     mRedirectChain.AppendElement(aEntry);
966   }
967   return NS_OK;
968 }
969 
970 NS_IMETHODIMP
GetRedirects(JSContext * aCx,JS::MutableHandle<JS::Value> aRedirects,const RedirectHistoryArray & aArray)971 LoadInfo::GetRedirects(JSContext* aCx, JS::MutableHandle<JS::Value> aRedirects,
972                        const RedirectHistoryArray& aArray) {
973   JS::Rooted<JSObject*> redirects(aCx, JS_NewArrayObject(aCx, aArray.Length()));
974   NS_ENSURE_TRUE(redirects, NS_ERROR_OUT_OF_MEMORY);
975 
976   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
977   NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
978 
979   nsCOMPtr<nsIXPConnect> xpc = mozilla::services::GetXPConnect();
980 
981   for (size_t idx = 0; idx < aArray.Length(); idx++) {
982     JS::RootedObject jsobj(aCx);
983     nsresult rv =
984         xpc->WrapNative(aCx, global, aArray[idx],
985                         NS_GET_IID(nsIRedirectHistoryEntry), jsobj.address());
986     NS_ENSURE_SUCCESS(rv, rv);
987     NS_ENSURE_STATE(jsobj);
988 
989     bool rc = JS_DefineElement(aCx, redirects, idx, jsobj, JSPROP_ENUMERATE);
990     NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
991   }
992 
993   aRedirects.setObject(*redirects);
994   return NS_OK;
995 }
996 
997 NS_IMETHODIMP
GetRedirectChainIncludingInternalRedirects(JSContext * aCx,JS::MutableHandle<JS::Value> aChain)998 LoadInfo::GetRedirectChainIncludingInternalRedirects(
999     JSContext* aCx, JS::MutableHandle<JS::Value> aChain) {
1000   return GetRedirects(aCx, aChain, mRedirectChainIncludingInternalRedirects);
1001 }
1002 
1003 const RedirectHistoryArray&
RedirectChainIncludingInternalRedirects()1004 LoadInfo::RedirectChainIncludingInternalRedirects() {
1005   return mRedirectChainIncludingInternalRedirects;
1006 }
1007 
1008 NS_IMETHODIMP
GetRedirectChain(JSContext * aCx,JS::MutableHandle<JS::Value> aChain)1009 LoadInfo::GetRedirectChain(JSContext* aCx,
1010                            JS::MutableHandle<JS::Value> aChain) {
1011   return GetRedirects(aCx, aChain, mRedirectChain);
1012 }
1013 
RedirectChain()1014 const RedirectHistoryArray& LoadInfo::RedirectChain() { return mRedirectChain; }
1015 
AncestorPrincipals()1016 const nsTArray<nsCOMPtr<nsIPrincipal>>& LoadInfo::AncestorPrincipals() {
1017   return mAncestorPrincipals;
1018 }
1019 
AncestorOuterWindowIDs()1020 const nsTArray<uint64_t>& LoadInfo::AncestorOuterWindowIDs() {
1021   return mAncestorOuterWindowIDs;
1022 }
1023 
SetCorsPreflightInfo(const nsTArray<nsCString> & aHeaders,bool aForcePreflight)1024 void LoadInfo::SetCorsPreflightInfo(const nsTArray<nsCString>& aHeaders,
1025                                     bool aForcePreflight) {
1026   MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
1027   MOZ_ASSERT(!mInitialSecurityCheckDone);
1028   mCorsUnsafeHeaders = aHeaders;
1029   mForcePreflight = aForcePreflight;
1030 }
1031 
CorsUnsafeHeaders()1032 const nsTArray<nsCString>& LoadInfo::CorsUnsafeHeaders() {
1033   return mCorsUnsafeHeaders;
1034 }
1035 
1036 NS_IMETHODIMP
GetForcePreflight(bool * aForcePreflight)1037 LoadInfo::GetForcePreflight(bool* aForcePreflight) {
1038   *aForcePreflight = mForcePreflight;
1039   return NS_OK;
1040 }
1041 
SetIsPreflight()1042 void LoadInfo::SetIsPreflight() {
1043   MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
1044   MOZ_ASSERT(!mInitialSecurityCheckDone);
1045   mIsPreflight = true;
1046 }
1047 
SetUpgradeInsecureRequests()1048 void LoadInfo::SetUpgradeInsecureRequests() { mUpgradeInsecureRequests = true; }
1049 
SetBrowserUpgradeInsecureRequests()1050 void LoadInfo::SetBrowserUpgradeInsecureRequests() {
1051   mBrowserUpgradeInsecureRequests = true;
1052 }
1053 
1054 NS_IMETHODIMP
GetIsPreflight(bool * aIsPreflight)1055 LoadInfo::GetIsPreflight(bool* aIsPreflight) {
1056   *aIsPreflight = mIsPreflight;
1057   return NS_OK;
1058 }
1059 
1060 NS_IMETHODIMP
SetLoadTriggeredFromExternal(bool aLoadTriggeredFromExternal)1061 LoadInfo::SetLoadTriggeredFromExternal(bool aLoadTriggeredFromExternal) {
1062   MOZ_ASSERT(!aLoadTriggeredFromExternal ||
1063                  mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
1064              "can only set load triggered from external for TYPE_DOCUMENT");
1065   mLoadTriggeredFromExternal = aLoadTriggeredFromExternal;
1066   return NS_OK;
1067 }
1068 
1069 NS_IMETHODIMP
GetLoadTriggeredFromExternal(bool * aLoadTriggeredFromExternal)1070 LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal) {
1071   *aLoadTriggeredFromExternal = mLoadTriggeredFromExternal;
1072   return NS_OK;
1073 }
1074 
1075 NS_IMETHODIMP
GetServiceWorkerTaintingSynthesized(bool * aServiceWorkerTaintingSynthesized)1076 LoadInfo::GetServiceWorkerTaintingSynthesized(
1077     bool* aServiceWorkerTaintingSynthesized) {
1078   MOZ_ASSERT(aServiceWorkerTaintingSynthesized);
1079   *aServiceWorkerTaintingSynthesized = mServiceWorkerTaintingSynthesized;
1080   return NS_OK;
1081 }
1082 
1083 NS_IMETHODIMP
GetTainting(uint32_t * aTaintingOut)1084 LoadInfo::GetTainting(uint32_t* aTaintingOut) {
1085   MOZ_ASSERT(aTaintingOut);
1086   *aTaintingOut = static_cast<uint32_t>(mTainting);
1087   return NS_OK;
1088 }
1089 
1090 NS_IMETHODIMP
MaybeIncreaseTainting(uint32_t aTainting)1091 LoadInfo::MaybeIncreaseTainting(uint32_t aTainting) {
1092   NS_ENSURE_ARG(aTainting <= TAINTING_OPAQUE);
1093 
1094   // Skip if the tainting has been set by the service worker.
1095   if (mServiceWorkerTaintingSynthesized) {
1096     return NS_OK;
1097   }
1098 
1099   LoadTainting tainting = static_cast<LoadTainting>(aTainting);
1100   if (tainting > mTainting) {
1101     mTainting = tainting;
1102   }
1103   return NS_OK;
1104 }
1105 
SynthesizeServiceWorkerTainting(LoadTainting aTainting)1106 void LoadInfo::SynthesizeServiceWorkerTainting(LoadTainting aTainting) {
1107   MOZ_DIAGNOSTIC_ASSERT(aTainting <= LoadTainting::Opaque);
1108   mTainting = aTainting;
1109 
1110   // Flag to prevent the tainting from being increased.
1111   mServiceWorkerTaintingSynthesized = true;
1112 }
1113 
1114 NS_IMETHODIMP
GetIsTopLevelLoad(bool * aResult)1115 LoadInfo::GetIsTopLevelLoad(bool* aResult) {
1116   *aResult = mFrameOuterWindowID ? mFrameOuterWindowID == mOuterWindowID
1117                                  : mParentOuterWindowID == mOuterWindowID;
1118   return NS_OK;
1119 }
1120 
SetIsFromProcessingFrameAttributes()1121 void LoadInfo::SetIsFromProcessingFrameAttributes() {
1122   mIsFromProcessingFrameAttributes = true;
1123 }
1124 
1125 NS_IMETHODIMP
GetIsFromProcessingFrameAttributes(bool * aIsFromProcessingFrameAttributes)1126 LoadInfo::GetIsFromProcessingFrameAttributes(
1127     bool* aIsFromProcessingFrameAttributes) {
1128   MOZ_ASSERT(aIsFromProcessingFrameAttributes);
1129   *aIsFromProcessingFrameAttributes = mIsFromProcessingFrameAttributes;
1130   return NS_OK;
1131 }
1132 
1133 NS_IMETHODIMP
GetResultPrincipalURI(nsIURI ** aURI)1134 LoadInfo::GetResultPrincipalURI(nsIURI** aURI) {
1135   NS_IF_ADDREF(*aURI = mResultPrincipalURI);
1136   return NS_OK;
1137 }
1138 
1139 NS_IMETHODIMP
SetResultPrincipalURI(nsIURI * aURI)1140 LoadInfo::SetResultPrincipalURI(nsIURI* aURI) {
1141   mResultPrincipalURI = aURI;
1142   return NS_OK;
1143 }
1144 
SetClientInfo(const ClientInfo & aClientInfo)1145 void LoadInfo::SetClientInfo(const ClientInfo& aClientInfo) {
1146   mClientInfo.emplace(aClientInfo);
1147 }
1148 
GetClientInfo()1149 const Maybe<ClientInfo>& LoadInfo::GetClientInfo() { return mClientInfo; }
1150 
GiveReservedClientSource(UniquePtr<ClientSource> && aClientSource)1151 void LoadInfo::GiveReservedClientSource(
1152     UniquePtr<ClientSource>&& aClientSource) {
1153   MOZ_DIAGNOSTIC_ASSERT(aClientSource);
1154   mReservedClientSource = Move(aClientSource);
1155   SetReservedClientInfo(mReservedClientSource->Info());
1156 }
1157 
TakeReservedClientSource()1158 UniquePtr<ClientSource> LoadInfo::TakeReservedClientSource() {
1159   if (mReservedClientSource) {
1160     // If the reserved ClientInfo was set due to a ClientSource being present,
1161     // then clear that info object when the ClientSource is taken.
1162     mReservedClientInfo.reset();
1163   }
1164   return Move(mReservedClientSource);
1165 }
1166 
SetReservedClientInfo(const ClientInfo & aClientInfo)1167 void LoadInfo::SetReservedClientInfo(const ClientInfo& aClientInfo) {
1168   MOZ_DIAGNOSTIC_ASSERT(mInitialClientInfo.isNothing());
1169   mReservedClientInfo.emplace(aClientInfo);
1170 }
1171 
GetReservedClientInfo()1172 const Maybe<ClientInfo>& LoadInfo::GetReservedClientInfo() {
1173   return mReservedClientInfo;
1174 }
1175 
SetInitialClientInfo(const ClientInfo & aClientInfo)1176 void LoadInfo::SetInitialClientInfo(const ClientInfo& aClientInfo) {
1177   MOZ_DIAGNOSTIC_ASSERT(!mReservedClientSource);
1178   MOZ_DIAGNOSTIC_ASSERT(mReservedClientInfo.isNothing());
1179   mInitialClientInfo.emplace(aClientInfo);
1180 }
1181 
GetInitialClientInfo()1182 const Maybe<ClientInfo>& LoadInfo::GetInitialClientInfo() {
1183   return mInitialClientInfo;
1184 }
1185 
SetController(const ServiceWorkerDescriptor & aServiceWorker)1186 void LoadInfo::SetController(const ServiceWorkerDescriptor& aServiceWorker) {
1187   mController.emplace(aServiceWorker);
1188 }
1189 
ClearController()1190 void LoadInfo::ClearController() { mController.reset(); }
1191 
GetController()1192 const Maybe<ServiceWorkerDescriptor>& LoadInfo::GetController() {
1193   return mController;
1194 }
1195 
SetPerformanceStorage(PerformanceStorage * aPerformanceStorage)1196 void LoadInfo::SetPerformanceStorage(PerformanceStorage* aPerformanceStorage) {
1197   mPerformanceStorage = aPerformanceStorage;
1198 }
1199 
GetPerformanceStorage()1200 PerformanceStorage* LoadInfo::GetPerformanceStorage() {
1201   return mPerformanceStorage;
1202 }
1203 
1204 }  // namespace net
1205 }  // namespace mozilla
1206