Source code

Revision control

Other Tools

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/ExpandedPrincipal.h"
11
#include "mozilla/dom/ClientIPCTypes.h"
12
#include "mozilla/dom/ClientSource.h"
13
#include "mozilla/dom/PerformanceStorage.h"
14
#include "mozilla/dom/BrowserChild.h"
15
#include "mozilla/dom/ToJSValue.h"
16
#include "mozilla/dom/BrowsingContext.h"
17
#include "mozilla/net/CookieSettings.h"
18
#include "mozilla/NullPrincipal.h"
19
#include "mozilla/StaticPrefs.h"
20
#include "mozIThirdPartyUtil.h"
21
#include "nsFrameLoader.h"
22
#include "nsFrameLoaderOwner.h"
23
#include "nsIContentSecurityPolicy.h"
24
#include "nsIDocShell.h"
25
#include "mozilla/dom/Document.h"
26
#include "nsCookiePermission.h"
27
#include "nsICookieService.h"
28
#include "nsIInterfaceRequestorUtils.h"
29
#include "nsISupportsImpl.h"
30
#include "nsISupportsUtils.h"
31
#include "nsIXPConnect.h"
32
#include "nsDocShell.h"
33
#include "nsGlobalWindow.h"
34
#include "nsMixedContentBlocker.h"
35
#include "nsQueryObject.h"
36
#include "nsRedirectHistoryEntry.h"
37
#include "nsSandboxFlags.h"
38
#include "LoadInfo.h"
39
40
using namespace mozilla::dom;
41
42
namespace mozilla {
43
namespace net {
44
45
static uint64_t FindTopOuterWindowID(nsPIDOMWindowOuter* aOuter) {
46
nsCOMPtr<nsPIDOMWindowOuter> outer = aOuter;
47
while (nsCOMPtr<nsPIDOMWindowOuter> parent =
48
outer->GetScriptableParentOrNull()) {
49
outer = parent;
50
}
51
return outer->WindowID();
52
}
53
54
LoadInfo::LoadInfo(
55
nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
56
nsINode* aLoadingContext, nsSecurityFlags aSecurityFlags,
57
nsContentPolicyType aContentPolicyType,
58
const Maybe<mozilla::dom::ClientInfo>& aLoadingClientInfo,
59
const Maybe<mozilla::dom::ServiceWorkerDescriptor>& aController)
60
: mLoadingPrincipal(aLoadingContext ? aLoadingContext->NodePrincipal()
61
: aLoadingPrincipal),
62
mTriggeringPrincipal(aTriggeringPrincipal ? aTriggeringPrincipal
63
: mLoadingPrincipal.get()),
64
mPrincipalToInherit(nullptr),
65
mClientInfo(aLoadingClientInfo),
66
mController(aController),
67
mLoadingContext(do_GetWeakReference(aLoadingContext)),
68
mContextForTopLevelLoad(nullptr),
69
mSecurityFlags(aSecurityFlags),
70
mInternalContentPolicyType(aContentPolicyType),
71
mTainting(LoadTainting::Basic),
72
mUpgradeInsecureRequests(false),
73
mBrowserUpgradeInsecureRequests(false),
74
mBrowserWouldUpgradeInsecureRequests(false),
75
mForceAllowDataURI(false),
76
mAllowInsecureRedirectToDataURI(false),
77
mBypassCORSChecks(false),
78
mSkipContentPolicyCheckForWebRequest(false),
79
mOriginalFrameSrcLoad(false),
80
mForceInheritPrincipalDropped(false),
81
mInnerWindowID(0),
82
mOuterWindowID(0),
83
mParentOuterWindowID(0),
84
mTopOuterWindowID(0),
85
mFrameOuterWindowID(0),
86
mBrowsingContextID(0),
87
mFrameBrowsingContextID(0),
88
mInitialSecurityCheckDone(false),
89
mIsThirdPartyContext(false),
90
mIsDocshellReload(false),
91
mSendCSPViolationEvents(true),
92
mRequestBlockingReason(BLOCKING_REASON_NONE),
93
mForcePreflight(false),
94
mIsPreflight(false),
95
mLoadTriggeredFromExternal(false),
96
mServiceWorkerTaintingSynthesized(false),
97
mDocumentHasUserInteracted(false),
98
mDocumentHasLoaded(false),
99
mIsFromProcessingFrameAttributes(false) {
100
MOZ_ASSERT(mLoadingPrincipal);
101
MOZ_ASSERT(mTriggeringPrincipal);
102
103
#ifdef DEBUG
104
// TYPE_DOCUMENT loads initiated by javascript tests will go through
105
// nsIOService and use the wrong constructor. Don't enforce the
106
// !TYPE_DOCUMENT check in those cases
107
bool skipContentTypeCheck = false;
108
skipContentTypeCheck =
109
Preferences::GetBool("network.loadinfo.skip_type_assertion");
110
#endif
111
112
// This constructor shouldn't be used for TYPE_DOCUMENT loads that don't
113
// have a loadingPrincipal
114
MOZ_ASSERT(skipContentTypeCheck || mLoadingPrincipal ||
115
mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT);
116
117
// We should only get an explicit controller for subresource requests.
118
MOZ_DIAGNOSTIC_ASSERT(aController.isNothing() ||
119
!nsContentUtils::IsNonSubresourceInternalPolicyType(
120
mInternalContentPolicyType));
121
122
// TODO(bug 1259873): Above, we initialize mIsThirdPartyContext to false
123
// meaning that consumers of LoadInfo that don't pass a context or pass a
124
// context from which we can't find a window will default to assuming that
125
// they're 1st party. It would be nice if we could default "safe" and assume
126
// that we are 3rd party until proven otherwise.
127
128
// if consumers pass both, aLoadingContext and aLoadingPrincipal
129
// then the loadingPrincipal must be the same as the node's principal
130
MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal ||
131
aLoadingContext->NodePrincipal() == aLoadingPrincipal);
132
133
// if the load is sandboxed, we can not also inherit the principal
134
if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
135
mForceInheritPrincipalDropped =
136
(mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
137
mSecurityFlags &= ~nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
138
}
139
140
uint32_t externalType =
141
nsContentUtils::InternalContentPolicyTypeToExternal(aContentPolicyType);
142
143
if (aLoadingContext) {
144
// Ensure that all network requests for a window client have the ClientInfo
145
// properly set. Workers must currently pass the loading ClientInfo
146
// explicitly. We allow main thread requests to explicitly pass the value as
147
// well.
148
if (mClientInfo.isNothing()) {
149
mClientInfo = aLoadingContext->OwnerDoc()->GetClientInfo();
150
}
151
152
// For subresource loads set the service worker based on the calling
153
// context's controller. Workers must currently pass the controller in
154
// explicitly. We allow main thread requests to explicitly pass the value
155
// as well, but otherwise extract from the loading context here.
156
if (mController.isNothing() &&
157
!nsContentUtils::IsNonSubresourceInternalPolicyType(
158
mInternalContentPolicyType)) {
159
mController = aLoadingContext->OwnerDoc()->GetController();
160
}
161
162
nsCOMPtr<nsPIDOMWindowOuter> contextOuter =
163
aLoadingContext->OwnerDoc()->GetWindow();
164
if (contextOuter) {
165
ComputeIsThirdPartyContext(contextOuter);
166
mOuterWindowID = contextOuter->WindowID();
167
nsCOMPtr<nsPIDOMWindowOuter> parent = contextOuter->GetScriptableParent();
168
mParentOuterWindowID = parent ? parent->WindowID() : mOuterWindowID;
169
mTopOuterWindowID = FindTopOuterWindowID(contextOuter);
170
RefPtr<dom::BrowsingContext> bc = contextOuter->GetBrowsingContext();
171
mBrowsingContextID = bc ? bc->Id() : 0;
172
173
nsGlobalWindowInner* innerWindow =
174
nsGlobalWindowInner::Cast(contextOuter->GetCurrentInnerWindow());
175
if (innerWindow) {
176
mTopLevelPrincipal = innerWindow->GetTopLevelPrincipal();
177
178
// The top-level-storage-area-principal is not null only for the first
179
// level of iframes (null for top-level contexts, and null for
180
// sub-iframes). If we are loading a sub-document resource, we must
181
// calculate what the top-level-storage-area-principal will be for the
182
// new context.
183
if (externalType != nsIContentPolicy::TYPE_SUBDOCUMENT) {
184
mTopLevelStorageAreaPrincipal =
185
innerWindow->GetTopLevelStorageAreaPrincipal();
186
} else if (contextOuter->IsTopLevelWindow()) {
187
Document* doc = innerWindow->GetExtantDoc();
188
if (!doc || (!doc->StorageAccessSandboxed() &&
189
!nsContentUtils::IsInPrivateBrowsing(doc))) {
190
mTopLevelStorageAreaPrincipal = innerWindow->GetPrincipal();
191
}
192
193
// If this is the first level iframe, innerWindow is our top-level
194
// principal.
195
if (!mTopLevelPrincipal) {
196
mTopLevelPrincipal = innerWindow->GetPrincipal();
197
}
198
}
199
200
mDocumentHasLoaded = innerWindow->IsDocumentLoaded();
201
202
if (innerWindow->IsFrame()) {
203
// For resources within iframes, we actually want the
204
// top-level document's flag, not the iframe document's.
205
mDocumentHasLoaded = false;
206
nsGlobalWindowOuter* topOuter =
207
innerWindow->GetScriptableTopInternal();
208
if (topOuter) {
209
nsGlobalWindowInner* topInner =
210
nsGlobalWindowInner::Cast(topOuter->GetCurrentInnerWindow());
211
if (topInner) {
212
mDocumentHasLoaded = topInner->IsDocumentLoaded();
213
}
214
}
215
}
216
}
217
218
// Let's inherit the cookie behavior and permission from the parent
219
// document.
220
mCookieSettings = aLoadingContext->OwnerDoc()->CookieSettings();
221
}
222
223
mInnerWindowID = aLoadingContext->OwnerDoc()->InnerWindowID();
224
mAncestorPrincipals = aLoadingContext->OwnerDoc()->AncestorPrincipals();
225
mAncestorOuterWindowIDs =
226
aLoadingContext->OwnerDoc()->AncestorOuterWindowIDs();
227
MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() ==
228
mAncestorOuterWindowIDs.Length());
229
mDocumentHasUserInteracted =
230
aLoadingContext->OwnerDoc()->UserHasInteracted();
231
232
// When the element being loaded is a frame, we choose the frame's window
233
// for the window ID and the frame element's window as the parent
234
// window. This is the behavior that Chrome exposes to add-ons.
235
// NB: If the frameLoaderOwner doesn't have a frame loader, then the load
236
// must be coming from an object (such as a plugin) that's loaded into it
237
// instead of a document being loaded. In that case, treat this object like
238
// any other non-document-loading element.
239
RefPtr<nsFrameLoaderOwner> frameLoaderOwner =
240
do_QueryObject(aLoadingContext);
241
RefPtr<nsFrameLoader> fl =
242
frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
243
if (fl) {
244
nsCOMPtr<nsIDocShell> docShell = fl->GetDocShell(IgnoreErrors());
245
if (docShell) {
246
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = do_GetInterface(docShell);
247
if (outerWindow) {
248
mFrameOuterWindowID = outerWindow->WindowID();
249
250
RefPtr<dom::BrowsingContext> bc = outerWindow->GetBrowsingContext();
251
mFrameBrowsingContextID = bc ? bc->Id() : 0;
252
}
253
}
254
}
255
256
// if the document forces all requests to be upgraded from http to https,
257
// then we should do that for all requests. If it only forces preloads to be
258
// upgraded then we should enforce upgrade insecure requests only for
259
// preloads.
260
mUpgradeInsecureRequests =
261
aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(false) ||
262
(nsContentUtils::IsPreloadType(mInternalContentPolicyType) &&
263
aLoadingContext->OwnerDoc()->GetUpgradeInsecureRequests(true));
264
265
if (nsContentUtils::IsUpgradableDisplayType(externalType)) {
266
nsCOMPtr<nsIURI> uri;
267
mLoadingPrincipal->GetURI(getter_AddRefs(uri));
268
if (uri) {
269
// Checking https not secure context as http://localhost can't be
270
// upgraded
271
bool isHttpsScheme;
272
nsresult rv = uri->SchemeIs("https", &isHttpsScheme);
273
if (NS_SUCCEEDED(rv) && isHttpsScheme) {
274
if (nsMixedContentBlocker::ShouldUpgradeMixedDisplayContent()) {
275
mBrowserUpgradeInsecureRequests = true;
276
} else {
277
mBrowserWouldUpgradeInsecureRequests = true;
278
}
279
}
280
}
281
}
282
}
283
284
mOriginAttributes = mLoadingPrincipal->OriginAttributesRef();
285
286
// We need to do this after inheriting the document's origin attributes
287
// above, in case the loading principal ends up being the system principal.
288
if (aLoadingContext) {
289
nsCOMPtr<nsILoadContext> loadContext =
290
aLoadingContext->OwnerDoc()->GetLoadContext();
291
nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
292
if (loadContext && docShell &&
293
docShell->ItemType() == nsIDocShellTreeItem::typeContent) {
294
bool usePrivateBrowsing;
295
nsresult rv = loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing);
296
if (NS_SUCCEEDED(rv)) {
297
mOriginAttributes.SyncAttributesWithPrivateBrowsing(usePrivateBrowsing);
298
}
299
}
300
}
301
302
// For chrome docshell, the mPrivateBrowsingId remains 0 even its
303
// UsePrivateBrowsing() is true, so we only update the mPrivateBrowsingId in
304
// origin attributes if the type of the docshell is content.
305
if (aLoadingContext) {
306
nsCOMPtr<nsIDocShell> docShell = aLoadingContext->OwnerDoc()->GetDocShell();
307
if (docShell) {
308
if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
309
MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
310
"chrome docshell shouldn't have mPrivateBrowsingId set.");
311
}
312
}
313
}
314
}
315
316
/* Constructor takes an outer window, but no loadingNode or loadingPrincipal.
317
* This constructor should only be used for TYPE_DOCUMENT loads, since they
318
* have a null loadingNode and loadingPrincipal.
319
*/
320
LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
321
nsIPrincipal* aTriggeringPrincipal,
322
nsISupports* aContextForTopLevelLoad,
323
nsSecurityFlags aSecurityFlags)
324
: mLoadingPrincipal(nullptr),
325
mTriggeringPrincipal(aTriggeringPrincipal),
326
mPrincipalToInherit(nullptr),
327
mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad)),
328
mSecurityFlags(aSecurityFlags),
329
mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT),
330
mTainting(LoadTainting::Basic),
331
mUpgradeInsecureRequests(false),
332
mBrowserUpgradeInsecureRequests(false),
333
mBrowserWouldUpgradeInsecureRequests(false),
334
mForceAllowDataURI(false),
335
mAllowInsecureRedirectToDataURI(false),
336
mBypassCORSChecks(false),
337
mSkipContentPolicyCheckForWebRequest(false),
338
mOriginalFrameSrcLoad(false),
339
mForceInheritPrincipalDropped(false),
340
mInnerWindowID(0),
341
mOuterWindowID(0),
342
mParentOuterWindowID(0),
343
mTopOuterWindowID(0),
344
mFrameOuterWindowID(0),
345
mBrowsingContextID(0),
346
mFrameBrowsingContextID(0),
347
mInitialSecurityCheckDone(false),
348
mIsThirdPartyContext(false), // NB: TYPE_DOCUMENT implies !third-party.
349
mIsDocshellReload(false),
350
mSendCSPViolationEvents(true),
351
mRequestBlockingReason(BLOCKING_REASON_NONE),
352
mForcePreflight(false),
353
mIsPreflight(false),
354
mLoadTriggeredFromExternal(false),
355
mServiceWorkerTaintingSynthesized(false),
356
mDocumentHasUserInteracted(false),
357
mDocumentHasLoaded(false),
358
mIsFromProcessingFrameAttributes(false) {
359
// Top-level loads are never third-party
360
// Grab the information we can out of the window.
361
MOZ_ASSERT(aOuterWindow);
362
MOZ_ASSERT(mTriggeringPrincipal);
363
364
// if the load is sandboxed, we can not also inherit the principal
365
if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) {
366
mForceInheritPrincipalDropped =
367
(mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
368
mSecurityFlags &= ~nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL;
369
}
370
371
// NB: Ignore the current inner window since we're navigating away from it.
372
mOuterWindowID = aOuterWindow->WindowID();
373
RefPtr<BrowsingContext> bc = aOuterWindow->GetBrowsingContext();
374
mBrowsingContextID = bc ? bc->Id() : 0;
375
376
// TODO We can have a parent without a frame element in some cases dealing
377
// with the hidden window.
378
nsCOMPtr<nsPIDOMWindowOuter> parent = aOuterWindow->GetScriptableParent();
379
mParentOuterWindowID = parent ? parent->WindowID() : 0;
380
mTopOuterWindowID = FindTopOuterWindowID(aOuterWindow);
381
382
nsGlobalWindowInner* innerWindow =
383
nsGlobalWindowInner::Cast(aOuterWindow->GetCurrentInnerWindow());
384
if (innerWindow) {
385
mTopLevelPrincipal = innerWindow->GetTopLevelPrincipal();
386
// mTopLevelStorageAreaPrincipal is always null for top-level document
387
// loading.
388
}
389
390
// get the docshell from the outerwindow, and then get the originattributes
391
nsCOMPtr<nsIDocShell> docShell = aOuterWindow->GetDocShell();
392
MOZ_ASSERT(docShell);
393
mOriginAttributes = nsDocShell::Cast(docShell)->GetOriginAttributes();
394
mAncestorPrincipals = nsDocShell::Cast(docShell)->AncestorPrincipals();
395
mAncestorOuterWindowIDs =
396
nsDocShell::Cast(docShell)->AncestorOuterWindowIDs();
397
MOZ_DIAGNOSTIC_ASSERT(mAncestorPrincipals.Length() ==
398
mAncestorOuterWindowIDs.Length());
399
400
#ifdef DEBUG
401
if (docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
402
MOZ_ASSERT(mOriginAttributes.mPrivateBrowsingId == 0,
403
"chrome docshell shouldn't have mPrivateBrowsingId set.");
404
}
405
#endif
406
407
// Let's take the current cookie behavior and current cookie permission
408
// for the documents' loadInfo. Note that for any other loadInfos,
409
// cookieBehavior will be BEHAVIOR_REJECT for security reasons.
410
mCookieSettings = CookieSettings::Create();
411
}
412
413
LoadInfo::LoadInfo(const LoadInfo& rhs)
414
: mLoadingPrincipal(rhs.mLoadingPrincipal),
415
mTriggeringPrincipal(rhs.mTriggeringPrincipal),
416
mPrincipalToInherit(rhs.mPrincipalToInherit),
417
mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal),
418
mTopLevelPrincipal(rhs.mTopLevelPrincipal),
419
mTopLevelStorageAreaPrincipal(rhs.mTopLevelStorageAreaPrincipal),
420
mResultPrincipalURI(rhs.mResultPrincipalURI),
421
mCookieSettings(rhs.mCookieSettings),
422
mCspToInherit(rhs.mCspToInherit),
423
mClientInfo(rhs.mClientInfo),
424
// mReservedClientSource must be handled specially during redirect
425
// mReservedClientInfo must be handled specially during redirect
426
// mInitialClientInfo must be handled specially during redirect
427
mController(rhs.mController),
428
mPerformanceStorage(rhs.mPerformanceStorage),
429
mLoadingContext(rhs.mLoadingContext),
430
mContextForTopLevelLoad(rhs.mContextForTopLevelLoad),
431
mSecurityFlags(rhs.mSecurityFlags),
432
mInternalContentPolicyType(rhs.mInternalContentPolicyType),
433
mTainting(rhs.mTainting),
434
mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests),
435
mBrowserUpgradeInsecureRequests(rhs.mBrowserUpgradeInsecureRequests),
436
mBrowserWouldUpgradeInsecureRequests(
437
rhs.mBrowserWouldUpgradeInsecureRequests),
438
mForceAllowDataURI(rhs.mForceAllowDataURI),
439
mAllowInsecureRedirectToDataURI(rhs.mAllowInsecureRedirectToDataURI),
440
mBypassCORSChecks(rhs.mBypassCORSChecks),
441
mSkipContentPolicyCheckForWebRequest(
442
rhs.mSkipContentPolicyCheckForWebRequest),
443
mOriginalFrameSrcLoad(rhs.mOriginalFrameSrcLoad),
444
mForceInheritPrincipalDropped(rhs.mForceInheritPrincipalDropped),
445
mInnerWindowID(rhs.mInnerWindowID),
446
mOuterWindowID(rhs.mOuterWindowID),
447
mParentOuterWindowID(rhs.mParentOuterWindowID),
448
mTopOuterWindowID(rhs.mTopOuterWindowID),
449
mFrameOuterWindowID(rhs.mFrameOuterWindowID),
450
mBrowsingContextID(rhs.mBrowsingContextID),
451
mFrameBrowsingContextID(rhs.mFrameBrowsingContextID),
452
mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone),
453
mIsThirdPartyContext(rhs.mIsThirdPartyContext),
454
mIsDocshellReload(rhs.mIsDocshellReload),
455
mSendCSPViolationEvents(rhs.mSendCSPViolationEvents),
456
mOriginAttributes(rhs.mOriginAttributes),
457
mRedirectChainIncludingInternalRedirects(
458
rhs.mRedirectChainIncludingInternalRedirects),
459
mRedirectChain(rhs.mRedirectChain),
460
mAncestorPrincipals(rhs.mAncestorPrincipals),
461
mAncestorOuterWindowIDs(rhs.mAncestorOuterWindowIDs),
462
mCorsUnsafeHeaders(rhs.mCorsUnsafeHeaders),
463
mRequestBlockingReason(rhs.mRequestBlockingReason),
464
mForcePreflight(rhs.mForcePreflight),
465
mIsPreflight(rhs.mIsPreflight),
466
mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal),
467
// mServiceWorkerTaintingSynthesized must be handled specially during
468
// redirect
469
mServiceWorkerTaintingSynthesized(false),
470
mDocumentHasUserInteracted(rhs.mDocumentHasUserInteracted),
471
mDocumentHasLoaded(rhs.mDocumentHasLoaded),
472
mCspNonce(rhs.mCspNonce),
473
mIsFromProcessingFrameAttributes(rhs.mIsFromProcessingFrameAttributes) {}
474
475
LoadInfo::LoadInfo(
476
nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal,
477
nsIPrincipal* aPrincipalToInherit, nsIPrincipal* aSandboxedLoadingPrincipal,
478
nsIPrincipal* aTopLevelPrincipal,
479
nsIPrincipal* aTopLevelStorageAreaPrincipal, nsIURI* aResultPrincipalURI,
480
nsICookieSettings* aCookieSettings, nsIContentSecurityPolicy* aCspToInherit,
481
const Maybe<ClientInfo>& aClientInfo,
482
const Maybe<ClientInfo>& aReservedClientInfo,
483
const Maybe<ClientInfo>& aInitialClientInfo,
484
const Maybe<ServiceWorkerDescriptor>& aController,
485
nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType,
486
LoadTainting aTainting, bool aUpgradeInsecureRequests,
487
bool aBrowserUpgradeInsecureRequests,
488
bool aBrowserWouldUpgradeInsecureRequests, bool aForceAllowDataURI,
489
bool aAllowInsecureRedirectToDataURI, bool aBypassCORSChecks,
490
bool aSkipContentPolicyCheckForWebRequest,
491
bool aForceInheritPrincipalDropped, uint64_t aInnerWindowID,
492
uint64_t aOuterWindowID, uint64_t aParentOuterWindowID,
493
uint64_t aTopOuterWindowID, uint64_t aFrameOuterWindowID,
494
uint64_t aBrowsingContextID, uint64_t aFrameBrowsingContextID,
495
bool aInitialSecurityCheckDone, bool aIsThirdPartyContext,
496
bool aIsDocshellReload, bool aSendCSPViolationEvents,
497
const OriginAttributes& aOriginAttributes,
498
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
499
RedirectHistoryArray& aRedirectChain,
500
nsTArray<nsCOMPtr<nsIPrincipal>>&& aAncestorPrincipals,
501
const nsTArray<uint64_t>& aAncestorOuterWindowIDs,
502
const nsTArray<nsCString>& aCorsUnsafeHeaders, bool aForcePreflight,
503
bool aIsPreflight, bool aLoadTriggeredFromExternal,
504
bool aServiceWorkerTaintingSynthesized, bool aDocumentHasUserInteracted,
505
bool aDocumentHasLoaded, const nsAString& aCspNonce,
506
uint32_t aRequestBlockingReason)
507
: mLoadingPrincipal(aLoadingPrincipal),
508
mTriggeringPrincipal(aTriggeringPrincipal),
509
mPrincipalToInherit(aPrincipalToInherit),
510
mTopLevelPrincipal(aTopLevelPrincipal),
511
mTopLevelStorageAreaPrincipal(aTopLevelStorageAreaPrincipal),
512
mResultPrincipalURI(aResultPrincipalURI),
513
mCookieSettings(aCookieSettings),
514
mCspToInherit(aCspToInherit),
515
mClientInfo(aClientInfo),
516
mReservedClientInfo(aReservedClientInfo),
517
mInitialClientInfo(aInitialClientInfo),
518
mController(aController),
519
mSecurityFlags(aSecurityFlags),
520
mInternalContentPolicyType(aContentPolicyType),
521
mTainting(aTainting),
522
mUpgradeInsecureRequests(aUpgradeInsecureRequests),
523
mBrowserUpgradeInsecureRequests(aBrowserUpgradeInsecureRequests),
524
mBrowserWouldUpgradeInsecureRequests(
525
aBrowserWouldUpgradeInsecureRequests),
526
mForceAllowDataURI(aForceAllowDataURI),
527
mAllowInsecureRedirectToDataURI(aAllowInsecureRedirectToDataURI),
528
mBypassCORSChecks(aBypassCORSChecks),
529
mSkipContentPolicyCheckForWebRequest(
530
aSkipContentPolicyCheckForWebRequest),
531
mOriginalFrameSrcLoad(false),
532
mForceInheritPrincipalDropped(aForceInheritPrincipalDropped),
533
mInnerWindowID(aInnerWindowID),
534
mOuterWindowID(aOuterWindowID),
535
mParentOuterWindowID(aParentOuterWindowID),
536
mTopOuterWindowID(aTopOuterWindowID),
537
mFrameOuterWindowID(aFrameOuterWindowID),
538
mBrowsingContextID(aBrowsingContextID),
539
mFrameBrowsingContextID(aFrameBrowsingContextID),
540
mInitialSecurityCheckDone(aInitialSecurityCheckDone),
541
mIsThirdPartyContext(aIsThirdPartyContext),
542
mIsDocshellReload(aIsDocshellReload),
543
mSendCSPViolationEvents(aSendCSPViolationEvents),
544
mOriginAttributes(aOriginAttributes),
545
mAncestorPrincipals(std::move(aAncestorPrincipals)),
546
mAncestorOuterWindowIDs(aAncestorOuterWindowIDs),
547
mCorsUnsafeHeaders(aCorsUnsafeHeaders),
548
mRequestBlockingReason(aRequestBlockingReason),
549
mForcePreflight(aForcePreflight),
550
mIsPreflight(aIsPreflight),
551
mLoadTriggeredFromExternal(aLoadTriggeredFromExternal),
552
mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized),
553
mDocumentHasUserInteracted(aDocumentHasUserInteracted),
554
mDocumentHasLoaded(aDocumentHasLoaded),
555
mCspNonce(aCspNonce),
556
mIsFromProcessingFrameAttributes(false) {
557
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
558
MOZ_ASSERT(mLoadingPrincipal ||
559
aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
560
MOZ_ASSERT(mTriggeringPrincipal);
561
562
mRedirectChainIncludingInternalRedirects.SwapElements(
563
aRedirectChainIncludingInternalRedirects);
564
565
mRedirectChain.SwapElements(aRedirectChain);
566
}
567
568
void LoadInfo::ComputeIsThirdPartyContext(nsPIDOMWindowOuter* aOuterWindow) {
569
nsContentPolicyType type =
570
nsContentUtils::InternalContentPolicyTypeToExternal(
571
mInternalContentPolicyType);
572
if (type == nsIContentPolicy::TYPE_DOCUMENT) {
573
// Top-level loads are never third-party.
574
mIsThirdPartyContext = false;
575
return;
576
}
577
578
nsCOMPtr<mozIThirdPartyUtil> util(do_GetService(THIRDPARTYUTIL_CONTRACTID));
579
if (NS_WARN_IF(!util)) {
580
return;
581
}
582
583
util->IsThirdPartyWindow(aOuterWindow, nullptr, &mIsThirdPartyContext);
584
}
585
586
NS_IMPL_ISUPPORTS(LoadInfo, nsILoadInfo)
587
588
already_AddRefed<nsILoadInfo> LoadInfo::Clone() const {
589
RefPtr<LoadInfo> copy(new LoadInfo(*this));
590
return copy.forget();
591
}
592
593
already_AddRefed<nsILoadInfo> LoadInfo::CloneWithNewSecFlags(
594
nsSecurityFlags aSecurityFlags) const {
595
RefPtr<LoadInfo> copy(new LoadInfo(*this));
596
copy->mSecurityFlags = aSecurityFlags;
597
return copy.forget();
598
}
599
600
already_AddRefed<nsILoadInfo> LoadInfo::CloneForNewRequest() const {
601
RefPtr<LoadInfo> copy(new LoadInfo(*this));
602
copy->mInitialSecurityCheckDone = false;
603
copy->mRedirectChainIncludingInternalRedirects.Clear();
604
copy->mRedirectChain.Clear();
605
copy->mResultPrincipalURI = nullptr;
606
return copy.forget();
607
}
608
609
NS_IMETHODIMP
610
LoadInfo::GetLoadingPrincipal(nsIPrincipal** aLoadingPrincipal) {
611
NS_IF_ADDREF(*aLoadingPrincipal = mLoadingPrincipal);
612
return NS_OK;
613
}
614
615
nsIPrincipal* LoadInfo::LoadingPrincipal() { return mLoadingPrincipal; }
616
617
NS_IMETHODIMP
618
LoadInfo::GetTriggeringPrincipal(nsIPrincipal** aTriggeringPrincipal) {
619
NS_ADDREF(*aTriggeringPrincipal = mTriggeringPrincipal);
620
return NS_OK;
621
}
622
623
nsIPrincipal* LoadInfo::TriggeringPrincipal() { return mTriggeringPrincipal; }
624
625
NS_IMETHODIMP
626
LoadInfo::GetPrincipalToInherit(nsIPrincipal** aPrincipalToInherit) {
627
NS_IF_ADDREF(*aPrincipalToInherit = mPrincipalToInherit);
628
return NS_OK;
629
}
630
631
NS_IMETHODIMP
632
LoadInfo::SetPrincipalToInherit(nsIPrincipal* aPrincipalToInherit) {
633
MOZ_ASSERT(aPrincipalToInherit, "must be a valid principal to inherit");
634
mPrincipalToInherit = aPrincipalToInherit;
635
return NS_OK;
636
}
637
638
nsIPrincipal* LoadInfo::PrincipalToInherit() { return mPrincipalToInherit; }
639
640
nsIPrincipal* LoadInfo::FindPrincipalToInherit(nsIChannel* aChannel) {
641
if (mPrincipalToInherit) {
642
return mPrincipalToInherit;
643
}
644
645
nsCOMPtr<nsIURI> uri = mResultPrincipalURI;
646
if (!uri) {
647
Unused << aChannel->GetOriginalURI(getter_AddRefs(uri));
648
}
649
650
auto prin = BasePrincipal::Cast(mTriggeringPrincipal);
651
return prin->PrincipalToInherit(uri);
652
}
653
654
nsIPrincipal* LoadInfo::GetSandboxedLoadingPrincipal() {
655
if (!(mSecurityFlags & nsILoadInfo::SEC_SANDBOXED)) {
656
return nullptr;
657
}
658
659
if (!mSandboxedLoadingPrincipal) {
660
if (mLoadingPrincipal) {
661
mSandboxedLoadingPrincipal =
662
NullPrincipal::CreateWithInheritedAttributes(mLoadingPrincipal);
663
} else {
664
OriginAttributes attrs(mOriginAttributes);
665
mSandboxedLoadingPrincipal = NullPrincipal::Create(attrs);
666
}
667
}
668
MOZ_ASSERT(mSandboxedLoadingPrincipal);
669
670
return mSandboxedLoadingPrincipal;
671
}
672
673
nsIPrincipal* LoadInfo::GetTopLevelPrincipal() { return mTopLevelPrincipal; }
674
675
nsIPrincipal* LoadInfo::GetTopLevelStorageAreaPrincipal() {
676
return mTopLevelStorageAreaPrincipal;
677
}
678
679
NS_IMETHODIMP
680
LoadInfo::GetLoadingDocument(Document** aResult) {
681
if (nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext)) {
682
RefPtr<Document> context = node->OwnerDoc();
683
context.forget(aResult);
684
}
685
return NS_OK;
686
}
687
688
nsINode* LoadInfo::LoadingNode() {
689
nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext);
690
return node;
691
}
692
693
already_AddRefed<nsISupports> LoadInfo::ContextForTopLevelLoad() {
694
// Most likely you want to query LoadingNode() instead of
695
// ContextForTopLevelLoad() if this assertion fires.
696
MOZ_ASSERT(mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
697
"should only query this context for top level document loads");
698
nsCOMPtr<nsISupports> context = do_QueryReferent(mContextForTopLevelLoad);
699
return context.forget();
700
}
701
702
already_AddRefed<nsISupports> LoadInfo::GetLoadingContext() {
703
nsCOMPtr<nsISupports> context;
704
if (mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT) {
705
context = ContextForTopLevelLoad();
706
} else {
707
context = LoadingNode();
708
}
709
return context.forget();
710
}
711
712
NS_IMETHODIMP
713
LoadInfo::GetLoadingContextXPCOM(nsISupports** aResult) {
714
nsCOMPtr<nsISupports> context = GetLoadingContext();
715
context.forget(aResult);
716
return NS_OK;
717
}
718
719
NS_IMETHODIMP
720
LoadInfo::GetSecurityFlags(nsSecurityFlags* aResult) {
721
*aResult = mSecurityFlags;
722
return NS_OK;
723
}
724
725
NS_IMETHODIMP
726
LoadInfo::GetSecurityMode(uint32_t* aFlags) {
727
*aFlags =
728
(mSecurityFlags & (nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS |
729
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED |
730
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
731
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL |
732
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS));
733
return NS_OK;
734
}
735
736
NS_IMETHODIMP
737
LoadInfo::GetIsInThirdPartyContext(bool* aIsInThirdPartyContext) {
738
*aIsInThirdPartyContext = mIsThirdPartyContext;
739
return NS_OK;
740
}
741
742
static const uint32_t sCookiePolicyMask =
743
nsILoadInfo::SEC_COOKIES_DEFAULT | nsILoadInfo::SEC_COOKIES_INCLUDE |
744
nsILoadInfo::SEC_COOKIES_SAME_ORIGIN | nsILoadInfo::SEC_COOKIES_OMIT;
745
746
NS_IMETHODIMP
747
LoadInfo::GetCookiePolicy(uint32_t* aResult) {
748
uint32_t policy = mSecurityFlags & sCookiePolicyMask;
749
if (policy == nsILoadInfo::SEC_COOKIES_DEFAULT) {
750
policy = (mSecurityFlags & SEC_REQUIRE_CORS_DATA_INHERITS)
751
? nsILoadInfo::SEC_COOKIES_SAME_ORIGIN
752
: nsILoadInfo::SEC_COOKIES_INCLUDE;
753
}
754
755
*aResult = policy;
756
return NS_OK;
757
}
758
759
namespace {
760
761
already_AddRefed<nsICookieSettings> CreateCookieSettings(
762
nsContentPolicyType aContentPolicyType) {
763
if (StaticPrefs::network_cookieSettings_unblocked_for_testing()) {
764
return CookieSettings::Create();
765
}
766
767
// These contentPolictTypes require a real CookieSettings because favicon and
768
// save-as requests must send cookies. Anything else should not send/receive
769
// cookies.
770
if (aContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON ||
771
aContentPolicyType == nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
772
return CookieSettings::Create();
773
}
774
775
return CookieSettings::CreateBlockingAll();
776
}
777
778
} // namespace
779
780
NS_IMETHODIMP
781
LoadInfo::GetCookieSettings(nsICookieSettings** aCookieSettings) {
782
if (!mCookieSettings) {
783
mCookieSettings = CreateCookieSettings(mInternalContentPolicyType);
784
}
785
786
nsCOMPtr<nsICookieSettings> cookieSettings = mCookieSettings;
787
cookieSettings.forget(aCookieSettings);
788
return NS_OK;
789
}
790
791
NS_IMETHODIMP
792
LoadInfo::SetCookieSettings(nsICookieSettings* aCookieSettings) {
793
MOZ_ASSERT(aCookieSettings);
794
// We allow the overwrite of CookieSettings.
795
mCookieSettings = aCookieSettings;
796
return NS_OK;
797
}
798
799
void LoadInfo::SetIncludeCookiesSecFlag() {
800
MOZ_ASSERT((mSecurityFlags & sCookiePolicyMask) ==
801
nsILoadInfo::SEC_COOKIES_DEFAULT);
802
mSecurityFlags =
803
(mSecurityFlags & ~sCookiePolicyMask) | nsILoadInfo::SEC_COOKIES_INCLUDE;
804
}
805
806
NS_IMETHODIMP
807
LoadInfo::GetForceInheritPrincipal(bool* aInheritPrincipal) {
808
*aInheritPrincipal =
809
(mSecurityFlags & nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL);
810
return NS_OK;
811
}
812
813
NS_IMETHODIMP
814
LoadInfo::GetForceInheritPrincipalOverruleOwner(bool* aInheritPrincipal) {
815
*aInheritPrincipal =
816
(mSecurityFlags &
817
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER);
818
return NS_OK;
819
}
820
821
NS_IMETHODIMP
822
LoadInfo::GetLoadingSandboxed(bool* aLoadingSandboxed) {
823
*aLoadingSandboxed = (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED);
824
return NS_OK;
825
}
826
827
NS_IMETHODIMP
828
LoadInfo::GetAboutBlankInherits(bool* aResult) {
829
*aResult = (mSecurityFlags & nsILoadInfo::SEC_ABOUT_BLANK_INHERITS);
830
return NS_OK;
831
}
832
833
NS_IMETHODIMP
834
LoadInfo::GetAllowChrome(bool* aResult) {
835
*aResult = (mSecurityFlags & nsILoadInfo::SEC_ALLOW_CHROME);
836
return NS_OK;
837
}
838
839
NS_IMETHODIMP
840
LoadInfo::GetDisallowScript(bool* aResult) {
841
*aResult = (mSecurityFlags & nsILoadInfo::SEC_DISALLOW_SCRIPT);
842
return NS_OK;
843
}
844
845
NS_IMETHODIMP
846
LoadInfo::GetDontFollowRedirects(bool* aResult) {
847
*aResult = (mSecurityFlags & nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS);
848
return NS_OK;
849
}
850
851
NS_IMETHODIMP
852
LoadInfo::GetLoadErrorPage(bool* aResult) {
853
*aResult = (mSecurityFlags & nsILoadInfo::SEC_LOAD_ERROR_PAGE);
854
return NS_OK;
855
}
856
857
NS_IMETHODIMP
858
LoadInfo::GetIsDocshellReload(bool* aResult) {
859
*aResult = mIsDocshellReload;
860
return NS_OK;
861
}
862
863
NS_IMETHODIMP
864
LoadInfo::SetIsDocshellReload(bool aValue) {
865
mIsDocshellReload = aValue;
866
return NS_OK;
867
}
868
869
NS_IMETHODIMP
870
LoadInfo::GetSendCSPViolationEvents(bool* aResult) {
871
*aResult = mSendCSPViolationEvents;
872
return NS_OK;
873
}
874
875
NS_IMETHODIMP
876
LoadInfo::SetSendCSPViolationEvents(bool aValue) {
877
mSendCSPViolationEvents = aValue;
878
return NS_OK;
879
}
880
881
NS_IMETHODIMP
882
LoadInfo::GetExternalContentPolicyType(nsContentPolicyType* aResult) {
883
*aResult = nsContentUtils::InternalContentPolicyTypeToExternal(
884
mInternalContentPolicyType);
885
return NS_OK;
886
}
887
888
nsContentPolicyType LoadInfo::InternalContentPolicyType() {
889
return mInternalContentPolicyType;
890
}
891
892
NS_IMETHODIMP
893
LoadInfo::GetUpgradeInsecureRequests(bool* aResult) {
894
*aResult = mUpgradeInsecureRequests;
895
return NS_OK;
896
}
897
898
NS_IMETHODIMP
899
LoadInfo::GetBrowserUpgradeInsecureRequests(bool* aResult) {
900
*aResult = mBrowserUpgradeInsecureRequests;
901
return NS_OK;
902
}
903
904
NS_IMETHODIMP
905
LoadInfo::GetBrowserWouldUpgradeInsecureRequests(bool* aResult) {
906
*aResult = mBrowserWouldUpgradeInsecureRequests;
907
return NS_OK;
908
}
909
910
NS_IMETHODIMP
911
LoadInfo::SetForceAllowDataURI(bool aForceAllowDataURI) {
912
MOZ_ASSERT(!mForceAllowDataURI ||
913
mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
914
"can only allow data URI navigation for TYPE_DOCUMENT");
915
mForceAllowDataURI = aForceAllowDataURI;
916
return NS_OK;
917
}
918
919
NS_IMETHODIMP
920
LoadInfo::GetForceAllowDataURI(bool* aForceAllowDataURI) {
921
*aForceAllowDataURI = mForceAllowDataURI;
922
return NS_OK;
923
}
924
925
NS_IMETHODIMP
926
LoadInfo::SetAllowInsecureRedirectToDataURI(
927
bool aAllowInsecureRedirectToDataURI) {
928
mAllowInsecureRedirectToDataURI = aAllowInsecureRedirectToDataURI;
929
return NS_OK;
930
}
931
932
NS_IMETHODIMP
933
LoadInfo::GetAllowInsecureRedirectToDataURI(
934
bool* aAllowInsecureRedirectToDataURI) {
935
*aAllowInsecureRedirectToDataURI = mAllowInsecureRedirectToDataURI;
936
return NS_OK;
937
}
938
939
NS_IMETHODIMP
940
LoadInfo::SetBypassCORSChecks(bool aBypassCORSChecks) {
941
mBypassCORSChecks = aBypassCORSChecks;
942
return NS_OK;
943
}
944
945
NS_IMETHODIMP
946
LoadInfo::GetBypassCORSChecks(bool* aBypassCORSChecks) {
947
*aBypassCORSChecks = mBypassCORSChecks;
948
return NS_OK;
949
}
950
951
NS_IMETHODIMP
952
LoadInfo::SetSkipContentPolicyCheckForWebRequest(bool aSkip) {
953
mSkipContentPolicyCheckForWebRequest = aSkip;
954
return NS_OK;
955
}
956
957
NS_IMETHODIMP
958
LoadInfo::GetSkipContentPolicyCheckForWebRequest(bool* aSkip) {
959
*aSkip = mSkipContentPolicyCheckForWebRequest;
960
return NS_OK;
961
}
962
963
NS_IMETHODIMP
964
LoadInfo::SetOriginalFrameSrcLoad(bool aOriginalFrameSrcLoad) {
965
mOriginalFrameSrcLoad = aOriginalFrameSrcLoad;
966
return NS_OK;
967
}
968
969
NS_IMETHODIMP
970
LoadInfo::GetOriginalFrameSrcLoad(bool* aOriginalFrameSrcLoad) {
971
*aOriginalFrameSrcLoad = mOriginalFrameSrcLoad;
972
return NS_OK;
973
}
974
975
NS_IMETHODIMP
976
LoadInfo::GetForceInheritPrincipalDropped(bool* aResult) {
977
*aResult = mForceInheritPrincipalDropped;
978
return NS_OK;
979
}
980
981
NS_IMETHODIMP
982
LoadInfo::GetInnerWindowID(uint64_t* aResult) {
983
*aResult = mInnerWindowID;
984
return NS_OK;
985
}
986
987
NS_IMETHODIMP
988
LoadInfo::GetOuterWindowID(uint64_t* aResult) {
989
*aResult = mOuterWindowID;
990
return NS_OK;
991
}
992
993
NS_IMETHODIMP
994
LoadInfo::GetParentOuterWindowID(uint64_t* aResult) {
995
*aResult = mParentOuterWindowID;
996
return NS_OK;
997
}
998
999
NS_IMETHODIMP
1000
LoadInfo::GetTopOuterWindowID(uint64_t* aResult) {
1001
*aResult = mTopOuterWindowID;
1002
return NS_OK;
1003
}
1004
1005
NS_IMETHODIMP
1006
LoadInfo::GetFrameOuterWindowID(uint64_t* aResult) {
1007
*aResult = mFrameOuterWindowID;
1008
return NS_OK;
1009
}
1010
1011
NS_IMETHODIMP
1012
LoadInfo::GetBrowsingContextID(uint64_t* aResult) {
1013
*aResult = mBrowsingContextID;
1014
return NS_OK;
1015
}
1016
1017
NS_IMETHODIMP
1018
LoadInfo::GetFrameBrowsingContextID(uint64_t* aResult) {
1019
*aResult = mFrameBrowsingContextID;
1020
return NS_OK;
1021
}
1022
1023
NS_IMETHODIMP
1024
LoadInfo::GetBrowsingContext(dom::BrowsingContext** aResult) {
1025
*aResult = BrowsingContext::Get(mBrowsingContextID).take();
1026
return NS_OK;
1027
}
1028
1029
NS_IMETHODIMP
1030
LoadInfo::GetFrameBrowsingContext(dom::BrowsingContext** aResult) {
1031
*aResult = BrowsingContext::Get(mFrameBrowsingContextID).take();
1032
return NS_OK;
1033
}
1034
1035
NS_IMETHODIMP
1036
LoadInfo::GetScriptableOriginAttributes(
1037
JSContext* aCx, JS::MutableHandle<JS::Value> aOriginAttributes) {
1038
if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aOriginAttributes))) {
1039
return NS_ERROR_FAILURE;
1040
}
1041
return NS_OK;
1042
}
1043
1044
NS_IMETHODIMP
1045
LoadInfo::ResetPrincipalToInheritToNullPrincipal() {
1046
// take the originAttributes from the LoadInfo and create
1047
// a new NullPrincipal using those origin attributes.
1048
nsCOMPtr<nsIPrincipal> newNullPrincipal =
1049
NullPrincipal::Create(mOriginAttributes);
1050
1051
mPrincipalToInherit = newNullPrincipal;
1052
1053
// setting SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER will overrule
1054
// any non null owner set on the channel and will return the principal
1055
// form the loadinfo instead.
1056
mSecurityFlags |= SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER;
1057
1058
return NS_OK;
1059
}
1060
1061
NS_IMETHODIMP
1062
LoadInfo::SetScriptableOriginAttributes(
1063
JSContext* aCx, JS::Handle<JS::Value> aOriginAttributes) {
1064
OriginAttributes attrs;
1065
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
1066
return NS_ERROR_INVALID_ARG;
1067
}
1068
1069
mOriginAttributes = attrs;
1070
return NS_OK;
1071
}
1072
1073
nsresult LoadInfo::GetOriginAttributes(
1074
mozilla::OriginAttributes* aOriginAttributes) {
1075
NS_ENSURE_ARG(aOriginAttributes);
1076
*aOriginAttributes = mOriginAttributes;
1077
return NS_OK;
1078
}
1079
1080
nsresult LoadInfo::SetOriginAttributes(
1081
const mozilla::OriginAttributes& aOriginAttributes) {
1082
mOriginAttributes = aOriginAttributes;
1083
return NS_OK;
1084
}
1085
1086
NS_IMETHODIMP
1087
LoadInfo::SetInitialSecurityCheckDone(bool aInitialSecurityCheckDone) {
1088
// Indicates whether the channel was ever evaluated by the
1089
// ContentSecurityManager. Once set to true, this flag must
1090
// remain true throughout the lifetime of the channel.
1091
// Setting it to anything else than true will be discarded.
1092
MOZ_ASSERT(aInitialSecurityCheckDone,
1093
"aInitialSecurityCheckDone must be true");
1094
mInitialSecurityCheckDone =
1095
mInitialSecurityCheckDone || aInitialSecurityCheckDone;
1096
return NS_OK;
1097
}
1098
1099
NS_IMETHODIMP
1100
LoadInfo::GetInitialSecurityCheckDone(bool* aResult) {
1101
*aResult = mInitialSecurityCheckDone;
1102
return NS_OK;
1103
}
1104
1105
NS_IMETHODIMP
1106
LoadInfo::AppendRedirectHistoryEntry(nsIRedirectHistoryEntry* aEntry,
1107
bool aIsInternalRedirect) {
1108
NS_ENSURE_ARG(aEntry);
1109
MOZ_ASSERT(NS_IsMainThread());
1110
1111
mRedirectChainIncludingInternalRedirects.AppendElement(aEntry);
1112
if (!aIsInternalRedirect) {
1113
mRedirectChain.AppendElement(aEntry);
1114
}
1115
return NS_OK;
1116
}
1117
1118
NS_IMETHODIMP
1119
LoadInfo::GetRedirects(JSContext* aCx, JS::MutableHandle<JS::Value> aRedirects,
1120
const RedirectHistoryArray& aArray) {
1121
JS::Rooted<JSObject*> redirects(aCx, JS_NewArrayObject(aCx, aArray.Length()));
1122
NS_ENSURE_TRUE(redirects, NS_ERROR_OUT_OF_MEMORY);
1123
1124
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
1125
NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
1126
1127
nsCOMPtr<nsIXPConnect> xpc = nsIXPConnect::XPConnect();
1128
1129
for (size_t idx = 0; idx < aArray.Length(); idx++) {
1130
JS::RootedObject jsobj(aCx);
1131
nsresult rv =
1132
xpc->WrapNative(aCx, global, aArray[idx],
1133
NS_GET_IID(nsIRedirectHistoryEntry), jsobj.address());
1134
NS_ENSURE_SUCCESS(rv, rv);
1135
NS_ENSURE_STATE(jsobj);
1136
1137
bool rc = JS_DefineElement(aCx, redirects, idx, jsobj, JSPROP_ENUMERATE);
1138
NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
1139
}
1140
1141
aRedirects.setObject(*redirects);
1142
return NS_OK;
1143
}
1144
1145
NS_IMETHODIMP
1146
LoadInfo::GetRedirectChainIncludingInternalRedirects(
1147
JSContext* aCx, JS::MutableHandle<JS::Value> aChain) {
1148
return GetRedirects(aCx, aChain, mRedirectChainIncludingInternalRedirects);
1149
}
1150
1151
const RedirectHistoryArray&
1152
LoadInfo::RedirectChainIncludingInternalRedirects() {
1153
return mRedirectChainIncludingInternalRedirects;
1154
}
1155
1156
NS_IMETHODIMP
1157
LoadInfo::GetRedirectChain(JSContext* aCx,
1158
JS::MutableHandle<JS::Value> aChain) {
1159
return GetRedirects(aCx, aChain, mRedirectChain);
1160
}
1161
1162
const RedirectHistoryArray& LoadInfo::RedirectChain() { return mRedirectChain; }
1163
1164
const nsTArray<nsCOMPtr<nsIPrincipal>>& LoadInfo::AncestorPrincipals() {
1165
return mAncestorPrincipals;
1166
}
1167
1168
const nsTArray<uint64_t>& LoadInfo::AncestorOuterWindowIDs() {
1169
return mAncestorOuterWindowIDs;
1170
}
1171
1172
void LoadInfo::SetCorsPreflightInfo(const nsTArray<nsCString>& aHeaders,
1173
bool aForcePreflight) {
1174
MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
1175
MOZ_ASSERT(!mInitialSecurityCheckDone);
1176
mCorsUnsafeHeaders = aHeaders;
1177
mForcePreflight = aForcePreflight;
1178
}
1179
1180
const nsTArray<nsCString>& LoadInfo::CorsUnsafeHeaders() {
1181
return mCorsUnsafeHeaders;
1182
}
1183
1184
NS_IMETHODIMP
1185
LoadInfo::GetForcePreflight(bool* aForcePreflight) {
1186
*aForcePreflight = mForcePreflight;
1187
return NS_OK;
1188
}
1189
1190
void LoadInfo::SetIsPreflight() {
1191
MOZ_ASSERT(GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS);
1192
MOZ_ASSERT(!mInitialSecurityCheckDone);
1193
mIsPreflight = true;
1194
}
1195
1196
void LoadInfo::SetUpgradeInsecureRequests() { mUpgradeInsecureRequests = true; }
1197
1198
void LoadInfo::SetBrowserUpgradeInsecureRequests() {
1199
mBrowserUpgradeInsecureRequests = true;
1200
}
1201
1202
void LoadInfo::SetBrowserWouldUpgradeInsecureRequests() {
1203
mBrowserWouldUpgradeInsecureRequests = true;
1204
}
1205
1206
NS_IMETHODIMP
1207
LoadInfo::GetIsPreflight(bool* aIsPreflight) {
1208
*aIsPreflight = mIsPreflight;
1209
return NS_OK;
1210
}
1211
1212
NS_IMETHODIMP
1213
LoadInfo::SetLoadTriggeredFromExternal(bool aLoadTriggeredFromExternal) {
1214
MOZ_ASSERT(!aLoadTriggeredFromExternal ||
1215
mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
1216
"can only set load triggered from external for TYPE_DOCUMENT");
1217
mLoadTriggeredFromExternal = aLoadTriggeredFromExternal;
1218
return NS_OK;
1219
}
1220
1221
NS_IMETHODIMP
1222
LoadInfo::GetLoadTriggeredFromExternal(bool* aLoadTriggeredFromExternal) {
1223
*aLoadTriggeredFromExternal = mLoadTriggeredFromExternal;
1224
return NS_OK;
1225
}
1226
1227
NS_IMETHODIMP
1228
LoadInfo::GetServiceWorkerTaintingSynthesized(
1229
bool* aServiceWorkerTaintingSynthesized) {
1230
MOZ_ASSERT(aServiceWorkerTaintingSynthesized);
1231
*aServiceWorkerTaintingSynthesized = mServiceWorkerTaintingSynthesized;
1232
return NS_OK;
1233
}
1234
1235
NS_IMETHODIMP
1236
LoadInfo::GetTainting(uint32_t* aTaintingOut) {
1237
MOZ_ASSERT(aTaintingOut);
1238
*aTaintingOut = static_cast<uint32_t>(mTainting);
1239
return NS_OK;
1240
}
1241
1242
NS_IMETHODIMP
1243
LoadInfo::MaybeIncreaseTainting(uint32_t aTainting) {
1244
NS_ENSURE_ARG(aTainting <= TAINTING_OPAQUE);
1245
1246
// Skip if the tainting has been set by the service worker.
1247
if (mServiceWorkerTaintingSynthesized) {
1248
return NS_OK;
1249
}
1250
1251
LoadTainting tainting = static_cast<LoadTainting>(aTainting);
1252
if (tainting > mTainting) {
1253
mTainting = tainting;
1254
}
1255
return NS_OK;
1256
}
1257
1258
void LoadInfo::SynthesizeServiceWorkerTainting(LoadTainting aTainting) {
1259
MOZ_DIAGNOSTIC_ASSERT(aTainting <= LoadTainting::Opaque);
1260
mTainting = aTainting;
1261
1262
// Flag to prevent the tainting from being increased.
1263
mServiceWorkerTaintingSynthesized = true;
1264
}
1265
1266
NS_IMETHODIMP
1267
LoadInfo::GetDocumentHasUserInteracted(bool* aDocumentHasUserInteracted) {
1268
MOZ_ASSERT(aDocumentHasUserInteracted);
1269
*aDocumentHasUserInteracted = mDocumentHasUserInteracted;
1270
return NS_OK;
1271
}
1272
1273
NS_IMETHODIMP
1274
LoadInfo::SetDocumentHasUserInteracted(bool aDocumentHasUserInteracted) {
1275
mDocumentHasUserInteracted = aDocumentHasUserInteracted;
1276
return NS_OK;
1277
}
1278
1279
NS_IMETHODIMP
1280
LoadInfo::GetDocumentHasLoaded(bool* aDocumentHasLoaded) {
1281
MOZ_ASSERT(aDocumentHasLoaded);
1282
*aDocumentHasLoaded = mDocumentHasLoaded;
1283
return NS_OK;
1284
}
1285
1286
NS_IMETHODIMP
1287
LoadInfo::SetDocumentHasLoaded(bool aDocumentHasLoaded) {
1288
mDocumentHasLoaded = aDocumentHasLoaded;
1289
return NS_OK;
1290
}
1291
1292
NS_IMETHODIMP
1293
LoadInfo::GetCspNonce(nsAString& aCspNonce) {
1294
aCspNonce = mCspNonce;
1295
return NS_OK;
1296
}
1297
1298
NS_IMETHODIMP
1299
LoadInfo::SetCspNonce(const nsAString& aCspNonce) {
1300
MOZ_ASSERT(!mInitialSecurityCheckDone,
1301
"setting the nonce is only allowed before any sec checks");
1302
mCspNonce = aCspNonce;
1303
return NS_OK;
1304
}
1305
1306
NS_IMETHODIMP
1307
LoadInfo::GetIsTopLevelLoad(bool* aResult) {
1308
*aResult = mFrameOuterWindowID ? mFrameOuterWindowID == mOuterWindowID
1309
: mParentOuterWindowID == mOuterWindowID;
1310
return NS_OK;
1311
}
1312
1313
void LoadInfo::SetIsFromProcessingFrameAttributes() {
1314
mIsFromProcessingFrameAttributes = true;
1315
}
1316
1317
NS_IMETHODIMP
1318
LoadInfo::GetIsFromProcessingFrameAttributes(
1319
bool* aIsFromProcessingFrameAttributes) {
1320
MOZ_ASSERT(aIsFromProcessingFrameAttributes);
1321
*aIsFromProcessingFrameAttributes = mIsFromProcessingFrameAttributes;
1322
return NS_OK;
1323
}
1324
1325
NS_IMETHODIMP
1326
LoadInfo::GetResultPrincipalURI(nsIURI** aURI) {
1327
NS_IF_ADDREF(*aURI = mResultPrincipalURI);
1328
return NS_OK;
1329
}
1330
1331
NS_IMETHODIMP
1332
LoadInfo::SetResultPrincipalURI(nsIURI* aURI) {
1333
mResultPrincipalURI = aURI;
1334
return NS_OK;
1335
}
1336
1337
NS_IMETHODIMP
1338
LoadInfo::SetRequestBlockingReason(uint32_t aReason) {
1339
mRequestBlockingReason = aReason;
1340
return NS_OK;
1341
}
1342
NS_IMETHODIMP
1343
LoadInfo::GetRequestBlockingReason(uint32_t* aReason) {
1344
*aReason = mRequestBlockingReason;
1345
return NS_OK;
1346
}
1347
1348
void LoadInfo::SetClientInfo(const ClientInfo& aClientInfo) {
1349
mClientInfo.emplace(aClientInfo);
1350
}
1351
1352
const Maybe<ClientInfo>& LoadInfo::GetClientInfo() { return mClientInfo; }
1353
1354
void LoadInfo::GiveReservedClientSource(
1355
UniquePtr<ClientSource>&& aClientSource) {
1356
MOZ_DIAGNOSTIC_ASSERT(aClientSource);
1357
mReservedClientSource = std::move(aClientSource);
1358
SetReservedClientInfo(mReservedClientSource->Info());
1359
}
1360
1361
UniquePtr<ClientSource> LoadInfo::TakeReservedClientSource() {
1362
if (mReservedClientSource) {
1363
// If the reserved ClientInfo was set due to a ClientSource being present,
1364
// then clear that info object when the ClientSource is taken.
1365
mReservedClientInfo.reset();
1366
}
1367
return std::move(mReservedClientSource);
1368
}
1369
1370
void LoadInfo::SetReservedClientInfo(const ClientInfo& aClientInfo) {
1371
MOZ_DIAGNOSTIC_ASSERT(mInitialClientInfo.isNothing());
1372
// Treat assignments of the same value as a no-op. The emplace below
1373
// will normally assert when overwriting an existing value.
1374
if (mReservedClientInfo.isSome() &&
1375
mReservedClientInfo.ref() == aClientInfo) {
1376
return;
1377
}
1378
mReservedClientInfo.emplace(aClientInfo);
1379
}
1380
1381
void LoadInfo::OverrideReservedClientInfoInParent(
1382
const ClientInfo& aClientInfo) {
1383
// This should only be called to handle redirects in the parent process.
1384
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
1385
1386
mInitialClientInfo.reset();
1387
mReservedClientInfo.reset();
1388
mReservedClientInfo.emplace(aClientInfo);
1389
}
1390
1391
const Maybe<ClientInfo>& LoadInfo::GetReservedClientInfo() {
1392
return mReservedClientInfo;
1393
}
1394
1395
void LoadInfo::SetInitialClientInfo(const ClientInfo& aClientInfo) {
1396
MOZ_DIAGNOSTIC_ASSERT(!mReservedClientSource);
1397
MOZ_DIAGNOSTIC_ASSERT(mReservedClientInfo.isNothing());
1398
// Treat assignments of the same value as a no-op. The emplace below
1399
// will normally assert when overwriting an existing value.
1400
if (mInitialClientInfo.isSome() && mInitialClientInfo.ref() == aClientInfo) {
1401
return;
1402
}
1403
mInitialClientInfo.emplace(aClientInfo);
1404
}
1405
1406
const Maybe<ClientInfo>& LoadInfo::GetInitialClientInfo() {
1407
return mInitialClientInfo;
1408
}
1409
1410
void LoadInfo::SetController(const ServiceWorkerDescriptor& aServiceWorker) {
1411
mController.emplace(aServiceWorker);
1412
}
1413
1414
void LoadInfo::ClearController() { mController.reset(); }
1415
1416
const Maybe<ServiceWorkerDescriptor>& LoadInfo::GetController() {
1417
return mController;
1418
}
1419
1420
void LoadInfo::SetPerformanceStorage(PerformanceStorage* aPerformanceStorage) {
1421
mPerformanceStorage = aPerformanceStorage;
1422
}
1423
1424
PerformanceStorage* LoadInfo::GetPerformanceStorage() {
1425
return mPerformanceStorage;
1426
}
1427
1428
NS_IMETHODIMP
1429
LoadInfo::GetCspEventListener(nsICSPEventListener** aCSPEventListener) {
1430
NS_IF_ADDREF(*aCSPEventListener = mCSPEventListener);
1431
return NS_OK;
1432
}
1433
1434
NS_IMETHODIMP
1435
LoadInfo::SetCspEventListener(nsICSPEventListener* aCSPEventListener) {
1436
mCSPEventListener = aCSPEventListener;
1437
return NS_OK;
1438
}
1439
1440
already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCsp() {
1441
// Before querying the CSP from the client we have to check if the
1442
// triggeringPrincipal originates from an addon and potentially
1443
// overrides the CSP stored within the client.
1444
if (mLoadingPrincipal && BasePrincipal::Cast(mTriggeringPrincipal)
1445
->OverridesCSP(mLoadingPrincipal)) {
1446
nsCOMPtr<nsIExpandedPrincipal> ep = do_QueryInterface(mTriggeringPrincipal);
1447
nsCOMPtr<nsIContentSecurityPolicy> addonCSP;
1448
if (ep) {
1449
addonCSP = ep->GetCsp();
1450
}
1451
return addonCSP.forget();
1452
}
1453
1454
if (mClientInfo.isNothing()) {
1455
return nullptr;
1456
}
1457
1458
nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext);
1459
RefPtr<Document> doc = node ? node->OwnerDoc() : nullptr;
1460
1461
// If the client is of type window, then we return the cached CSP
1462
// stored on the document instead of having to deserialize the CSP
1463
// from the ClientInfo.
1464
if (doc && mClientInfo->Type() == ClientType::Window) {
1465
nsCOMPtr<nsIContentSecurityPolicy> docCSP = doc->GetCsp();
1466
return docCSP.forget();
1467
}
1468
1469
Maybe<mozilla::ipc::CSPInfo> cspInfo = mClientInfo->GetCspInfo();
1470
if (cspInfo.isNothing()) {
1471
return nullptr;
1472
}
1473
nsCOMPtr<nsIContentSecurityPolicy> clientCSP =
1474
CSPInfoToCSP(cspInfo.ref(), doc);
1475
return clientCSP.forget();
1476
}
1477
1478
already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetPreloadCsp() {
1479
if (mClientInfo.isNothing()) {
1480
return nullptr;
1481
}
1482
1483
nsCOMPtr<nsINode> node = do_QueryReferent(mLoadingContext);
1484
RefPtr<Document> doc = node ? node->OwnerDoc() : nullptr;
1485
1486
// If the client is of type window, then we return the cached CSP
1487
// stored on the document instead of having to deserialize the CSP
1488
// from the ClientInfo.
1489
if (doc && mClientInfo->Type() == ClientType::Window) {
1490
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp = doc->GetPreloadCsp();
1491
return preloadCsp.forget();
1492
}
1493
1494
Maybe<mozilla::ipc::CSPInfo> cspInfo = mClientInfo->GetPreloadCspInfo();
1495
if (cspInfo.isNothing()) {
1496
return nullptr;
1497
}
1498
nsCOMPtr<nsIContentSecurityPolicy> preloadCSP =
1499
CSPInfoToCSP(cspInfo.ref(), doc);
1500
return preloadCSP.forget();
1501
}
1502
1503
already_AddRefed<nsIContentSecurityPolicy> LoadInfo::GetCspToInherit() {
1504
nsCOMPtr<nsIContentSecurityPolicy> cspToInherit = mCspToInherit;
1505
return cspToInherit.forget();
1506
}
1507
1508
} // namespace net
1509
} // namespace mozilla