From 95c46082414632687e3ddd52435d476ab9dc320f Mon Sep 17 00:00:00 2001 From: janekptacijarabaci Date: Sun, 22 Apr 2018 20:38:02 +0200 Subject: Bug 1329288: Allow content policy consumers to identify contentPolicy checks from docshell --- docshell/base/nsDocShell.cpp | 14 +++++++++++++- dom/security/nsCSPContext.cpp | 5 +++-- toolkit/modules/addons/WebRequestContent.js | 10 ++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index f3db4a3cb..b1fcc5c23 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -139,6 +139,7 @@ #include "nsISiteSecurityService.h" #include "nsStructuredCloneContainer.h" #include "nsIStructuredCloneContainer.h" +#include "nsISupportsPrimitives.h" #ifdef MOZ_PLACES #include "nsIFaviconService.h" #include "mozIPlacesPendingOperation.h" @@ -9931,13 +9932,24 @@ nsDocShell::InternalLoad(nsIURI* aURI, #endif } + // Since Content Policy checks are performed within docShell as well as + // the ContentSecurityManager we need a reliable way to let certain + // nsIContentPolicy consumers ignore duplicate calls. Let's use the 'extra' + // argument to pass a specific identifier. + nsCOMPtr extraStr = + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + NS_NAMED_LITERAL_STRING(msg, "conPolCheckFromDocShell"); + rv = extraStr->SetData(msg); + NS_ENSURE_SUCCESS(rv, rv); + int16_t shouldLoad = nsIContentPolicy::ACCEPT; rv = NS_CheckContentLoadPolicy(contentType, aURI, aTriggeringPrincipal, requestingContext, EmptyCString(), // mime guess - nullptr, // extra + extraStr, // extra &shouldLoad); if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) { diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index a7517f65e..979bd915f 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -171,9 +171,10 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType, } } - // aExtra is only non-null if the channel got redirected. - bool wasRedirected = (aExtra != nullptr); + // aExtra holds the original URI of the channel if the + // channel got redirected (until we fix Bug 1332422). nsCOMPtr originalURI = do_QueryInterface(aExtra); + bool wasRedirected = originalURI; bool permitted = permitsInternal(dir, aContentLocation, diff --git a/toolkit/modules/addons/WebRequestContent.js b/toolkit/modules/addons/WebRequestContent.js index 219675e5b..f044a1cd4 100644 --- a/toolkit/modules/addons/WebRequestContent.js +++ b/toolkit/modules/addons/WebRequestContent.js @@ -80,6 +80,16 @@ var ContentPolicy = { shouldLoad(policyType, contentLocation, requestOrigin, node, mimeTypeGuess, extra, requestPrincipal) { + + // Loads of TYPE_DOCUMENT and TYPE_SUBDOCUMENT perform a ConPol check + // within docshell as well as within the ContentSecurityManager. To avoid + // duplicate evaluations we ignore ConPol checks performed within docShell. + if (extra instanceof Ci.nsISupportsString) { + if (extra.data === "conPolCheckFromDocShell") { + return Ci.nsIContentPolicy.ACCEPT; + } + } + if (requestPrincipal && Services.scriptSecurityManager.isSystemPrincipal(requestPrincipal)) { return Ci.nsIContentPolicy.ACCEPT; -- cgit v1.2.3