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