mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
b3dd358267
- Bug 1247362 - move mAnonymousGlobalScope tracing into nsMessageManagerScriptExecutor; r=mccr8 (9b33b54bc9)
- Bug 1195881 - Contextual Identity working under e10s. r=tanvi r=sicking r=baku (b3fd69bd92)
- Bug 1174624 - Add the Transferable parameter into SendAsyncMessage of nsFrameMessageManager. r=baku (33911dc6f7)
- Bug 1174624 - Add PortIdentifier copy code in order to communicate with same process. r=baku (d597f24e20)
- Bug 1234176 - Do not send memory pressure events to applications sent into the background. r=dhylands (687f154573)
- Bug 1201394 - Remove unused mLRUPoolSize member variable. r=gsvelto (a109934b8d)
- Bug 1144132 follow up to fix static check build bustage on a CLOSED TREE with r=me (050f49060e)
- Bug 1153394 - make HangMonitorChild::sInstance an atomic variable; r=billm (89e6905f3f)
- Bug 1202952 - Fix directory picking for e10s on Windows by making FilePickerParent use the correct nsIFilePicker API for directory picking. r=roc (a7e964d4fa)
- Bug 1227312 - Avoid calling FinalizeChildData twice in GenerateCompleteMinidump. r=ted (c29e6786ae)
- Bug 1222109 - Initialize mHasGamepadListener in InitializeMembers(); r=cleu (8057137e5d)
- Bug 1231498 - ContentParent::RecvCreateWindow() should fail in opt builds if passed bad chromeflags. r=billm (639fb93101)
- minor indentation (f5dbd8996c)
- fix misspatch (3b306e0084)
- Bug 1101264: Truncate long sourceName messages since they can be massive data: URLs. r=bent (c528048e58)
- Bug 1233497 - Update test_bug1086684.html to not access CPOWs unsafely inside SpecialPowers. r=mrbkap (d5d161eac2)
- align tests (24d98036dc)
- Bug 1232931 Return null instead of throwing if swm.getWorkerByID() cannot find the worker. r=ochameau IGNORE IDL for comment only change (17f293f323)
- Bug 1186812 (part 3) - Replace nsBaseHashtable::EnumerateRead() calls in dom/{ipc,plugins}/. r=jimm. (a944fa4480)
- Bug 1234656 - Add TouchEvent ctor, r=mbrubeck (842245df14)
- Bug 1246854 - Remove unnecessary warning. r=botond (7d0532e516)
- Bug 1245393 - Measure s{,Default}RootBranch in the Preferences memory reporter. r=froydnj. (be200f9ebe)
- Bug 1089232 - Updates nsContentPrefService to take an extra isPrivate argument. r=adw (9ea4fe075d)
- Bug 1229519: Fix toolkit/components/contentprefs to pass eslint checks. r=mconley (e48b64448b)
- Bug 663570 - MetaCSP Part 6: CSP preload changes (r=sicking) (65700820c1)
- Bug 1030936 - [CSP] remove fast-path for certified apps once the C++ backend is activated. r=ckerschb (e9527e9cfc)
- Bug 1228497 - initialize 3 members in class. r=christophkerschbaumer (44414e8429)
- Bug 1208946 - Strip URIs in CSP reports (r=dveditz) (dd6c18a8ff)
- Bug 1247464 - Run CSP report URIs through the URL classifier. r=ckerschb (ebb3570172)
- Bug 1242909, r=ckerschb (569de89b26)
- Bug 1119565: Ensure that a plugin listener's stream type is always set, even when it is STREAM_TYPE_UNKNOWN; r=jimm (43fb9ebdb9)
- Bug 1228116 - Relax Security checks for DTD loads. r=sicking (b77e2c4531)
- Bug 1195173 - Use channel->ascynOpen2 layout/style/Loader.cpp (r=bz) (97de97b864)
- let-var (fb35f8f50c)
- Bug 1226324 - Do not use NS_ENSURCE_SUCCESS(rv, NS_OK) within nsContentSecurityManager. r=tanvi (745ecaf562)
- Bug 1221365 - Tests for "Is origin potentially trustworthy?" logic. r=ckerschb,bkelly (1d520ebcc5)
- Bug 1132211 - Dispatch an event when <input type=password> is added to a document (including outside of a form). r=smaug (3e9acb8bf3)
- Bug 1217766 - All PDFs trigger the insecure password warning. r=MattN,bz (0ea7e35b96)
- Bug 1155471 - Mark some members of nsNodeInfoManager as MOZ_NON_OWNING_REF; r=baku (bd47bcea10)
- Tests for bug 1200856; r=sicking (454ff8048a)
- Bug 1243453 P1 Make nsCORSListenerProxy call UpdateChannel() for internal redirects. r=sicking (f2a45b1997)
- Bug 1243453 P2 Test XHR with a non-intercepting service worker. r=ehsan (d83b31ab3d)
- Bug 1169233 - Get grey (inactive) text color from menu labels. r=karlt (470155483b)
- Bug 1161056 - Gtk3 - use sMozWindowBackground colors for combobox background. r=karlt (4502f5583a)
- Bug 1169232 - [gtk3] Add background class to tooltip window to get correct background color. r=karlt (9421a23b1c)
- Bug 1219717 - Derive text color/background from GtkTextView. r=karlt (a39cd997ee)
- Bug 1241239 - Fix missing 'using mozilla::LogLevel' in nsIdleServiceGTK.cpp. r=karlt (16bacfc530)
- Bug 1209659 - Disable client-side decorations on broken Gtk3 versions (<3.20). r=karlt (d5cbd4c0fb)
- Bug 540078 - Remove assertion annotations that are no longer needed and add crashtest. (89f33bb00c)
- Bug 1168219 - Make nsIWidget::Configuration::mChild a smart pointer on widget/qt too. r=froydnj (0f2f97a31b)
- Bug 1234385: Add downloadable blocklist support for between comparison types, by recognizing driverVersionMax when parsing. r=benwa (87617d0fa1)
- Bug 1112712 - DOM key mapping for soft1 soft2 and call keys r=schien (3f4360e64b)
- Bug 1237691 - Implement Oculus Head Pose Prediction (3f6b0122e3)
- Bug 1041882 - Remove Froyo-specific OMX plugin support. r=snorp (eb2f6dd36a)
- Bug 1205930 - Tighten up warnings handling in media/omx-plugin/. r=gerald. (86845d720a)
- Bug 1153849 - Use MOZ_JPEG_CFLAGS when build libyuv with system jpeg. r=jesup (a38f53057d)
- Bug 1240635 - Interpret glyph x-offsets on SVG vertical text paths in the correct direction. r=longsonr (ce90452da1)
- Bug 1185266 - Look up painting properties on the SVGTextFrame when painting text frames that are direct children of <text>. r=jwatt (9c89ab71eb)
- Bug 1143096 - Init all WebMBufferedParser members - r=kinetik (7df2e4e0c3)
- Bug 1231855 - Avoid inserting out of (timecode) order entries in WebMBufferedParser. r=jya (f7806faec4)
580 lines
20 KiB
C++
580 lines
20 KiB
C++
#include "nsContentSecurityManager.h"
|
|
#include "nsIChannel.h"
|
|
#include "nsIStreamListener.h"
|
|
#include "nsILoadInfo.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsCORSListenerProxy.h"
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "mozilla/dom/Element.h"
|
|
|
|
NS_IMPL_ISUPPORTS(nsContentSecurityManager,
|
|
nsIContentSecurityManager,
|
|
nsIChannelEventSink)
|
|
|
|
static nsresult
|
|
ValidateSecurityFlags(nsILoadInfo* aLoadInfo)
|
|
{
|
|
nsSecurityFlags securityMode = aLoadInfo->GetSecurityMode();
|
|
|
|
if (securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS &&
|
|
securityMode != nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED &&
|
|
securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS &&
|
|
securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
|
|
securityMode != nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
|
MOZ_ASSERT(false, "need one securityflag from nsILoadInfo to perform security checks");
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// all good, found the right security flags
|
|
return NS_OK;
|
|
}
|
|
|
|
static bool SchemeIs(nsIURI* aURI, const char* aScheme)
|
|
{
|
|
nsCOMPtr<nsIURI> baseURI = NS_GetInnermostURI(aURI);
|
|
NS_ENSURE_TRUE(baseURI, false);
|
|
|
|
bool isScheme = false;
|
|
return NS_SUCCEEDED(baseURI->SchemeIs(aScheme, &isScheme)) && isScheme;
|
|
}
|
|
|
|
static nsresult
|
|
DoCheckLoadURIChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
|
{
|
|
// Bug 1228117: determine the correct security policy for DTD loads
|
|
if (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DTD) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadInfo->LoadingPrincipal();
|
|
uint32_t flags = nsIScriptSecurityManager::STANDARD;
|
|
if (aLoadInfo->GetAllowChrome()) {
|
|
flags |= nsIScriptSecurityManager::ALLOW_CHROME;
|
|
}
|
|
|
|
rv = nsContentUtils::GetSecurityManager()->
|
|
CheckLoadURIWithPrincipal(loadingPrincipal,
|
|
aURI,
|
|
flags);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// If the loadingPrincipal and the triggeringPrincipal are different, then make
|
|
// sure the triggeringPrincipal is allowed to access that URI.
|
|
nsCOMPtr<nsIPrincipal> triggeringPrincipal = aLoadInfo->TriggeringPrincipal();
|
|
if (loadingPrincipal != triggeringPrincipal) {
|
|
rv = nsContentUtils::GetSecurityManager()->
|
|
CheckLoadURIWithPrincipal(triggeringPrincipal,
|
|
aURI,
|
|
flags);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
static bool
|
|
URIHasFlags(nsIURI* aURI, uint32_t aURIFlags)
|
|
{
|
|
bool hasFlags;
|
|
nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
|
|
NS_ENSURE_SUCCESS(rv, false);
|
|
|
|
return hasFlags;
|
|
}
|
|
|
|
static nsresult
|
|
DoSOPChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo, nsIChannel* aChannel)
|
|
{
|
|
if (aLoadInfo->GetAllowChrome() &&
|
|
(URIHasFlags(aURI, nsIProtocolHandler::URI_IS_UI_RESOURCE) ||
|
|
SchemeIs(aURI, "moz-safe-about"))) {
|
|
// UI resources are allowed.
|
|
return DoCheckLoadURIChecks(aURI, aLoadInfo);
|
|
}
|
|
|
|
NS_ENSURE_FALSE(NS_HasBeenCrossOrigin(aChannel, true),
|
|
NS_ERROR_DOM_BAD_URI);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
static nsresult
|
|
DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
|
|
nsCOMPtr<nsIStreamListener>& aInAndOutListener)
|
|
{
|
|
MOZ_RELEASE_ASSERT(aInAndOutListener, "can not perform CORS checks without a listener");
|
|
|
|
// No need to set up CORS if TriggeringPrincipal is the SystemPrincipal.
|
|
// For example, allow user stylesheets to load XBL from external files
|
|
// without requiring CORS.
|
|
if (nsContentUtils::IsSystemPrincipal(aLoadInfo->TriggeringPrincipal())) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsIPrincipal* loadingPrincipal = aLoadInfo->LoadingPrincipal();
|
|
RefPtr<nsCORSListenerProxy> corsListener =
|
|
new nsCORSListenerProxy(aInAndOutListener,
|
|
loadingPrincipal,
|
|
aLoadInfo->GetCookiePolicy() ==
|
|
nsILoadInfo::SEC_COOKIES_INCLUDE);
|
|
// XXX: @arg: DataURIHandling::Allow
|
|
// lets use DataURIHandling::Allow for now and then decide on callsite basis. see also:
|
|
// http://mxr.mozilla.org/mozilla-central/source/dom/security/nsCORSListenerProxy.h#33
|
|
nsresult rv = corsListener->Init(aChannel, DataURIHandling::Allow);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
aInAndOutListener = corsListener;
|
|
return NS_OK;
|
|
}
|
|
|
|
static nsresult
|
|
DoContentSecurityChecks(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
|
{
|
|
nsContentPolicyType contentPolicyType =
|
|
aLoadInfo->GetExternalContentPolicyType();
|
|
nsContentPolicyType internalContentPolicyType =
|
|
aLoadInfo->InternalContentPolicyType();
|
|
nsCString mimeTypeGuess;
|
|
nsCOMPtr<nsINode> requestingContext = nullptr;
|
|
|
|
switch(contentPolicyType) {
|
|
case nsIContentPolicy::TYPE_OTHER: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_SCRIPT: {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("application/javascript");
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_IMAGE: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_STYLESHEET: {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("text/css");
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_OBJECT:
|
|
case nsIContentPolicy::TYPE_DOCUMENT: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_SUBDOCUMENT: {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("text/html");
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
|
"type_subdocument requires requestingContext of type Document");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_REFRESH: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_XBL: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_PING: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
|
|
// alias nsIContentPolicy::TYPE_DATAREQUEST:
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
|
"type_xml requires requestingContext of type Document");
|
|
|
|
// We're checking for the external TYPE_XMLHTTPREQUEST here in case
|
|
// an addon creates a request with that type.
|
|
if (internalContentPolicyType ==
|
|
nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST ||
|
|
internalContentPolicyType ==
|
|
nsIContentPolicy::TYPE_XMLHTTPREQUEST) {
|
|
mimeTypeGuess = EmptyCString();
|
|
}
|
|
else {
|
|
MOZ_ASSERT(internalContentPolicyType ==
|
|
nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE,
|
|
"can not set mime type guess for unexpected internal type");
|
|
mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
|
"type_subrequest requires requestingContext of type Element");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_DTD: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
|
"type_dtd requires requestingContext of type Document");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_FONT: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_MEDIA: {
|
|
if (internalContentPolicyType == nsIContentPolicy::TYPE_INTERNAL_TRACK) {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("text/vtt");
|
|
}
|
|
else {
|
|
mimeTypeGuess = EmptyCString();
|
|
}
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
|
|
"type_media requires requestingContext of type Element");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_WEBSOCKET: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_CSP_REPORT: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_XSLT: {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("application/xml");
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
|
"type_xslt requires requestingContext of type Document");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_BEACON: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
MOZ_ASSERT(!requestingContext ||
|
|
requestingContext->NodeType() == nsIDOMNode::DOCUMENT_NODE,
|
|
"type_beacon requires requestingContext of type Document");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_FETCH: {
|
|
mimeTypeGuess = EmptyCString();
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_IMAGESET: {
|
|
MOZ_ASSERT(false, "contentPolicyType not supported yet");
|
|
break;
|
|
}
|
|
|
|
case nsIContentPolicy::TYPE_WEB_MANIFEST: {
|
|
mimeTypeGuess = NS_LITERAL_CSTRING("application/manifest+json");
|
|
requestingContext = aLoadInfo->LoadingNode();
|
|
break;
|
|
}
|
|
|
|
default:
|
|
// nsIContentPolicy::TYPE_INVALID
|
|
MOZ_ASSERT(false, "can not perform security check without a valid contentType");
|
|
}
|
|
|
|
int16_t shouldLoad = nsIContentPolicy::ACCEPT;
|
|
nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
|
|
aURI,
|
|
aLoadInfo->LoadingPrincipal(),
|
|
requestingContext,
|
|
mimeTypeGuess,
|
|
nullptr, //extra,
|
|
&shouldLoad,
|
|
nsContentUtils::GetContentPolicy(),
|
|
nsContentUtils::GetSecurityManager());
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
if (NS_CP_REJECTED(shouldLoad)) {
|
|
return NS_ERROR_CONTENT_BLOCKED;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
/*
|
|
* Based on the security flags provided in the loadInfo of the channel,
|
|
* doContentSecurityCheck() performs the following content security checks
|
|
* before opening the channel:
|
|
*
|
|
* (1) Same Origin Policy Check (if applicable)
|
|
* (2) Allow Cross Origin but perform sanity checks whether a principal
|
|
* is allowed to access the following URL.
|
|
* (3) Perform CORS check (if applicable)
|
|
* (4) ContentPolicy checks (Content-Security-Policy, Mixed Content, ...)
|
|
*
|
|
* @param aChannel
|
|
* The channel to perform the security checks on.
|
|
* @param aInAndOutListener
|
|
* The streamListener that is passed to channel->AsyncOpen2() that is now potentially
|
|
* wrappend within nsCORSListenerProxy() and becomes the corsListener that now needs
|
|
* to be set as new streamListener on the channel.
|
|
*/
|
|
nsresult
|
|
nsContentSecurityManager::doContentSecurityCheck(nsIChannel* aChannel,
|
|
nsCOMPtr<nsIStreamListener>& aInAndOutListener)
|
|
{
|
|
NS_ENSURE_ARG(aChannel);
|
|
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
|
|
|
if (!loadInfo) {
|
|
MOZ_ASSERT(false, "channel needs to have loadInfo to perform security checks");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
// if dealing with a redirected channel then we have already installed
|
|
// streamlistener and redirect proxies and so we are done.
|
|
if (loadInfo->GetInitialSecurityCheckDone()) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// make sure that only one of the five security flags is set in the loadinfo
|
|
// e.g. do not require same origin and allow cross origin at the same time
|
|
nsresult rv = ValidateSecurityFlags(loadInfo);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// since aChannel was openend using asyncOpen2() we have to make sure
|
|
// that redirects of that channel also get openend using asyncOpen2()
|
|
// please note that some implementations of ::AsyncOpen2 might already
|
|
// have set that flag to true (e.g. nsViewSourceChannel) in which case
|
|
// we just set the flag again.
|
|
rv = loadInfo->SetEnforceSecurity(true);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Allow subresource loads if TriggeringPrincipal is the SystemPrincipal.
|
|
// For example, allow user stylesheets to load XBL from external files.
|
|
if (nsContentUtils::IsSystemPrincipal(loadInfo->TriggeringPrincipal()) &&
|
|
loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT &&
|
|
loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_SUBDOCUMENT) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (loadInfo->GetSecurityMode() == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
|
rv = DoCORSChecks(aChannel, loadInfo, aInAndOutListener);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
rv = CheckChannel(aChannel);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsIURI> finalChannelURI;
|
|
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(finalChannelURI));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Perform all ContentPolicy checks (MixedContent, CSP, ...)
|
|
rv = DoContentSecurityChecks(finalChannelURI, loadInfo);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// now lets set the initalSecurityFlag for subsequent calls
|
|
rv = loadInfo->SetInitialSecurityCheckDone(true);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// all security checks passed - lets allow the load
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsContentSecurityManager::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
|
nsIChannel* aNewChannel,
|
|
uint32_t aRedirFlags,
|
|
nsIAsyncVerifyRedirectCallback *aCb)
|
|
{
|
|
nsCOMPtr<nsILoadInfo> loadInfo = aOldChannel->GetLoadInfo();
|
|
// Are we enforcing security using LoadInfo?
|
|
if (loadInfo && loadInfo->GetEnforceSecurity()) {
|
|
nsresult rv = CheckChannel(aNewChannel);
|
|
if (NS_FAILED(rv)) {
|
|
aOldChannel->Cancel(rv);
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
// Also verify that the redirecting server is allowed to redirect to the
|
|
// given URI
|
|
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
|
nsContentUtils::GetSecurityManager()->
|
|
GetChannelResultPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
|
|
|
|
nsCOMPtr<nsIURI> newURI;
|
|
aNewChannel->GetURI(getter_AddRefs(newURI));
|
|
nsCOMPtr<nsIURI> newOriginalURI;
|
|
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
|
|
|
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
|
|
|
const uint32_t flags =
|
|
nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
|
|
nsIScriptSecurityManager::DISALLOW_SCRIPT;
|
|
nsresult rv = nsContentUtils::GetSecurityManager()->
|
|
CheckLoadURIWithPrincipal(oldPrincipal, newURI, flags);
|
|
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
|
rv = nsContentUtils::GetSecurityManager()->
|
|
CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags);
|
|
}
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
aCb->OnRedirectVerifyCallback(NS_OK);
|
|
return NS_OK;
|
|
}
|
|
|
|
static void
|
|
AddLoadFlags(nsIRequest *aRequest, nsLoadFlags aNewFlags)
|
|
{
|
|
nsLoadFlags flags;
|
|
aRequest->GetLoadFlags(&flags);
|
|
flags |= aNewFlags;
|
|
aRequest->SetLoadFlags(flags);
|
|
}
|
|
|
|
/*
|
|
* Check that this channel passes all security checks. Returns an error code
|
|
* if this requesst should not be permitted.
|
|
*/
|
|
nsresult
|
|
nsContentSecurityManager::CheckChannel(nsIChannel* aChannel)
|
|
{
|
|
nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
|
|
MOZ_ASSERT(loadInfo);
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// Handle cookie policies
|
|
uint32_t cookiePolicy = loadInfo->GetCookiePolicy();
|
|
if (cookiePolicy == nsILoadInfo::SEC_COOKIES_SAME_ORIGIN) {
|
|
nsIPrincipal* loadingPrincipal = loadInfo->LoadingPrincipal();
|
|
|
|
// It doesn't matter what we pass for the third, data-inherits, argument.
|
|
// Any protocol which inherits won't pay attention to cookies anyway.
|
|
rv = loadingPrincipal->CheckMayLoad(uri, false, false);
|
|
if (NS_FAILED(rv)) {
|
|
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
|
|
}
|
|
}
|
|
else if (cookiePolicy == nsILoadInfo::SEC_COOKIES_OMIT) {
|
|
AddLoadFlags(aChannel, nsIRequest::LOAD_ANONYMOUS);
|
|
}
|
|
|
|
nsSecurityFlags securityMode = loadInfo->GetSecurityMode();
|
|
|
|
// CORS mode is handled by nsCORSListenerProxy
|
|
if (securityMode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS) {
|
|
if (NS_HasBeenCrossOrigin(aChannel)) {
|
|
loadInfo->MaybeIncreaseTainting(LoadTainting::CORS);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
// if none of the REQUIRE_SAME_ORIGIN flags are set, then SOP does not apply
|
|
if ((securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS) ||
|
|
(securityMode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED)) {
|
|
rv = DoSOPChecks(uri, loadInfo, aChannel);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
if ((securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS) ||
|
|
(securityMode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL)) {
|
|
if (NS_HasBeenCrossOrigin(aChannel)) {
|
|
loadInfo->MaybeIncreaseTainting(LoadTainting::Opaque);
|
|
}
|
|
// Please note that DoCheckLoadURIChecks should only be enforced for
|
|
// cross origin requests. If the flag SEC_REQUIRE_CORS_DATA_INHERITS is set
|
|
// within the loadInfo, then then CheckLoadURIWithPrincipal is performed
|
|
// within nsCorsListenerProxy
|
|
rv = DoCheckLoadURIChecks(uri, loadInfo);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// ==== nsIContentSecurityManager implementation =====
|
|
|
|
NS_IMETHODIMP
|
|
nsContentSecurityManager::PerformSecurityCheck(nsIChannel* aChannel,
|
|
nsIStreamListener* aStreamListener,
|
|
nsIStreamListener** outStreamListener)
|
|
{
|
|
nsCOMPtr<nsIStreamListener> inAndOutListener = aStreamListener;
|
|
nsresult rv = doContentSecurityCheck(aChannel, inAndOutListener);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
inAndOutListener.forget(outStreamListener);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsContentSecurityManager::IsURIPotentiallyTrustworthy(nsIURI* aURI, bool* aIsTrustWorthy)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
NS_ENSURE_ARG_POINTER(aURI);
|
|
NS_ENSURE_ARG_POINTER(aIsTrustWorthy);
|
|
|
|
*aIsTrustWorthy = false;
|
|
nsAutoCString scheme;
|
|
nsresult rv = aURI->GetScheme(scheme);
|
|
if (NS_FAILED(rv)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
// According to the specification, the user agent may choose to extend the
|
|
// trust to other, vendor-specific URL schemes. We use this for "resource:",
|
|
// which is technically a substituting protocol handler that is not limited to
|
|
// local resource mapping, but in practice is never mapped remotely as this
|
|
// would violate assumptions a lot of code makes.
|
|
if (scheme.EqualsLiteral("https") ||
|
|
scheme.EqualsLiteral("file") ||
|
|
scheme.EqualsLiteral("resource") ||
|
|
scheme.EqualsLiteral("app") ||
|
|
scheme.EqualsLiteral("wss")) {
|
|
*aIsTrustWorthy = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsAutoCString host;
|
|
rv = aURI->GetHost(host);
|
|
if (NS_FAILED(rv)) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (host.Equals("127.0.0.1") ||
|
|
host.Equals("localhost") ||
|
|
host.Equals("::1")) {
|
|
*aIsTrustWorthy = true;
|
|
return NS_OK;
|
|
}
|
|
return NS_OK;
|
|
}
|