diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index dda6a824d..4b86477f7 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -10053,6 +10053,9 @@ nsDocShell::InternalLoad(nsIURI* aURI, int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(contentType, aURI, + // This is a top-level load, so the loading + // principal is null. + nullptr, aTriggeringPrincipal, requestingContext, EmptyCString(), // mime guess diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index 35f5ef676..ce316a939 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -1571,7 +1571,8 @@ WebSocketImpl::Init(JSContext* aCx, int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_WEBSOCKET, uri, - aPrincipal, + aPrincipal, // loading principal + aPrincipal, // triggering principal originDoc, EmptyCString(), nullptr, diff --git a/dom/base/nsContentPolicyUtils.h b/dom/base/nsContentPolicyUtils.h index 3984ede54..9b4de2427 100644 --- a/dom/base/nsContentPolicyUtils.h +++ b/dom/base/nsContentPolicyUtils.h @@ -152,7 +152,7 @@ NS_CP_ContentTypeName(uint32_t contentType) return NS_ERROR_FAILURE; \ \ return policy-> action (contentType, contentLocation, requestOrigin, \ - context, mimeType, extra, originPrincipal, \ + context, mimeType, extra, triggeringPrincipal, \ decision); \ PR_END_MACRO @@ -160,7 +160,7 @@ NS_CP_ContentTypeName(uint32_t contentType) #define CHECK_CONTENT_POLICY_WITH_SERVICE(action, _policy) \ PR_BEGIN_MACRO \ return _policy-> action (contentType, contentLocation, requestOrigin, \ - context, mimeType, extra, originPrincipal, \ + context, mimeType, extra, triggeringPrincipal, \ decision); \ PR_END_MACRO @@ -173,14 +173,18 @@ NS_CP_ContentTypeName(uint32_t contentType) #define CHECK_PRINCIPAL_AND_DATA(action) \ nsCOMPtr requestOrigin; \ PR_BEGIN_MACRO \ - if (originPrincipal) { \ + if (loadingPrincipal) { \ nsCOMPtr secMan = aSecMan; \ if (!secMan) { \ secMan = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID); \ } \ if (secMan) { \ bool isSystem; \ - nsresult rv = secMan->IsSystemPrincipal(originPrincipal, \ + /* We exempt most loads into any document with the system principal \ + * from content policy checks, mostly as an optimization. Which means \ + * that we need to apply this check to the loading principal, not the \ + * principal that triggered the load. */ \ + nsresult rv = secMan->IsSystemPrincipal(loadingPrincipal, \ &isSystem); \ NS_ENSURE_SUCCESS(rv, rv); \ if (isSystem && contentType != nsIContentPolicy::TYPE_DOCUMENT) { \ @@ -203,31 +207,33 @@ NS_CP_ContentTypeName(uint32_t contentType) dataPolicy-> action (externalType, contentLocation, \ requestOrigin, context, \ mimeType, extra, \ - originPrincipal, decision); \ + triggeringPrincipal, decision);\ } \ } \ } \ return NS_OK; \ } \ } \ - nsresult rv = originPrincipal->GetURI(getter_AddRefs(requestOrigin)); \ + nsresult rv = loadingPrincipal->GetURI(getter_AddRefs(requestOrigin)); \ NS_ENSURE_SUCCESS(rv, rv); \ } \ PR_END_MACRO /** * Alias for calling ShouldLoad on the content policy service. Parameters are - * the same as nsIContentPolicy::shouldLoad, except for the originPrincipal - * parameter, which should be non-null if possible, and the last two - * parameters, which can be used to pass in pointer to some useful services if - * the caller already has them. The origin URI to pass to shouldLoad will be - * the URI of originPrincipal, unless originPrincipal is null (in which case a - * null origin URI will be passed). + * the same as nsIContentPolicy::shouldLoad, except for the loadingPrincipal + * and triggeringPrincipal parameters (which should be non-null if possible, + * and have the same semantics as in LoadInfo), and the last two parameters, + * which can be used to pass in pointer to some useful services if the caller + * already has them. The origin URI to pass to shouldLoad will be the URI of + * loadingPrincipal, unless loadingPrincipal is null (in which case a null + * origin URI will be passed). */ inline nsresult NS_CheckContentLoadPolicy(uint32_t contentType, nsIURI *contentLocation, - nsIPrincipal *originPrincipal, + nsIPrincipal *loadingPrincipal, + nsIPrincipal *triggeringPrincipal, nsISupports *context, const nsACString &mimeType, nsISupports *extra, @@ -244,17 +250,19 @@ NS_CheckContentLoadPolicy(uint32_t contentType, /** * Alias for calling ShouldProcess on the content policy service. Parameters - * are the same as nsIContentPolicy::shouldLoad, except for the originPrincipal - * parameter, which should be non-null if possible, and the last two - * parameters, which can be used to pass in pointer to some useful services if - * the caller already has them. The origin URI to pass to shouldLoad will be - * the URI of originPrincipal, unless originPrincipal is null (in which case a - * null origin URI will be passed). + * are the same as nsIContentPolicy::shouldLoad, except for the and + * triggeringPrincipal parameters (which should be non-null if possible, and + * have the same semantics as in nsLoadInfo), and the last parameter, which + * can be used to pass in a pointer to a useful service if the caller already + * has it. The origin URI to pass to shouldLoad will be the URI of + * loadingPrincipal, unless loadingPrincipal is null (in which case a null + * origin URI will be passed). */ inline nsresult NS_CheckContentProcessPolicy(uint32_t contentType, nsIURI *contentLocation, - nsIPrincipal *originPrincipal, + nsIPrincipal *loadingPrincipal, + nsIPrincipal *triggeringPrincipal, nsISupports *context, const nsACString &mimeType, nsISupports *extra, diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 8cd788b01..7eb7a8e1a 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -3308,6 +3308,7 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext, rv = NS_CheckContentLoadPolicy(aContentType, aURI, aLoadingPrincipal, + aLoadingPrincipal, // triggering principal aContext, EmptyCString(), //mime guess nullptr, //extra diff --git a/dom/base/nsIContentPolicy.idl b/dom/base/nsIContentPolicy.idl index 200b97fbc..ae347729d 100644 --- a/dom/base/nsIContentPolicy.idl +++ b/dom/base/nsIContentPolicy.idl @@ -35,8 +35,11 @@ interface nsIContentPolicy : nsIContentPolicyBase * not be null * * @param aRequestOrigin OPTIONAL. the location of the resource that - * initiated this load request; can be null if - * inapplicable + * that is loading the request. This will generally + * be the URI of the loading principal for the + * resulting request (as determined by its + * LoadInfo), but may vary depending on the + * caller. Can be null if inapplicable. * * @param aContext OPTIONAL. the nsIDOMNode or nsIDOMWindow that * initiated the request, or something that can QI @@ -56,8 +59,12 @@ interface nsIContentPolicy : nsIContentPolicyBase * @param aRequestPrincipal an OPTIONAL argument, defines the principal that * caused the load. This is optional only for * non-gecko code: all gecko code should set this - * argument. For navigation events, this is - * the principal of the page that caused this load. + * argument. This should generally be the same as + * the triggering principal for the resulting + * request (as determined by its LoadInfo), but may + * vary depending on the caller. Sometimes it will + * be the loading principal or final channel + * principal instead. * * @return ACCEPT or REJECT_* * diff --git a/dom/base/nsObjectLoadingContent.cpp b/dom/base/nsObjectLoadingContent.cpp index 5bd257a79..f031086c2 100644 --- a/dom/base/nsObjectLoadingContent.cpp +++ b/dom/base/nsObjectLoadingContent.cpp @@ -1559,7 +1559,8 @@ nsObjectLoadingContent::CheckLoadPolicy(int16_t *aContentPolicy) *aContentPolicy = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType, mURI, - doc->NodePrincipal(), + doc->NodePrincipal(), // loading principal + doc->NodePrincipal(), // triggering principal thisContent, mContentType, nullptr, //extra @@ -1610,7 +1611,8 @@ nsObjectLoadingContent::CheckProcessPolicy(int16_t *aContentPolicy) nsresult rv = NS_CheckContentProcessPolicy(objectType, mURI ? mURI : mBaseURI, - doc->NodePrincipal(), + doc->NodePrincipal(), // loading principal + doc->NodePrincipal(), // triggering principal static_cast(this), mContentType, nullptr, //extra diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp index 4d4f15d64..51c2cb98c 100644 --- a/dom/html/ImageDocument.cpp +++ b/dom/html/ImageDocument.cpp @@ -98,11 +98,14 @@ ImageListener::OnStartRequest(nsIRequest* request, nsISupports *ctxt) if (secMan) { secMan->GetChannelResultPrincipal(channel, getter_AddRefs(channelPrincipal)); } + + nsCOMPtr loadInfo = channel->GetLoadInfo(); int16_t decision = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentProcessPolicy(nsIContentPolicy::TYPE_INTERNAL_IMAGE, channelURI, channelPrincipal, + loadInfo ? loadInfo->TriggeringPrincipal() : nullptr, domWindow->GetFrameElementInternal(), mimeType, nullptr, diff --git a/dom/plugins/base/nsPluginStreamListenerPeer.cpp b/dom/plugins/base/nsPluginStreamListenerPeer.cpp index 0476315d5..ffe7081dd 100644 --- a/dom/plugins/base/nsPluginStreamListenerPeer.cpp +++ b/dom/plugins/base/nsPluginStreamListenerPeer.cpp @@ -504,7 +504,8 @@ nsPluginStreamListenerPeer::OnStartRequest(nsIRequest *request, int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentProcessPolicy(nsIContentPolicy::TYPE_OBJECT_SUBREQUEST, mURL, - principal, + principal, // loading principal + principal, // triggering principal element, contentType, nullptr, diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 69eee82e3..7418535b4 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -451,7 +451,8 @@ ScriptLoader::CheckContentPolicy(nsIDocument* aDocument, int16_t shouldLoad = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType, aURI, - aDocument->NodePrincipal(), + aDocument->NodePrincipal(), // loading principal + aDocument->NodePrincipal(), // triggering principal aContext, NS_LossyConvertUTF16toASCII(aType), nullptr, //extra diff --git a/dom/security/nsContentSecurityManager.cpp b/dom/security/nsContentSecurityManager.cpp index d4193e087..bcbfb52b6 100644 --- a/dom/security/nsContentSecurityManager.cpp +++ b/dom/security/nsContentSecurityManager.cpp @@ -577,18 +577,11 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo) MOZ_ASSERT(false, "can not perform security check without a valid contentType"); } - // For document loads we use the triggeringPrincipal as the originPrincipal. - // Note the the loadingPrincipal for loads of TYPE_DOCUMENT is a nullptr. - nsCOMPtr principal = - (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT || - contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) - ? aLoadInfo->TriggeringPrincipal() - : aLoadInfo->LoadingPrincipal(); - int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(internalContentPolicyType, uri, - principal, + aLoadInfo->LoadingPrincipal(), + aLoadInfo->TriggeringPrincipal(), requestingContext, mimeTypeGuess, nullptr, //extra, diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index ea9985df5..e1057a20f 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -260,10 +260,14 @@ public: rv = NS_NewURI(getter_AddRefs(uri), url, nullptr, nullptr); NS_ENSURE_SUCCESS(rv, false); int16_t decision = nsIContentPolicy::ACCEPT; - rv = NS_CheckContentLoadPolicy(aLoadInfo->InternalContentPolicyType(), uri, + rv = NS_CheckContentLoadPolicy(aLoadInfo->InternalContentPolicyType(), + uri, aLoadInfo->LoadingPrincipal(), - aLoadInfo->LoadingNode(), EmptyCString(), - nullptr, &decision); + aLoadInfo->TriggeringPrincipal(), + aLoadInfo->LoadingNode(), + EmptyCString(), + nullptr, + &decision); NS_ENSURE_SUCCESS(rv, false); return decision == nsIContentPolicy::ACCEPT; } diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index c22b3d07a..f0182a78b 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -599,7 +599,8 @@ ServiceWorkerManager::Register(mozIDOMWindow* aWindow, int16_t decision = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER, aScriptURI, - documentPrincipal, + documentPrincipal, // loading principal + documentPrincipal, // triggering principal doc, EmptyCString(), nullptr, diff --git a/dom/xml/nsXMLContentSink.cpp b/dom/xml/nsXMLContentSink.cpp index 877fe5f70..a4749191d 100644 --- a/dom/xml/nsXMLContentSink.cpp +++ b/dom/xml/nsXMLContentSink.cpp @@ -697,7 +697,8 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement, int16_t decision = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_XSLT, url, - mDocument->NodePrincipal(), + mDocument->NodePrincipal(), // loading principal + mDocument->NodePrincipal(), // triggering principal aElement, type, nullptr, diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index 6e46389e1..01429f27e 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -568,7 +568,8 @@ ShouldLoadCachedImage(imgRequest* aImgRequest, int16_t decision = nsIContentPolicy::REJECT_REQUEST; rv = NS_CheckContentLoadPolicy(aPolicyType, contentLocation, - aLoadingPrincipal, + aLoadingPrincipal, // loading principal + aLoadingPrincipal, // triggering principal aLoadingContext, EmptyCString(), //mime guess nullptr, //aExtra diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index 8f3bff07a..26fddad44 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -1364,7 +1364,8 @@ FontFaceSet::IsFontLoadAllowed(nsIURI* aFontLocation, nsIPrincipal* aPrincipal) int16_t shouldLoad = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_FONT, aFontLocation, - aPrincipal, + aPrincipal, // loading principal + aPrincipal, // triggering principal mDocument, EmptyCString(), // mime type nullptr, // aExtra diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index b032e6b45..c137122e5 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -1028,14 +1028,15 @@ Loader::ObsoleteSheet(nsIURI* aURI) } nsresult -Loader::CheckContentPolicy(nsIPrincipal* aSourcePrincipal, - nsIURI* aTargetURI, - nsISupports* aContext, - bool aIsPreload) +Loader::CheckContentPolicy(nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsIURI* aTargetURI, + nsISupports* aContext, + bool aIsPreload) { // When performing a system load (e.g. aUseSystemPrincipal = true) - // then aSourcePrincipal == null; don't consult content policies. - if (!aSourcePrincipal) { + // then aLoadingPrincipal == null; don't consult content policies. + if (!aLoadingPrincipal) { return NS_OK; } @@ -1046,7 +1047,8 @@ Loader::CheckContentPolicy(nsIPrincipal* aSourcePrincipal, int16_t shouldLoad = nsIContentPolicy::ACCEPT; nsresult rv = NS_CheckContentLoadPolicy(contentPolicyType, aTargetURI, - aSourcePrincipal, + aLoadingPrincipal, + aTriggeringPrincipal, aContext, NS_LITERAL_CSTRING("text/css"), nullptr, //extra param @@ -2033,15 +2035,20 @@ Loader::LoadStyleLink(nsIContent* aElement, NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_INITIALIZED); - nsIPrincipal* principal = - aElement ? aElement->NodePrincipal() : mDocument->NodePrincipal(); + nsIPrincipal* loadingPrincipal = aElement ? aElement->NodePrincipal() + : mDocument->NodePrincipal(); + //SHOULD BE: + //nsIPrincipal* principal = aTriggeringPrincipal ? aTriggeringPrincipal + // : loadingPrincipal; + nsIPrincipal* principal = loadingPrincipal; + nsISupports* context = aElement; if (!context) { context = mDocument; } - nsresult rv = CheckContentPolicy(principal, aURL, context, false); + nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aURL, context, false); if (NS_WARN_IF(NS_FAILED(rv))) { // Don't fire the error event if our document is loaded as data. We're // supposed to not even try to do loads in that case... Unfortunately, we @@ -2182,13 +2189,18 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet, owningNode = topSheet->GetOwnerNode(); } - nsISupports* context = owningNode; - if (!context) { + nsISupports* context = nullptr; + nsIPrincipal* loadingPrincipal = nullptr; + if (owningNode) { + context = owningNode; + loadingPrincipal = owningNode->NodePrincipal(); + } else if (mDocument) { context = mDocument; + loadingPrincipal = mDocument->NodePrincipal(); } nsIPrincipal* principal = aParentSheet->Principal(); - nsresult rv = CheckContentPolicy(principal, aURL, context, false); + nsresult rv = CheckContentPolicy(loadingPrincipal, principal, aURL, context, false); NS_ENSURE_SUCCESS(rv, rv); SheetLoadData* parentData = nullptr; @@ -2345,7 +2357,11 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL, return NS_ERROR_NOT_AVAILABLE; } - nsresult rv = CheckContentPolicy(aOriginPrincipal, aURL, mDocument, aIsPreload); + nsCOMPtr loadingPrincipal = (aOriginPrincipal && mDocument + ? mDocument->NodePrincipal() + : nullptr); + nsresult rv = CheckContentPolicy(loadingPrincipal, aOriginPrincipal, + aURL, mDocument, aIsPreload); NS_ENSURE_SUCCESS(rv, rv); StyleSheetState state; diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 7c40975d2..162d9eaad 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -453,7 +453,8 @@ public: private: friend class SheetLoadData; - nsresult CheckContentPolicy(nsIPrincipal* aSourcePrincipal, + nsresult CheckContentPolicy(nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aTriggeringPrincipal, nsIURI* aTargetURI, nsISupports* aContext, bool aIsPreload); diff --git a/toolkit/modules/addons/WebRequestContent.js b/toolkit/modules/addons/WebRequestContent.js index f044a1cd4..d3f52bc6a 100644 --- a/toolkit/modules/addons/WebRequestContent.js +++ b/toolkit/modules/addons/WebRequestContent.js @@ -173,7 +173,10 @@ var ContentPolicy = { windowId, parentWindowId}; if (requestOrigin) { - data.originUrl = requestOrigin.spec; + data.documentUrl = requestOrigin.spec; + } + if (requestPrincipal && requestPrincipal.URI) { + data.originUrl = requestPrincipal.URI.spec; } if (block) { let rval = mm.sendSyncMessage("WebRequest:ShouldLoad", data);