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 "nsArray.h"
8
#include "nsContentSecurityManager.h"
9
#include "nsEscape.h"
10
#include "nsDataHandler.h"
11
#include "nsIChannel.h"
12
#include "nsIHttpChannelInternal.h"
13
#include "nsINode.h"
14
#include "nsIStreamListener.h"
15
#include "nsILoadInfo.h"
16
#include "nsIOService.h"
17
#include "nsContentUtils.h"
18
#include "nsCORSListenerProxy.h"
19
#include "nsIStreamListener.h"
20
#include "nsIRedirectHistoryEntry.h"
21
#include "nsReadableUtils.h"
22
23
#include "mozilla/BasePrincipal.h"
24
#include "mozilla/ClearOnShutdown.h"
25
#include "mozilla/dom/Element.h"
26
#include "mozilla/dom/nsMixedContentBlocker.h"
27
#include "mozilla/dom/BrowserChild.h"
28
#include "mozilla/Components.h"
29
#include "mozilla/Logging.h"
30
#include "mozilla/StaticPrefs_dom.h"
31
#include "mozilla/Telemetry.h"
32
#include "mozilla/TelemetryComms.h"
33
#include "xpcpublic.h"
34
35
#include "jsapi.h"
36
#include "js/RegExp.h"
37
38
using namespace mozilla::Telemetry;
39
40
NS_IMPL_ISUPPORTS(nsContentSecurityManager, nsIContentSecurityManager,
41
nsIChannelEventSink)
42
43
static mozilla::LazyLogModule sCSMLog("CSMLog");
44
45
static Atomic<bool, mozilla::Relaxed> sTelemetryEventEnabled(false);
46
47
/* static */
48
bool nsContentSecurityManager::AllowTopLevelNavigationToDataURI(
49
nsIChannel* aChannel) {
50
// Let's block all toplevel document navigations to a data: URI.
51
// In all cases where the toplevel document is navigated to a
52
// data: URI the triggeringPrincipal is a contentPrincipal, or
53
// a NullPrincipal. In other cases, e.g. typing a data: URL into
54
// the URL-Bar, the triggeringPrincipal is a SystemPrincipal;
55
// we don't want to block those loads. Only exception, loads coming
56
// from an external applicaton (e.g. Thunderbird) don't load
57
// using a contentPrincipal, but we want to block those loads.
58
if (!mozilla::net::nsIOService::BlockToplevelDataUriNavigations()) {
59
return true;
60
}
61
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
62
if (loadInfo->GetExternalContentPolicyType() !=
63
nsIContentPolicy::TYPE_DOCUMENT) {
64
return true;
65
}
66
if (loadInfo->GetForceAllowDataURI()) {
67
// if the loadinfo explicitly allows the data URI navigation, let's allow it
68
// now
69
return true;
70
}
71
nsCOMPtr<nsIURI> uri;
72
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
73
NS_ENSURE_SUCCESS(rv, true);
74
bool isDataURI = uri->SchemeIs("data");
75
if (!isDataURI) {
76
return true;
77
}
78
79
nsAutoCString spec;
80
rv = uri->GetSpec(spec);
81
NS_ENSURE_SUCCESS(rv, true);
82
nsAutoCString contentType;
83
bool base64;
84
rv = nsDataHandler::ParseURI(spec, contentType, nullptr, base64, nullptr);
85
NS_ENSURE_SUCCESS(rv, true);
86
87
// Whitelist data: images as long as they are not SVGs
88
if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/")) &&
89
!contentType.EqualsLiteral("image/svg+xml")) {
90
return true;
91
}
92
// Whitelist all plain text types as well as data: PDFs.
93
if (nsContentUtils::IsPlainTextType(contentType) ||
94
contentType.EqualsLiteral("application/pdf")) {
95
return true;
96
}
97
// Redirecting to a toplevel data: URI is not allowed, hence we make
98
// sure the RedirectChain is empty.
99
if (!loadInfo->GetLoadTriggeredFromExternal() &&
100
loadInfo->TriggeringPrincipal()->IsSystemPrincipal() &&
101
loadInfo->RedirectChain().IsEmpty()) {
102
return true;
103
}
104
nsAutoCString dataSpec;
105
uri->GetSpec(dataSpec);
106
if (dataSpec.Length() > 50) {
107
dataSpec.Truncate(50);
108
dataSpec.AppendLiteral("...");
109
}
110
nsCOMPtr<nsISupports> context = loadInfo->ContextForTopLevelLoad();
111
nsCOMPtr<nsIBrowserChild> browserChild = do_QueryInterface(context);
112
nsCOMPtr<Document> doc;
113
if (browserChild) {
114
doc = static_cast<mozilla::dom::BrowserChild*>(browserChild.get())
115
->GetTopLevelDocument();
116
}
117
AutoTArray<nsString, 1> params;
118
CopyUTF8toUTF16(NS_UnescapeURL(dataSpec), *params.AppendElement());
119
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
120
NS_LITERAL_CSTRING("DATA_URI_BLOCKED"), doc,
121
nsContentUtils::eSECURITY_PROPERTIES,
122
"BlockTopLevelDataURINavigation", params);
123
return false;
124
}
125
126
/* static */
127
bool nsContentSecurityManager::AllowInsecureRedirectToDataURI(
128
nsIChannel* aNewChannel) {
129
nsCOMPtr<nsILoadInfo> loadInfo = aNewChannel->LoadInfo();
130
if (loadInfo->GetExternalContentPolicyType() !=
131
nsIContentPolicy::TYPE_SCRIPT) {
132
return true;
133
}
134
nsCOMPtr<nsIURI> newURI;
135
nsresult rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
136
if (NS_FAILED(rv) || !newURI) {
137
return true;
138
}
139
bool isDataURI = newURI->SchemeIs("data");
140
if (!isDataURI) {
141
return true;
142
}
143
144
// Web Extensions are exempt from that restriction and are allowed to redirect
145
// a channel to a data: URI. When a web extension redirects a channel, we set
146
// a flag on the loadInfo which allows us to identify such redirects here.
147
if (loadInfo->GetAllowInsecureRedirectToDataURI()) {
148
return true;
149
}
150
151
nsAutoCString dataSpec;
152
newURI->GetSpec(dataSpec);
153
if (dataSpec.Length() > 50) {
154
dataSpec.Truncate(50);
155
dataSpec.AppendLiteral("...");
156
}
157
nsCOMPtr<Document> doc;
158
nsINode* node = loadInfo->LoadingNode();
159
if (node) {
160
doc = node->OwnerDoc();
161
}
162
AutoTArray<nsString, 1> params;
163
CopyUTF8toUTF16(NS_UnescapeURL(dataSpec), *params.AppendElement());
164
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
165
NS_LITERAL_CSTRING("DATA_URI_BLOCKED"), doc,
166
nsContentUtils::eSECURITY_PROPERTIES,
167
"BlockSubresourceRedirectToData", params);
168
return false;
169
}
170
171
/* static */
172
nsresult nsContentSecurityManager::CheckFTPSubresourceLoad(
173
nsIChannel* aChannel) {
174
// We dissallow using FTP resources as a subresource everywhere.
175
// The only valid way to use FTP resources is loading it as
176
// a top level document.
177
178
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
179
nsContentPolicyType type = loadInfo->GetExternalContentPolicyType();
180
181
// Allow top-level FTP documents and save-as download of FTP files on
182
// HTTP pages.
183
if (type == nsIContentPolicy::TYPE_DOCUMENT ||
184
type == nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
185
return NS_OK;
186
}
187
188
// Allow the system principal to load everything. This is meant to
189
// temporarily fix downloads and pdf.js.
190
nsIPrincipal* triggeringPrincipal = loadInfo->TriggeringPrincipal();
191
if (triggeringPrincipal->IsSystemPrincipal()) {
192
return NS_OK;
193
}
194
195
nsCOMPtr<nsIURI> uri;
196
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
197
NS_ENSURE_SUCCESS(rv, rv);
198
if (!uri) {
199
return NS_OK;
200
}
201
202
bool isFtpURI = uri->SchemeIs("ftp");
203
if (!isFtpURI) {
204
return NS_OK;
205
}
206
207
nsCOMPtr<Document> doc;
208
if (nsINode* node = loadInfo->LoadingNode()) {
209
doc = node->OwnerDoc();
210
}
211
212
nsAutoCString spec;
213
uri->GetSpec(spec);
214
AutoTArray<nsString, 1> params;
215
CopyUTF8toUTF16(NS_UnescapeURL(spec), *params.AppendElement());
216
217
nsContentUtils::ReportToConsole(
218
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("FTP_URI_BLOCKED"), doc,
219
nsContentUtils::eSECURITY_PROPERTIES, "BlockSubresourceFTP", params);
220
221
return NS_ERROR_CONTENT_BLOCKED;
222
}
223
224
static nsresult ValidateSecurityFlags(nsILoadInfo* aLoadInfo) {
225
nsSecurityFlags securityMode = aLoadInfo->GetSecurityMode();
226
227
// We should never perform a security check on a loadInfo that uses the flag
228
// SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK, because that is only used for
229
// temporary loadInfos used for explicit nsIContentPolicy checks, but never be
230
// set as a security flag on an actual channel.
231
if (securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS &&
232
securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED &&
233
securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS &&
234
securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
235
securityMode != nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
236
MOZ_ASSERT(
237
false,
238
"need one securityflag from nsILoadInfo to perform security checks");
239
return NS_ERROR_FAILURE;
240
}
241
242
// all good, found the right security flags
243
return NS_OK;
244
}
245
246
static bool IsImageLoadInEditorAppType(nsILoadInfo* aLoadInfo) {
247
// Editor apps get special treatment here, editors can load images
248
// from anywhere. This allows editor to insert images from file://
249
// into documents that are being edited.
250
nsContentPolicyType type = aLoadInfo->InternalContentPolicyType();
251
if (type != nsIContentPolicy::TYPE_INTERNAL_IMAGE &&
252
type != nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD &&
253
type != nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON &&
254
type != nsIContentPolicy::TYPE_IMAGESET) {
255
return false;
256
}
257
258
auto appType = nsIDocShell::APP_TYPE_UNKNOWN;
259
nsINode* node = aLoadInfo->LoadingNode();
260
if (!node) {
261
return false;
262
}
263
Document* doc = node->OwnerDoc();
264
if (!doc) {
265
return false;
266
}
267
268
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = doc->GetDocShell();
269
if (!docShellTreeItem) {
270
return false;
271
}
272
273
nsCOMPtr<nsIDocShellTreeItem> root;
274
docShellTreeItem->GetInProcessRootTreeItem(getter_AddRefs(root));
275
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(root));
276
if (docShell) {
277
appType = docShell->GetAppType();
278
}
279
280
return appType == nsIDocShell::APP_TYPE_EDITOR;
281
}
282
283
static nsresult DoCheckLoadURIChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo) {
284
// In practice, these DTDs are just used for localization, so applying the
285
// same principal check as Fluent.
286
if (aLoadInfo->InternalContentPolicyType() ==
287
nsIContentPolicy::TYPE_INTERNAL_DTD) {
288
RefPtr<Document> doc;
289
aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
290
return nsContentUtils::PrincipalAllowsL10n(
291
*aLoadInfo->TriggeringPrincipal(),
292
doc ? doc->GetDocumentURI() : nullptr)
293
? NS_OK
294
: NS_ERROR_DOM_BAD_URI;
295
}
296
297
// This is used in order to allow a privileged DOMParser to parse documents
298
// that need to access localization DTDs. We just allow through
299
// TYPE_INTERNAL_FORCE_ALLOWED_DTD no matter what the triggering principal is.
300
if (aLoadInfo->InternalContentPolicyType() ==
301
nsIContentPolicy::TYPE_INTERNAL_FORCE_ALLOWED_DTD) {
302
return NS_OK;
303
}
304
305
if (IsImageLoadInEditorAppType(aLoadInfo)) {
306
return NS_OK;
307
}
308
309
// Only call CheckLoadURIWithPrincipal() using the TriggeringPrincipal and not
310
// the LoadingPrincipal when SEC_ALLOW_CROSS_ORIGIN_* security flags are set,
311
// to allow, e.g. user stylesheets to load chrome:// URIs.
312
return nsContentUtils::GetSecurityManager()->CheckLoadURIWithPrincipal(
313
aLoadInfo->TriggeringPrincipal(), aURI, aLoadInfo->CheckLoadURIFlags(),
314
aLoadInfo->GetInnerWindowID());
315
}
316
317
static bool URIHasFlags(nsIURI* aURI, uint32_t aURIFlags) {
318
bool hasFlags;
319
nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
320
NS_ENSURE_SUCCESS(rv, false);
321
322
return hasFlags;
323
}
324
325
static nsresult DoSOPChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo,
326
nsIChannel* aChannel) {
327
if (aLoadInfo->GetAllowChrome() &&
328
(URIHasFlags(aURI, nsIProtocolHandler::URI_IS_UI_RESOURCE) ||
329
nsContentUtils::SchemeIs(aURI, "moz-safe-about"))) {
330
// UI resources are allowed.
331
return DoCheckLoadURIChecks(aURI, aLoadInfo);
332
}
333
334
if (NS_HasBeenCrossOrigin(aChannel, true)) {
335
NS_SetRequestBlockingReason(aLoadInfo,
336
nsILoadInfo::BLOCKING_REASON_NOT_SAME_ORIGIN);
337
return NS_ERROR_DOM_BAD_URI;
338
}
339
340
return NS_OK;
341
}
342
343
static nsresult DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
344
nsCOMPtr<nsIStreamListener>& aInAndOutListener) {
345
MOZ_RELEASE_ASSERT(aInAndOutListener,
346
"can not perform CORS checks without a listener");
347
348
// No need to set up CORS if TriggeringPrincipal is the SystemPrincipal.
349
// For example, allow user stylesheets to load XBL from external files
350
// without requiring CORS.
351
if (aLoadInfo->TriggeringPrincipal()->IsSystemPrincipal()) {
352
return NS_OK;
353
}
354
355
// We use the triggering principal here, rather than the loading principal
356
// to ensure that anonymous CORS content in the browser resources and in
357
// WebExtensions is allowed to load.
358
nsIPrincipal* principal = aLoadInfo->TriggeringPrincipal();
359
RefPtr<nsCORSListenerProxy> corsListener = new nsCORSListenerProxy(
360
aInAndOutListener, principal,
361
aLoadInfo->GetCookiePolicy() == nsILoadInfo::SEC_COOKIES_INCLUDE);
362
// XXX: @arg: DataURIHandling::Allow
363
// lets use DataURIHandling::Allow for now and then decide on callsite basis.
364
// see also:
366
nsresult rv = corsListener->Init(aChannel, DataURIHandling::Allow);
367
NS_ENSURE_SUCCESS(rv, rv);
368
aInAndOutListener = corsListener;
369
return NS_OK;
370
}
371
372
static nsresult DoContentSecurityChecks(nsIChannel* aChannel,
373
nsILoadInfo* aLoadInfo) {
374
nsContentPolicyType contentPolicyType =
375
aLoadInfo->GetExternalContentPolicyType();
376
nsContentPolicyType internalContentPolicyType =
377
aLoadInfo->InternalContentPolicyType();
378
nsCString mimeTypeGuess;
379
380
nsCOMPtr<nsIURI> uri;
381
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
382
NS_ENSURE_SUCCESS(rv, rv);
383
384
switch (contentPolicyType) {
385
case nsIContentPolicy::TYPE_OTHER: {
386
mimeTypeGuess = EmptyCString();
387
break;
388
}
389
390
case nsIContentPolicy::TYPE_SCRIPT: {
391
mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
392
break;
393
}
394
395
case nsIContentPolicy::TYPE_IMAGE: {
396
mimeTypeGuess = EmptyCString();
397
break;
398
}
399
400
case nsIContentPolicy::TYPE_STYLESHEET: {
401
mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
402
break;
403
}
404
405
case nsIContentPolicy::TYPE_OBJECT: {
406
mimeTypeGuess = EmptyCString();
407
break;
408
}
409
410
case nsIContentPolicy::TYPE_DOCUMENT: {
411
mimeTypeGuess = EmptyCString();
412
break;
413
}
414
415
case nsIContentPolicy::TYPE_SUBDOCUMENT: {
416
mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
417
break;
418
}
419
420
case nsIContentPolicy::TYPE_REFRESH: {
421
MOZ_ASSERT(false, "contentPolicyType not supported yet");
422
break;
423
}
424
425
case nsIContentPolicy::TYPE_XBL: {
426
mimeTypeGuess = EmptyCString();
427
break;
428
}
429
430
case nsIContentPolicy::TYPE_PING: {
431
mimeTypeGuess = EmptyCString();
432
break;
433
}
434
435
case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
436
// alias nsIContentPolicy::TYPE_DATAREQUEST:
437
#ifdef DEBUG
438
{
439
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
440
MOZ_ASSERT(!node || node->NodeType() == nsINode::DOCUMENT_NODE,
441
"type_xml requires requestingContext of type Document");
442
}
443
#endif
444
// We're checking for the external TYPE_XMLHTTPREQUEST here in case
445
// an addon creates a request with that type.
446
if (internalContentPolicyType ==
447
nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST ||
448
internalContentPolicyType == nsIContentPolicy::TYPE_XMLHTTPREQUEST) {
449
mimeTypeGuess = EmptyCString();
450
} else {
451
MOZ_ASSERT(internalContentPolicyType ==
452
nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
453
"can not set mime type guess for unexpected internal type");
454
mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
455
}
456
break;
457
}
458
459
case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
460
mimeTypeGuess = EmptyCString();
461
#ifdef DEBUG
462
{
463
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
464
MOZ_ASSERT(
465
!node || node->NodeType() == nsINode::ELEMENT_NODE,
466
"type_subrequest requires requestingContext of type Element");
467
}
468
#endif
469
break;
470
}
471
472
case nsIContentPolicy::TYPE_DTD: {
473
mimeTypeGuess = EmptyCString();
474
#ifdef DEBUG
475
{
476
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
477
MOZ_ASSERT(!node || node->NodeType() == nsINode::DOCUMENT_NODE,
478
"type_dtd requires requestingContext of type Document");
479
}
480
#endif
481
break;
482
}
483
484
case nsIContentPolicy::TYPE_FONT: {
485
mimeTypeGuess = EmptyCString();
486
break;
487
}
488
489
case nsIContentPolicy::TYPE_MEDIA: {
490
if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) {
491
mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt");
492
} else {
493
mimeTypeGuess = EmptyCString();
494
}
495
#ifdef DEBUG
496
{
497
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
498
MOZ_ASSERT(!node || node->NodeType() == nsINode::ELEMENT_NODE,
499
"type_media requires requestingContext of type Element");
500
}
501
#endif
502
break;
503
}
504
505
case nsIContentPolicy::TYPE_WEBSOCKET: {
506
// Websockets have to use the proxied URI:
507
// ws:// instead of http:// for CSP checks
508
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
509
do_QueryInterface(aChannel);
510
MOZ_ASSERT(httpChannelInternal);
511
if (httpChannelInternal) {
512
rv = httpChannelInternal->GetProxyURI(getter_AddRefs(uri));
513
MOZ_ASSERT(NS_SUCCEEDED(rv));
514
}
515
mimeTypeGuess = EmptyCString();
516
break;
517
}
518
519
case nsIContentPolicy::TYPE_CSP_REPORT: {
520
mimeTypeGuess = EmptyCString();
521
break;
522
}
523
524
case nsIContentPolicy::TYPE_XSLT: {
525
mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
526
#ifdef DEBUG
527
{
528
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
529
MOZ_ASSERT(!node || node->NodeType() == nsINode::DOCUMENT_NODE,
530
"type_xslt requires requestingContext of type Document");
531
}
532
#endif
533
break;
534
}
535
536
case nsIContentPolicy::TYPE_BEACON: {
537
mimeTypeGuess = EmptyCString();
538
#ifdef DEBUG
539
{
540
nsCOMPtr<nsINode> node = aLoadInfo->LoadingNode();
541
MOZ_ASSERT(!node || node->NodeType() == nsINode::DOCUMENT_NODE,
542
"type_beacon requires requestingContext of type Document");
543
}
544
#endif
545
break;
546
}
547
548
case nsIContentPolicy::TYPE_FETCH: {
549
mimeTypeGuess = EmptyCString();
550
break;
551
}
552
553
case nsIContentPolicy::TYPE_IMAGESET: {
554
mimeTypeGuess = EmptyCString();
555
break;
556
}
557
558
case nsIContentPolicy::TYPE_WEB_MANIFEST: {
559
mimeTypeGuess = NS_LITERAL_CSTRING("application/manifest+json");
560
break;
561
}
562
563
case nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD: {
564
mimeTypeGuess = EmptyCString();
565
break;
566
}
567
568
case nsIContentPolicy::TYPE_SPECULATIVE: {
569
mimeTypeGuess = EmptyCString();
570
break;
571
}
572
573
default:
574
// nsIContentPolicy::TYPE_INVALID
575
MOZ_ASSERT(false,
576
"can not perform security check without a valid contentType");
577
}
578
579
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
580
rv = NS_CheckContentLoadPolicy(uri, aLoadInfo, mimeTypeGuess, &shouldLoad,
581
nsContentUtils::GetContentPolicy());
582
583
if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
584
NS_SetRequestBlockingReasonIfNull(
585
aLoadInfo, nsILoadInfo::BLOCKING_REASON_CONTENT_POLICY_GENERAL);
586
587
if ((NS_SUCCEEDED(rv) && shouldLoad == nsIContentPolicy::REJECT_TYPE) &&
588
(contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
589
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT)) {
590
// for docshell loads we might have to return SHOW_ALT.
591
return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
592
}
593
return NS_ERROR_CONTENT_BLOCKED;
594
}
595
596
return NS_OK;
597
}
598
599
static void LogPrincipal(nsIPrincipal* aPrincipal,
600
const nsAString& aPrincipalName) {
601
if (aPrincipal && aPrincipal->IsSystemPrincipal()) {
602
MOZ_LOG(sCSMLog, LogLevel::Debug,
603
(" %s: SystemPrincipal\n",
604
NS_ConvertUTF16toUTF8(aPrincipalName).get()));
605
return;
606
}
607
if (aPrincipal) {
608
if (aPrincipal->GetIsNullPrincipal()) {
609
MOZ_LOG(sCSMLog, LogLevel::Debug,
610
(" %s: NullPrincipal\n",
611
NS_ConvertUTF16toUTF8(aPrincipalName).get()));
612
return;
613
}
614
if (aPrincipal->GetIsExpandedPrincipal()) {
615
nsCOMPtr<nsIExpandedPrincipal> expanded(do_QueryInterface(aPrincipal));
616
const nsTArray<nsCOMPtr<nsIPrincipal>>& allowList = expanded->AllowList();
617
nsAutoCString origin;
618
origin.AssignLiteral("[Expanded Principal [");
619
for (size_t i = 0; i < allowList.Length(); ++i) {
620
if (i != 0) {
621
origin.AppendLiteral(", ");
622
}
623
624
nsAutoCString subOrigin;
625
DebugOnly<nsresult> rv = allowList.ElementAt(i)->GetOrigin(subOrigin);
626
MOZ_ASSERT(NS_SUCCEEDED(rv));
627
origin.Append(subOrigin);
628
}
629
origin.AppendLiteral("]]");
630
631
MOZ_LOG(sCSMLog, LogLevel::Debug,
632
(" %s: %s\n", NS_ConvertUTF16toUTF8(aPrincipalName).get(),
633
origin.get()));
634
return;
635
}
636
nsAutoCString principalSpec;
637
aPrincipal->GetAsciiSpec(principalSpec);
638
MOZ_LOG(sCSMLog, LogLevel::Debug,
639
(" %s: %s\n", NS_ConvertUTF16toUTF8(aPrincipalName).get(),
640
principalSpec.get()));
641
return;
642
}
643
MOZ_LOG(sCSMLog, LogLevel::Debug,
644
(" %s: nullptr\n", NS_ConvertUTF16toUTF8(aPrincipalName).get()));
645
}
646
647
static void LogSecurityFlags(nsSecurityFlags securityFlags) {
648
struct DebugSecFlagType {
649
unsigned long secFlag;
650
char secTypeStr[128];
651
};
652
static const DebugSecFlagType secTypes[] = {
653
{nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
654
"SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK"},
655
{nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
656
"SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS"},
657
{nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
658
"SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED"},
659
{nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS,
660
"SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS"},
661
{nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
662
"SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL"},
663
{nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
664
"SEC_REQUIRE_CORS_DATA_INHERITS"},
665
{nsILoadInfo::SEC_COOKIES_DEFAULT, "SEC_COOKIES_DEFAULT"},
666
{nsILoadInfo::SEC_COOKIES_INCLUDE, "SEC_COOKIES_INCLUDE"},
667
{nsILoadInfo::SEC_COOKIES_SAME_ORIGIN, "SEC_COOKIES_SAME_ORIGIN"},
668
{nsILoadInfo::SEC_COOKIES_OMIT, "SEC_COOKIES_OMIT"},
669
{nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, "SEC_FORCE_INHERIT_PRINCIPAL"},
670
{nsILoadInfo::SEC_ABOUT_BLANK_INHERITS, "SEC_ABOUT_BLANK_INHERITS"},
671
{nsILoadInfo::SEC_ALLOW_CHROME, "SEC_ALLOW_CHROME"},
672
{nsILoadInfo::SEC_DISALLOW_SCRIPT, "SEC_DISALLOW_SCRIPT"},
673
{nsILoadInfo::SEC_DONT_FOLLOW_REDIRECTS, "SEC_DONT_FOLLOW_REDIRECTS"},
674
{nsILoadInfo::SEC_LOAD_ERROR_PAGE, "SEC_LOAD_ERROR_PAGE"},
675
{nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER,
676
"SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER"}};
677
678
for (const DebugSecFlagType flag : secTypes) {
679
if (securityFlags & flag.secFlag) {
680
MOZ_LOG(sCSMLog, LogLevel::Debug, (" %s,\n", flag.secTypeStr));
681
}
682
}
683
}
684
static void DebugDoContentSecurityCheck(nsIChannel* aChannel,
685
nsILoadInfo* aLoadInfo) {
686
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
687
688
// we only log http channels, unless loglevel is 5.
689
if (httpChannel || MOZ_LOG_TEST(sCSMLog, LogLevel::Verbose)) {
690
nsCOMPtr<nsIURI> channelURI;
691
nsAutoCString channelSpec;
692
nsAutoCString channelMethod;
693
NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
694
if (channelURI) {
695
channelURI->GetSpec(channelSpec);
696
}
697
698
MOZ_LOG(sCSMLog, LogLevel::Verbose, ("doContentSecurityCheck {\n"));
699
MOZ_LOG(sCSMLog, LogLevel::Verbose,
700
(" channelURI: %s\n", channelSpec.get()));
701
702
// Log HTTP-specific things
703
if (httpChannel) {
704
nsresult rv;
705
rv = httpChannel->GetRequestMethod(channelMethod);
706
if (!NS_FAILED(rv)) {
707
MOZ_LOG(sCSMLog, LogLevel::Verbose,
708
(" HTTP Method: %s\n", channelMethod.get()));
709
}
710
}
711
712
// Log Principals
713
nsCOMPtr<nsIPrincipal> requestPrincipal = aLoadInfo->TriggeringPrincipal();
714
LogPrincipal(aLoadInfo->LoadingPrincipal(),
715
NS_LITERAL_STRING("loadingPrincipal"));
716
LogPrincipal(requestPrincipal, NS_LITERAL_STRING("triggeringPrincipal"));
717
LogPrincipal(aLoadInfo->PrincipalToInherit(),
718
NS_LITERAL_STRING("principalToInherit"));
719
720
// Log Redirect Chain
721
MOZ_LOG(sCSMLog, LogLevel::Verbose, (" RedirectChain:\n"));
722
for (nsIRedirectHistoryEntry* redirectHistoryEntry :
723
aLoadInfo->RedirectChain()) {
724
nsCOMPtr<nsIPrincipal> principal;
725
redirectHistoryEntry->GetPrincipal(getter_AddRefs(principal));
726
LogPrincipal(principal, NS_LITERAL_STRING("->"));
727
}
728
729
MOZ_LOG(sCSMLog, LogLevel::Verbose,
730
(" internalContentPolicyType: %d\n",
731
aLoadInfo->InternalContentPolicyType()));
732
MOZ_LOG(sCSMLog, LogLevel::Verbose,
733
(" externalContentPolicyType: %d\n",
734
aLoadInfo->GetExternalContentPolicyType()));
735
MOZ_LOG(sCSMLog, LogLevel::Verbose,
736
(" upgradeInsecureRequests: %s\n",
737
aLoadInfo->GetUpgradeInsecureRequests() ? "true" : "false"));
738
MOZ_LOG(sCSMLog, LogLevel::Verbose,
739
(" initalSecurityChecksDone: %s\n",
740
aLoadInfo->GetInitialSecurityCheckDone() ? "true" : "false"));
741
742
// Log CSPrequestPrincipal
743
nsCOMPtr<nsIContentSecurityPolicy> csp = aLoadInfo->GetCsp();
744
if (csp) {
745
nsAutoString parsedPolicyStr;
746
uint32_t count = 0;
747
csp->GetPolicyCount(&count);
748
MOZ_LOG(sCSMLog, LogLevel::Debug, (" CSP (%d): ", count));
749
for (uint32_t i = 0; i < count; ++i) {
750
csp->GetPolicyString(i, parsedPolicyStr);
751
MOZ_LOG(sCSMLog, LogLevel::Debug,
752
(" %s\n", NS_ConvertUTF16toUTF8(parsedPolicyStr).get()));
753
}
754
}
755
756
// Security Flags
757
MOZ_LOG(sCSMLog, LogLevel::Verbose, (" securityFlags: "));
758
LogSecurityFlags(aLoadInfo->GetSecurityFlags());
759
MOZ_LOG(sCSMLog, LogLevel::Verbose, ("}\n\n"));
760
}
761
}
762
763
/* static */
764
nsresult nsContentSecurityManager::CheckAllowLoadInSystemPrivilegedContext(
765
nsIChannel* aChannel) {
766
// Check and assert that we never allow remote documents/scripts (http:,
767
// https:, ...) to load in system privileged contexts.
768
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
769
770
// nothing to do here if we are not loading a resource into a
771
// system prvileged context.
772
if (!loadInfo->LoadingPrincipal() ||
773
!loadInfo->LoadingPrincipal()->IsSystemPrincipal()) {
774
return NS_OK;
775
}
776
777
nsCOMPtr<nsIURI> finalURI;
778
NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalURI));
779
780
// nothing to do here if we are not loading a resource using http:, https:,
781
// etc.
782
if (!nsContentUtils::SchemeIs(finalURI, "http") &&
783
!nsContentUtils::SchemeIs(finalURI, "https") &&
784
!nsContentUtils::SchemeIs(finalURI, "ftp")) {
785
return NS_OK;
786
}
787
788
nsContentPolicyType contentPolicyType =
789
loadInfo->GetExternalContentPolicyType();
790
791
// We distinguish between 2 cases:
792
// a) remote scripts
793
// which should never be loaded into system privileged contexts
794
// b) remote documents/frames
795
// which generally should also never be loaded into system
796
// privileged contexts but with some exceptions, like e.g. the
797
// discoverURL.
798
if (contentPolicyType == nsIContentPolicy::TYPE_SCRIPT) {
799
if (StaticPrefs::
800
dom_security_skip_remote_script_assertion_in_system_priv_context()) {
801
return NS_OK;
802
}
803
nsAutoCString scriptSpec;
804
finalURI->GetSpec(scriptSpec);
805
MOZ_LOG(
806
sCSMLog, LogLevel::Warning,
807
("Do not load remote scripts into system privileged contexts, url: %s",
808
scriptSpec.get()));
809
MOZ_ASSERT(false,
810
"Do not load remote scripts into system privileged contexts");
811
// Bug 1607673: Do not only assert but cancel the channel and
812
// return NS_ERROR_CONTENT_BLOCKED.
813
return NS_OK;
814
}
815
816
if ((contentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) &&
817
(contentPolicyType != nsIContentPolicy::TYPE_SUBDOCUMENT)) {
818
return NS_OK;
819
}
820
821
// FIXME The discovery feature in about:addons uses the SystemPrincpal.
822
// We should remove the exception for AMO with bug 1544011.
823
// We should remove the exception for Firefox Accounts with bug 1561318.
824
static nsAutoCString sDiscoveryPrePath;
825
#ifdef ANDROID
826
static nsAutoCString sFxaSPrePath;
827
#endif
828
static bool recvdPrefValues = false;
829
if (!recvdPrefValues) {
830
nsAutoCString discoveryURLString;
831
Preferences::GetCString("extensions.webservice.discoverURL",
832
discoveryURLString);
833
// discoverURL is by default suffixed with parameters in path like
834
// /%LOCALE%/ so, we use the prePath for comparison
835
nsCOMPtr<nsIURI> discoveryURL;
836
NS_NewURI(getter_AddRefs(discoveryURL), discoveryURLString);
837
if (discoveryURL) {
838
discoveryURL->GetPrePath(sDiscoveryPrePath);
839
}
840
#ifdef ANDROID
841
nsAutoCString fxaURLString;
842
Preferences::GetCString("identity.fxaccounts.remote.webchannel.uri",
843
fxaURLString);
844
nsCOMPtr<nsIURI> fxaURL;
845
NS_NewURI(getter_AddRefs(fxaURL), fxaURLString);
846
if (fxaURL) {
847
fxaURL->GetPrePath(sFxaSPrePath);
848
}
849
#endif
850
recvdPrefValues = true;
851
}
852
nsAutoCString requestedPrePath;
853
finalURI->GetPrePath(requestedPrePath);
854
855
if (requestedPrePath.Equals(sDiscoveryPrePath)) {
856
return NS_OK;
857
}
858
#ifdef ANDROID
859
if (requestedPrePath.Equals(sFxaSPrePath)) {
860
return NS_OK;
861
}
862
#endif
863
nsAutoCString requestedURL;
864
finalURI->GetAsciiSpec(requestedURL);
865
if (xpc::AreNonLocalConnectionsDisabled()) {
866
bool disallowSystemPrincipalRemoteDocuments = Preferences::GetBool(
867
"security.disallow_non_local_systemprincipal_in_tests");
868
if (disallowSystemPrincipalRemoteDocuments) {
869
// our own mochitest needs NS_ASSERTION instead of MOZ_ASSERT
870
NS_ASSERTION(false, "SystemPrincipal must not load remote documents.");
871
aChannel->Cancel(NS_ERROR_CONTENT_BLOCKED);
872
return NS_ERROR_CONTENT_BLOCKED;
873
}
874
// but other mochitest are exempt from this
875
return NS_OK;
876
}
877
MOZ_LOG(
878
sCSMLog, LogLevel::Warning,
879
("SystemPrincipal must not load remote documents. URL: %s", requestedURL)
880
.get());
881
MOZ_ASSERT(false, "SystemPrincipal must not load remote documents.");
882
aChannel->Cancel(NS_ERROR_CONTENT_BLOCKED);
883
return NS_ERROR_CONTENT_BLOCKED;
884
}
885
886
/*
887
* Based on the security flags provided in the loadInfo of the channel,
888
* doContentSecurityCheck() performs the following content security checks
889
* before opening the channel:
890
*
891
* (1) Same Origin Policy Check (if applicable)
892
* (2) Allow Cross Origin but perform sanity checks whether a principal
893
* is allowed to access the following URL.
894
* (3) Perform CORS check (if applicable)
895
* (4) ContentPolicy checks (Content-Security-Policy, Mixed Content, ...)
896
*
897
* @param aChannel
898
* The channel to perform the security checks on.
899
* @param aInAndOutListener
900
* The streamListener that is passed to channel->AsyncOpen() that is now
901
* potentially wrappend within nsCORSListenerProxy() and becomes the
902
* corsListener that now needs to be set as new streamListener on the channel.
903
*/
904
nsresult nsContentSecurityManager::doContentSecurityCheck(
905
nsIChannel* aChannel, nsCOMPtr<nsIStreamListener>& aInAndOutListener) {
906
NS_ENSURE_ARG(aChannel);
907
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
908
if (MOZ_UNLIKELY(MOZ_LOG_TEST(sCSMLog, LogLevel::Verbose))) {
909
DebugDoContentSecurityCheck(aChannel, loadInfo);
910
}
911
912
nsresult rv = CheckAllowLoadInSystemPrivilegedContext(aChannel);
913
NS_ENSURE_SUCCESS(rv, rv);
914
915
// if dealing with a redirected channel then we have already installed
916
// streamlistener and redirect proxies and so we are done.
917
if (loadInfo->GetInitialSecurityCheckDone()) {
918
return NS_OK;
919
}
920
921
// make sure that only one of the five security flags is set in the loadinfo
922
// e.g. do not require same origin and allow cross origin at the same time
923
rv = ValidateSecurityFlags(loadInfo);
924
NS_ENSURE_SUCCESS(rv, rv);
925
926
if (loadInfo->GetSecurityMode() ==
927
nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
928
rv = DoCORSChecks(aChannel, loadInfo, aInAndOutListener);
929
NS_ENSURE_SUCCESS(rv, rv);
930
}
931
932
rv = CheckChannel(aChannel);
933
NS_ENSURE_SUCCESS(rv, rv);
934
935
// Perform all ContentPolicy checks (MixedContent, CSP, ...)
936
rv = DoContentSecurityChecks(aChannel, loadInfo);
937
NS_ENSURE_SUCCESS(rv, rv);
938
939
// Apply this after CSP to match Chrome.
940
rv = CheckFTPSubresourceLoad(aChannel);
941
NS_ENSURE_SUCCESS(rv, rv);
942
943
// now lets set the initalSecurityFlag for subsequent calls
944
loadInfo->SetInitialSecurityCheckDone(true);
945
946
// all security checks passed - lets allow the load
947
return NS_OK;
948
}
949
950
NS_IMETHODIMP
951
nsContentSecurityManager::AsyncOnChannelRedirect(
952
nsIChannel* aOldChannel, nsIChannel* aNewChannel, uint32_t aRedirFlags,
953
nsIAsyncVerifyRedirectCallback* aCb) {
954
// Since we compare the principal from the loadInfo to the URI's
955
// princicpal, it's possible that the checks fail when doing an internal
956
// redirect. We can just return early instead, since we should never
957
// need to block an internal redirect.
958
if (aRedirFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
959
aCb->OnRedirectVerifyCallback(NS_OK);
960
return NS_OK;
961
}
962
963
nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->LoadInfo();
964
nsresult rv = CheckChannel(aNewChannel);
965
if (NS_SUCCEEDED(rv)) {
966
rv = CheckFTPSubresourceLoad(aNewChannel);
967
}
968
if (NS_FAILED(rv)) {
969
aOldChannel->Cancel(rv);
970
return rv;
971
}
972
973
// Also verify that the redirecting server is allowed to redirect to the
974
// given URI
975
nsCOMPtr<nsIPrincipal> oldPrincipal;
976
nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
977
aOldChannel, getter_AddRefs(oldPrincipal));
978
979
nsCOMPtr<nsIURI> newURI;
980
Unused << NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
981
NS_ENSURE_STATE(oldPrincipal && newURI);
982
983
// Do not allow insecure redirects to data: URIs
984
if (!AllowInsecureRedirectToDataURI(aNewChannel)) {
985
// cancel the old channel and return an error
986
aOldChannel->Cancel(NS_ERROR_CONTENT_BLOCKED);
987
return NS_ERROR_CONTENT_BLOCKED;
988
}
989
990
const uint32_t flags =
991
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
992
nsIScriptSecurityManager::DISALLOW_SCRIPT;
993
rv = nsContentUtils::GetSecurityManager()->CheckLoadURIWithPrincipal(
994
oldPrincipal, newURI, flags, loadInfo->GetInnerWindowID());
995
NS_ENSURE_SUCCESS(rv, rv);
996
997
aCb->OnRedirectVerifyCallback(NS_OK);
998
return NS_OK;
999
}
1000
1001
static void AddLoadFlags(nsIRequest* aRequest, nsLoadFlags aNewFlags) {
1002
nsLoadFlags flags;
1003
aRequest->GetLoadFlags(&flags);
1004
flags |= aNewFlags;
1005
aRequest->SetLoadFlags(flags);
1006
}
1007
1008
/*
1009
* Check that this channel passes all security checks. Returns an error code
1010
* if this requesst should not be permitted.
1011
*/
1012
nsresult nsContentSecurityManager::CheckChannel(nsIChannel* aChannel) {
1013
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
1014
nsCOMPtr<nsIURI> uri;
1015
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
1016
NS_ENSURE_SUCCESS(rv, rv);
1017
1018
// Handle cookie policies
1019
uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
1020
if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
1021
// We shouldn't have the SEC_COOKIES_SAME_ORIGIN flag for top level loads
1022
MOZ_ASSERT(loadInfo->GetExternalContentPolicyType() !=
1023
nsIContentPolicy::TYPE_DOCUMENT);
1024
nsIPrincipal* loadingPrincipal = loadInfo->LoadingPrincipal();
1025
1026
// It doesn't matter what we pass for the second, data-inherits, argument.
1027
// Any protocol which inherits won't pay attention to cookies anyway.
1028
rv = loadingPrincipal->CheckMayLoad(uri, false);
1029
if (NS_FAILED(rv)) {
1030
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
1031
}
1032
} else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
1033
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
1034
}
1035
1036
nsSecurityFlags securityMode = loadInfo->GetSecurityMode();
1037
1038
// CORS mode is handled by nsCORSListenerProxy
1039
if (securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
1040
if (NS_HasBeenCrossOrigin(aChannel)) {
1041
loadInfo->MaybeIncreaseTainting(LoadTainting::CORS);
1042
}
1043
return NS_OK;
1044
}
1045
1046
// Allow subresource loads if TriggeringPrincipal is the SystemPrincipal.
1047
// For example, allow user stylesheets to load XBL from external files.
1048
if (loadInfo->TriggeringPrincipal()->IsSystemPrincipal() &&
1049
loadInfo->GetExternalContentPolicyType() !=
1050
nsIContentPolicy::TYPE_DOCUMENT &&
1051
loadInfo->GetExternalContentPolicyType() !=
1052
nsIContentPolicy::TYPE_SUBDOCUMENT) {
1053
return NS_OK;
1054
}
1055
1056
// if none of the REQUIRE_SAME_ORIGIN flags are set, then SOP does not apply
1057
if ((securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS) ||
1058
(securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED)) {
1059
rv = DoSOPChecks(uri, loadInfo, aChannel);
1060
NS_ENSURE_SUCCESS(rv, rv);
1061
}
1062
1063
if ((securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS) ||
1064
(securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL)) {
1065
if (NS_HasBeenCrossOrigin(aChannel)) {
1066
NS_ENSURE_FALSE(loadInfo->GetDontFollowRedirects(), NS_ERROR_DOM_BAD_URI);
1067
loadInfo->MaybeIncreaseTainting(LoadTainting::Opaque);
1068
}
1069
// Please note that DoCheckLoadURIChecks should only be enforced for
1070
// cross origin requests. If the flag SEC_REQUIRE_CORS_DATA_INHERITS is set
1071
// within the loadInfo, then then CheckLoadURIWithPrincipal is performed
1072
// within nsCorsListenerProxy
1073
rv = DoCheckLoadURIChecks(uri, loadInfo);
1074
NS_ENSURE_SUCCESS(rv, rv);
1075
// TODO: Bug 1371237
1076
// consider calling SetBlockedRequest in
1077
// nsContentSecurityManager::CheckChannel
1078
}
1079
1080
return NS_OK;
1081
}
1082
1083
// ==== nsIContentSecurityManager implementation =====
1084
1085
NS_IMETHODIMP
1086
nsContentSecurityManager::PerformSecurityCheck(
1087
nsIChannel* aChannel, nsIStreamListener* aStreamListener,
1088
nsIStreamListener** outStreamListener) {
1089
nsCOMPtr<nsIStreamListener> inAndOutListener = aStreamListener;
1090
nsresult rv = doContentSecurityCheck(aChannel, inAndOutListener);
1091
NS_ENSURE_SUCCESS(rv, rv);
1092
1093
inAndOutListener.forget(outStreamListener);
1094
return NS_OK;
1095
}