Backed out 3 changesets (bug 1409200) as requested by dev

Backed out changeset ea10214aa35f (bug 1409200)
Backed out changeset a66ea7d7f812 (bug 1409200)
Backed out changeset e8a83b1e7e08 (bug 1409200)
This commit is contained in:
Norisz Fay 2023-06-09 15:11:48 +03:00
parent d4a4ca7c15
commit ceef84983b
23 changed files with 117 additions and 389 deletions

View File

@ -915,10 +915,11 @@ function isFrameBlockedByCSP(node) {
const res = node.ownerDocument.csp.shouldLoad(
Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
null, // nsICSPEventListener
null, // nsILoadInfo
uri,
null, // aOriginalURIIfRedirect
false // aSendViolationReports
false, // aSendViolationReports
null, // aNonce
false // aParserCreated
);
return res !== Ci.nsIContentPolicy.ACCEPT;

View File

@ -344,10 +344,11 @@ interface nsIContentSecurityPolicy : nsISerializable
*/
short shouldLoad(in nsContentPolicyType aContentType,
in nsICSPEventListener aCSPEventListener,
in nsILoadInfo aLoadInfo,
in nsIURI aContentLocation,
in nsIURI aOriginalURIIfRedirect,
in bool aSendViolationReports);
in bool aSendViolationReports,
in AString aNonce,
in boolean aParserCreated);
%{ C++
// nsIObserver topic to fire when the policy encounters a violation.

View File

@ -407,9 +407,6 @@ nsresult ScriptLoader::CheckContentPolicy(Document* aDocument,
requestingNode, nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
contentPolicyType);
secCheckLoadInfo->SetIntegrityMetadata(
aRequest->mIntegrity.GetIntegrityString());
// snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT ||
contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) {
@ -626,9 +623,6 @@ nsresult ScriptLoader::StartLoadInternal(
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
loadInfo->SetIntegrityMetadata(aRequest->mIntegrity.GetIntegrityString());
// snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT ||
contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) {
@ -636,6 +630,7 @@ nsresult ScriptLoader::StartLoadInternal(
nsString* cspNonce =
static_cast<nsString*>(context->GetProperty(nsGkAtoms::nonce));
if (cspNonce) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
loadInfo->SetCspNonce(*cspNonce);
}
}

View File

@ -130,9 +130,10 @@ static void BlockedContentSourceToString(
NS_IMETHODIMP
nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
nsICSPEventListener* aCSPEventListener,
nsILoadInfo* aLoadInfo, nsIURI* aContentLocation,
nsIURI* aContentLocation,
nsIURI* aOriginalURIIfRedirect,
bool aSendViolationReports, int16_t* outDecision) {
bool aSendViolationReports, const nsAString& aNonce,
bool aParserCreated, int16_t* outDecision) {
if (CSPCONTEXTLOGENABLED()) {
CSPCONTEXTLOG(("nsCSPContext::ShouldLoad, aContentLocation: %s",
aContentLocation->GetSpecOrDefault().get()));
@ -161,10 +162,11 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
bool permitted = permitsInternal(
dir,
nullptr, // aTriggeringElement
aCSPEventListener, aLoadInfo, aContentLocation, aOriginalURIIfRedirect,
aCSPEventListener, aContentLocation, aOriginalURIIfRedirect, aNonce,
false, // allow fallback to default-src
aSendViolationReports,
true); // send blocked URI in violation reports
true, // send blocked URI in violation reports
aParserCreated);
*outDecision =
permitted ? nsIContentPolicy::ACCEPT : nsIContentPolicy::REJECT_SERVER;
@ -181,17 +183,18 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
bool nsCSPContext::permitsInternal(
CSPDirective aDir, Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener, nsILoadInfo* aLoadInfo,
nsIURI* aContentLocation, nsIURI* aOriginalURIIfRedirect, bool aSpecific,
bool aSendViolationReports, bool aSendContentLocationInViolationReports) {
nsICSPEventListener* aCSPEventListener, nsIURI* aContentLocation,
nsIURI* aOriginalURIIfRedirect, const nsAString& aNonce, bool aSpecific,
bool aSendViolationReports, bool aSendContentLocationInViolationReports,
bool aParserCreated) {
EnsureIPCPoliciesRead();
bool permits = true;
nsAutoString violatedDirective;
for (uint32_t p = 0; p < mPolicies.Length(); p++) {
if (!mPolicies[p]->permits(aDir, aLoadInfo, aContentLocation,
if (!mPolicies[p]->permits(aDir, aContentLocation, aNonce,
!!aOriginalURIIfRedirect, aSpecific,
violatedDirective)) {
aParserCreated, violatedDirective)) {
// If the policy is violated and not report-only, reject the load and
// report to the console
if (!mPolicies[p]->getReportOnlyFlag()) {
@ -1687,12 +1690,13 @@ nsCSPContext::PermitsAncestry(nsILoadInfo* aLoadInfo,
permitsInternal(nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE,
nullptr, // triggering element
nullptr, // nsICSPEventListener
nullptr, // nsILoadInfo
ancestorsArray[a],
nullptr, // no redirect here.
u""_ns, // no nonce
true, // specific, do not use default-src
true, // send violation reports
okToSendAncestor);
okToSendAncestor,
false); // not parser created
if (!permits) {
*outPermitsAncestry = false;
}
@ -1722,12 +1726,13 @@ nsCSPContext::Permits(Element* aTriggeringElement,
}
}
*outPermits = permitsInternal(aDir, aTriggeringElement, aCSPEventListener,
nullptr, // no nsILoadInfo
aURI,
nullptr, // no original (pre-redirect) URI
aSpecific, aSendViolationReports,
true); // send blocked URI in violation reports
*outPermits =
permitsInternal(aDir, aTriggeringElement, aCSPEventListener, aURI,
nullptr, // no original (pre-redirect) URI
u""_ns, // no nonce
aSpecific, aSendViolationReports,
true, // send blocked URI in violation reports
false); // not parser created
if (CSPCONTEXTLOGENABLED()) {
CSPCONTEXTLOG(("nsCSPContext::Permits, aUri: %s, aDir: %s, isAllowed: %s",

View File

@ -154,10 +154,11 @@ class nsCSPContext : public nsIContentSecurityPolicy {
bool permitsInternal(CSPDirective aDir,
mozilla::dom::Element* aTriggeringElement,
nsICSPEventListener* aCSPEventListener,
nsILoadInfo* aLoadInfo, nsIURI* aContentLocation,
nsIURI* aOriginalURIIfRedirect, bool aSpecific,
nsIURI* aContentLocation, nsIURI* aOriginalURIIfRedirect,
const nsAString& aNonce, bool aSpecific,
bool aSendViolationReports,
bool aSendContentLocationInViolationReports);
bool aSendContentLocationInViolationReports,
bool aParserCreated);
// helper to report inline script/style violations
void reportInlineViolation(CSPDirective aDirective,

View File

@ -111,6 +111,7 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
}
nsContentPolicyType contentType = aLoadInfo->InternalContentPolicyType();
bool parserCreatedScript = aLoadInfo->GetParserCreatedScript();
nsCOMPtr<nsICSPEventListener> cspEventListener;
nsresult rv =
@ -135,6 +136,10 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
return NS_OK;
}
nsAutoString cspNonce;
rv = aLoadInfo->GetCspNonce(cspNonce);
NS_ENSURE_SUCCESS(rv, rv);
// 1) Apply speculate CSP for preloads
bool isPreload = nsContentUtils::IsPreloadType(contentType);
@ -143,9 +148,9 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
if (preloadCsp) {
// obtain the enforcement decision
rv = preloadCsp->ShouldLoad(
contentType, cspEventListener, aLoadInfo, aContentLocation,
contentType, cspEventListener, aContentLocation,
nullptr, // no redirect, aOriginal URL is null.
false, aDecision);
false, cspNonce, parserCreatedScript, aDecision);
NS_ENSURE_SUCCESS(rv, rv);
// if the preload policy already denied the load, then there
@ -187,9 +192,10 @@ bool subjectToCSP(nsIURI* aURI, nsContentPolicyType aContentType) {
// obtain the enforcement decision
rv = csp->ShouldLoad(
contentType, cspEventListener, aLoadInfo, aContentLocation,
contentType, cspEventListener, aContentLocation,
originalURI, // no redirect, unless it's a frame navigation.
!isPreload && aLoadInfo->GetSendCSPViolationEvents(), aDecision);
!isPreload && aLoadInfo->GetSendCSPViolationEvents(), cspNonce,
parserCreatedScript, aDecision);
if (NS_CP_REJECTED(*aDecision)) {
NS_SetRequestBlockingReason(
@ -344,6 +350,10 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
aLoadInfo->GetCspEventListener(getter_AddRefs(cspEventListener));
MOZ_ALWAYS_SUCCEEDS(rv);
nsAutoString cspNonce;
rv = aLoadInfo->GetCspNonce(cspNonce);
MOZ_ALWAYS_SUCCEEDS(rv);
bool isPreload = nsContentUtils::IsPreloadType(policyType);
/* On redirect, if the content policy is a preload type, rejecting the
@ -352,6 +362,7 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
*/
int16_t decision = nsIContentPolicy::ACCEPT;
bool parserCreatedScript = aLoadInfo->GetParserCreatedScript();
// 1) Apply speculative CSP for preloads
if (isPreload) {
@ -360,11 +371,12 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
// Pass originalURI to indicate the redirect
preloadCsp->ShouldLoad(
policyType, // load type per nsIContentPolicy (uint32_t)
cspEventListener, aLoadInfo,
cspEventListener,
aNewURI, // nsIURI
aOriginalURI, // Original nsIURI
true, // aSendViolationReports
&decision);
cspNonce, // nonce
parserCreatedScript, &decision);
// if the preload policy already denied the load, then there
// is no point in checking the real policy
@ -380,11 +392,12 @@ nsresult CSPService::ConsultCSPForRedirect(nsIURI* aOriginalURI,
if (csp) {
// Pass originalURI to indicate the redirect
csp->ShouldLoad(policyType, // load type per nsIContentPolicy (uint32_t)
cspEventListener, aLoadInfo,
cspEventListener,
aNewURI, // nsIURI
aOriginalURI, // Original nsIURI
true, // aSendViolationReports
&decision);
cspNonce, // nonce
parserCreatedScript, &decision);
if (NS_CP_REJECTED(decision)) {
aCancelCode = Some(NS_ERROR_DOM_BAD_URI);
return NS_BINDING_FAILED;

View File

@ -21,16 +21,12 @@
#include "nsReadableUtils.h"
#include "nsSandboxFlags.h"
#include "nsServiceManagerUtils.h"
#include "nsWhitespaceTokenizer.h"
#include "mozilla/Components.h"
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/StaticPrefs_security.h"
using mozilla::dom::SRIMetadata;
#define DEFAULT_PORT -1
static mozilla::LogModule* GetCspUtilsLog() {
@ -1080,151 +1076,14 @@ nsCSPDirective::~nsCSPDirective() {
}
}
// This check only considers types "script-like"
// (https://fetch.spec.whatwg.org/#request-destination-script-like) that can
// also have integrity metadata.
static bool IsScriptLikeWithIntegrity(nsContentPolicyType aType) {
switch (aType) {
case nsIContentPolicy::TYPE_SCRIPT:
case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
case nsIContentPolicy::TYPE_INTERNAL_MODULE:
case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
return true;
default:
return false;
}
}
// https://www.w3.org/TR/SRI/#parse-metadata
// This function is similar to SRICheck::IntegrityMetadata, but also keeps
// SRI metadata with weaker hashes.
// CSP treats "no metadata" and empty results the same way.
static nsTArray<SRIMetadata> ParseSRIMetadata(const nsAString& aMetadata) {
// Step 1. Let result be the empty set.
// Step 2. Let empty be equal to true.
nsTArray<SRIMetadata> result;
NS_ConvertUTF16toUTF8 metadataList(aMetadata);
nsAutoCString token;
// Step 3. For each token returned by splitting metadata on spaces:
nsCWhitespaceTokenizer tokenizer(metadataList);
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
// Step 3.1. Set empty to false.
// Step 3.3. Parse token per the grammar in integrity metadata.
SRIMetadata metadata(token);
// Step 3.2. If token is not a valid metadata, skip the remaining steps, and
// proceed to the next token.
if (metadata.IsMalformed()) {
continue;
}
// Step 3.4. Let algorithm be the alg component of token.
// Step 3.5. If algorithm is a hash function recognized by the user agent,
// add the
// parsed token to result.
if (metadata.IsAlgorithmSupported()) {
result.AppendElement(metadata);
}
}
// Step 4. Return no metadata if empty is true, otherwise return result.
return result;
}
bool nsCSPDirective::permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo,
nsIURI* aUri, const nsAString& aNonce,
bool nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce,
bool aWasRedirected, bool aReportOnly,
bool aUpgradeInsecure, bool aParserCreated) const {
MOZ_ASSERT(equals(aDirective) || isDefaultDirective());
if (CSPUTILSLOGENABLED()) {
CSPUTILSLOG(
("nsCSPDirective::permits, aUri: %s", aUri->GetSpecOrDefault().get()));
}
// https://w3c.github.io/webappsec-csp/#script-pre-request
if (aLoadInfo) {
// Step 1. If requests destination is script-like:
if (IsScriptLikeWithIntegrity(aLoadInfo->InternalContentPolicyType())) {
MOZ_ASSERT(aDirective == CSPDirective::SCRIPT_SRC_ELEM_DIRECTIVE);
// Step 1.2. Let integrity expressions be the set of source expressions in
// directives value that match the hash-source grammar.
nsTArray<nsCSPHashSrc*> integrityExpressions;
for (uint32_t i = 0; i < mSrcs.Length(); i++) {
if (mSrcs[i]->isHash()) {
integrityExpressions.AppendElement(
static_cast<nsCSPHashSrc*>(mSrcs[i]));
}
}
// Step 1.3. If integrity expressions is not empty:
if (!integrityExpressions.IsEmpty()) {
// Step 1.3.1. Let integrity sources be the result of executing the
// algorithm defined in [SRI 3.3.3 Parse metadata] on requests
// integrity metadata.
nsAutoString integrityMetadata;
aLoadInfo->GetIntegrityMetadata(integrityMetadata);
nsTArray<SRIMetadata> integritySources =
ParseSRIMetadata(integrityMetadata);
// Step 1.3.2. If integrity sources is "no metadata" or an empty set,
// skip the remaining substeps.
if (!integritySources.IsEmpty()) {
// Step 1.3.3. Let bypass due to integrity match be true.
bool bypass = true;
nsAutoCString sourceAlgorithmUTF8;
nsAutoCString sourceHashUTF8;
nsAutoString sourceAlgorithm;
nsAutoString sourceHash;
nsAutoString algorithm;
nsAutoString hash;
// Step 1.3.4. For each source of integrity sources:
for (const SRIMetadata& source : integritySources) {
source.GetAlgorithm(&sourceAlgorithmUTF8);
sourceAlgorithm = NS_ConvertUTF8toUTF16(sourceAlgorithmUTF8);
source.GetHash(0, &sourceHashUTF8);
sourceHash = NS_ConvertUTF8toUTF16(sourceHashUTF8);
// Step 1.3.4.1 If directives value does not contain a source
// expression whose hash-algorithm is an ASCII case-insensitive
// match for sources hash-algorithm, and whose base64-value is
// identical to sources base64-value, then set bypass due to
// integrity match to false.
bool found = false;
for (const nsCSPHashSrc* hashSrc : integrityExpressions) {
hashSrc->getAlgorithm(algorithm);
hashSrc->getHash(hash);
// The nsCSPHashSrc constructor lowercases algorithm, so this
// is case-insensitive.
if (sourceAlgorithm == algorithm && sourceHash == hash) {
found = true;
break;
}
}
if (!found) {
bypass = false;
break;
}
}
// Step 1.3.5. If bypass due to integrity match is true, return
// "Allowed".
if (bypass) {
return true;
}
}
}
}
}
for (uint32_t i = 0; i < mSrcs.Length(); i++) {
if (mSrcs[i]->permits(aUri, aNonce, aWasRedirected, aReportOnly,
aUpgradeInsecure, aParserCreated)) {
@ -1540,8 +1399,9 @@ nsCSPPolicy::~nsCSPPolicy() {
}
}
bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
nsIURI* aUri, bool aWasRedirected, bool aSpecific,
bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri,
const nsAString& aNonce, bool aWasRedirected,
bool aSpecific, bool aParserCreated,
nsAString& outViolatedDirective) const {
if (CSPUTILSLOGENABLED()) {
CSPUTILSLOG(("nsCSPPolicy::permits, aUri: %s, aDir: %d, aSpecific: %s",
@ -1552,13 +1412,6 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
NS_ASSERTION(aUri, "permits needs an uri to perform the check!");
outViolatedDirective.Truncate();
bool parserCreated = false;
nsAutoString nonce;
if (aLoadInfo) {
parserCreated = aLoadInfo->GetParserCreatedScript();
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->GetCspNonce(nonce));
}
nsCSPDirective* defaultDir = nullptr;
// Try to find a relevant directive
@ -1566,9 +1419,8 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
// hashtable.
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->equals(aDir)) {
if (!mDirectives[i]->permits(aDir, aLoadInfo, aUri, nonce, aWasRedirected,
mReportOnly, mUpgradeInsecDir,
parserCreated)) {
if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected, mReportOnly,
mUpgradeInsecDir, aParserCreated)) {
mDirectives[i]->getDirName(outViolatedDirective);
return false;
}
@ -1582,8 +1434,8 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
// If the above loop runs through, we haven't found a matching directive.
// Avoid relooping, just store the result of default-src while looping.
if (!aSpecific && defaultDir) {
if (!defaultDir->permits(aDir, aLoadInfo, aUri, nonce, aWasRedirected,
mReportOnly, mUpgradeInsecDir, parserCreated)) {
if (!defaultDir->permits(aUri, aNonce, aWasRedirected, mReportOnly,
mUpgradeInsecDir, aParserCreated)) {
defaultDir->getDirName(outViolatedDirective);
return false;
}
@ -1670,9 +1522,8 @@ bool nsCSPPolicy::allowsNavigateTo(nsIURI* aURI, bool aWasRedirected,
return true;
}
// Otherwise, check against the allowlist.
if (!mDirectives[i]->permits(
nsIContentSecurityPolicy::NAVIGATE_TO_DIRECTIVE, nullptr, aURI,
u""_ns, aWasRedirected, false, false, false)) {
if (!mDirectives[i]->permits(aURI, u""_ns, aWasRedirected, false, false,
false)) {
allowsNavigateTo = false;
}
}

View File

@ -9,7 +9,6 @@
#include "nsCOMPtr.h"
#include "nsIContentSecurityPolicy.h"
#include "nsILoadInfo.h"
#include "nsIURI.h"
#include "nsLiteralString.h"
#include "nsString.h"
@ -237,8 +236,6 @@ class nsCSPBaseSrc {
virtual bool isReportSample() const { return false; }
virtual bool isHash() const { return false; }
protected:
// invalidate srcs if 'script-dynamic' is present or also invalidate
// unsafe-inline' if nonce- or hash-source specified
@ -391,8 +388,6 @@ class nsCSPHashSrc : public nsCSPBaseSrc {
// not invalidate hashes.
}
bool isHash() const final { return true; }
private:
nsString mAlgorithm;
nsString mHash;
@ -452,8 +447,7 @@ class nsCSPDirective {
explicit nsCSPDirective(CSPDirective aDirective);
virtual ~nsCSPDirective();
virtual bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo,
nsIURI* aUri, const nsAString& aNonce,
virtual bool permits(nsIURI* aUri, const nsAString& aNonce,
bool aWasRedirected, bool aReportOnly,
bool aUpgradeInsecure, bool aParserCreated) const;
virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
@ -560,9 +554,9 @@ class nsBlockAllMixedContentDirective : public nsCSPDirective {
explicit nsBlockAllMixedContentDirective(CSPDirective aDirective);
~nsBlockAllMixedContentDirective();
bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
const nsAString& aNonce, bool aWasRedirected, bool aReportOnly,
bool aUpgradeInsecure, bool aParserCreated) const override {
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
bool aReportOnly, bool aUpgradeInsecure,
bool aParserCreated) const override {
return false;
}
@ -618,9 +612,9 @@ class nsUpgradeInsecureDirective : public nsCSPDirective {
explicit nsUpgradeInsecureDirective(CSPDirective aDirective);
~nsUpgradeInsecureDirective();
bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
const nsAString& aNonce, bool aWasRedirected, bool aReportOnly,
bool aUpgradeInsecure, bool aParserCreated) const override {
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
bool aReportOnly, bool aUpgradeInsecure,
bool aParserCreated) const override {
return false;
}
@ -647,8 +641,8 @@ class nsCSPPolicy {
nsCSPPolicy();
virtual ~nsCSPPolicy();
bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
bool aWasRedirected, bool aSpecific,
bool permits(CSPDirective aDirective, nsIURI* aUri, const nsAString& aNonce,
bool aWasRedirected, bool aSpecific, bool aParserCreated,
nsAString& outViolatedDirective) const;
bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
const nsAString& aHashOrNonce, bool aParserCreated) const;

View File

@ -194,10 +194,11 @@ function run_test() {
csp.shouldLoad(
Ci.nsIContentPolicy.TYPE_SCRIPT,
null, // nsICSPEventListener
null, // aLoadInfo
NetUtil.newURI("http://blocked.test/foo.js"),
null,
true
true,
null,
false
);
}
);
@ -260,10 +261,11 @@ function run_test() {
csp.shouldLoad(
Ci.nsIContentPolicy.TYPE_IMAGE,
null, // nsICSPEventListener
null, // nsILoadInfo
NetUtil.newURI("data:image/png;base64," + base64data),
null,
true
true,
null,
false
);
});
@ -273,10 +275,11 @@ function run_test() {
csp.shouldLoad(
Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
null, // nsICSPEventListener
null, // nsILoadInfo
NetUtil.newURI("intent://mymaps.com/maps?um=1&ie=UTF-8&fb=1&sll"),
null,
true
true,
null,
false
);
});
@ -288,10 +291,11 @@ function run_test() {
csp.shouldLoad(
Ci.nsIContentPolicy.TYPE_SCRIPT,
null, // nsICSPEventListener
null, // nsILoadInfo
NetUtil.newURI(selfSpec + "#bar"),
null,
true
true,
null,
false
);
});
}

View File

@ -486,10 +486,6 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
nsAutoString cspNonce;
Unused << NS_WARN_IF(NS_FAILED(aLoadInfo->GetCspNonce(cspNonce)));
nsAutoString integrityMetadata;
Unused << NS_WARN_IF(
NS_FAILED(aLoadInfo->GetIntegrityMetadata(integrityMetadata)));
nsCOMPtr<nsICookieJarSettings> cookieJarSettings;
rv = aLoadInfo->GetCookieJarSettings(getter_AddRefs(cookieJarSettings));
NS_ENSURE_SUCCESS(rv, rv);
@ -572,9 +568,8 @@ nsresult LoadInfoToLoadInfoArgs(nsILoadInfo* aLoadInfo,
aLoadInfo->GetDocumentHasUserInteracted(),
aLoadInfo->GetAllowListFutureDocumentsCreatedFromThisRedirectChain(),
aLoadInfo->GetNeedForCheckingAntiTrackingHeuristic(), cspNonce,
integrityMetadata, aLoadInfo->GetSkipContentSniffing(),
aLoadInfo->GetHttpsOnlyStatus(), aLoadInfo->GetHstsStatus(),
aLoadInfo->GetHasValidUserGestureActivation(),
aLoadInfo->GetSkipContentSniffing(), aLoadInfo->GetHttpsOnlyStatus(),
aLoadInfo->GetHstsStatus(), aLoadInfo->GetHasValidUserGestureActivation(),
aLoadInfo->GetAllowDeprecatedSystemRequests(),
aLoadInfo->GetIsInDevToolsContext(), aLoadInfo->GetParserCreatedScript(),
aLoadInfo->GetIsFromProcessingFrameAttributes(),
@ -862,9 +857,9 @@ nsresult LoadInfoArgsToLoadInfo(
loadInfoArgs.documentHasUserInteracted(),
loadInfoArgs.allowListFutureDocumentsCreatedFromThisRedirectChain(),
loadInfoArgs.needForCheckingAntiTrackingHeuristic(),
loadInfoArgs.cspNonce(), loadInfoArgs.integrityMetadata(),
loadInfoArgs.skipContentSniffing(), loadInfoArgs.httpsOnlyStatus(),
loadInfoArgs.hstsStatus(), loadInfoArgs.hasValidUserGestureActivation(),
loadInfoArgs.cspNonce(), loadInfoArgs.skipContentSniffing(),
loadInfoArgs.httpsOnlyStatus(), loadInfoArgs.hstsStatus(),
loadInfoArgs.hasValidUserGestureActivation(),
loadInfoArgs.allowDeprecatedSystemRequests(),
loadInfoArgs.isInDevToolsContext(), loadInfoArgs.parserCreatedScript(),
loadInfoArgs.storagePermission(), loadInfoArgs.isMetaRefresh(),

View File

@ -611,7 +611,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mNeedForCheckingAntiTrackingHeuristic(
rhs.mNeedForCheckingAntiTrackingHeuristic),
mCspNonce(rhs.mCspNonce),
mIntegrityMetadata(rhs.mIntegrityMetadata),
mSkipContentSniffing(rhs.mSkipContentSniffing),
mHttpsOnlyStatus(rhs.mHttpsOnlyStatus),
mHstsStatus(rhs.mHstsStatus),
@ -665,8 +664,7 @@ LoadInfo::LoadInfo(
bool aServiceWorkerTaintingSynthesized, bool aDocumentHasUserInteracted,
bool aAllowListFutureDocumentsCreatedFromThisRedirectChain,
bool aNeedForCheckingAntiTrackingHeuristic, const nsAString& aCspNonce,
const nsAString& aIntegrityMetadata, bool aSkipContentSniffing,
uint32_t aHttpsOnlyStatus, bool aHstsStatus,
bool aSkipContentSniffing, uint32_t aHttpsOnlyStatus, bool aHstsStatus,
bool aHasValidUserGestureActivation, bool aAllowDeprecatedSystemRequests,
bool aIsInDevToolsContext, bool aParserCreatedScript,
nsILoadInfo::StoragePermissionState aStoragePermission, bool aIsMetaRefresh,
@ -732,7 +730,6 @@ LoadInfo::LoadInfo(
mNeedForCheckingAntiTrackingHeuristic(
aNeedForCheckingAntiTrackingHeuristic),
mCspNonce(aCspNonce),
mIntegrityMetadata(aIntegrityMetadata),
mSkipContentSniffing(aSkipContentSniffing),
mHttpsOnlyStatus(aHttpsOnlyStatus),
mHstsStatus(aHstsStatus),
@ -1806,20 +1803,6 @@ LoadInfo::SetCspNonce(const nsAString& aCspNonce) {
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
aIntegrityMetadata = mIntegrityMetadata;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
MOZ_ASSERT(!mInitialSecurityCheckDone,
"setting the nonce is only allowed before any sec checks");
mIntegrityMetadata = aIntegrityMetadata;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) {
*aSkipContentSniffing = mSkipContentSniffing;

View File

@ -234,8 +234,7 @@ class LoadInfo final : public nsILoadInfo {
bool aServiceWorkerTaintingSynthesized, bool aDocumentHasUserInteracted,
bool aAllowListFutureDocumentsCreatedFromThisRedirectChain,
bool aNeedForCheckingAntiTrackingHeuristic, const nsAString& aCspNonce,
const nsAString& aIntegrityMetadata, bool aSkipContentSniffing,
uint32_t aHttpsOnlyStatus, bool aHstsStatus,
bool aSkipContentSniffing, uint32_t aHttpsOnlyStatus, bool aHstsStatus,
bool aHasValidUserGestureActivation, bool aAllowDeprecatedSystemRequests,
bool aIsInDevToolsContext, bool aParserCreatedScript,
nsILoadInfo::StoragePermissionState aStoragePermission,
@ -343,7 +342,6 @@ class LoadInfo final : public nsILoadInfo {
bool mAllowListFutureDocumentsCreatedFromThisRedirectChain = false;
bool mNeedForCheckingAntiTrackingHeuristic = false;
nsString mCspNonce;
nsString mIntegrityMetadata;
bool mSkipContentSniffing = false;
uint32_t mHttpsOnlyStatus = nsILoadInfo::HTTPS_ONLY_UNINITIALIZED;
bool mHstsStatus = false;

View File

@ -539,16 +539,6 @@ TRRLoadInfo::SetCspNonce(const nsAString& aCspNonce) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
TRRLoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) {
return NS_ERROR_NOT_IMPLEMENTED;

View File

@ -1336,9 +1336,6 @@ interface nsILoadInfo : nsISupports
*/
attribute AString cspNonce;
// Subresource Integrity (SRI) metadata.
attribute AString integrityMetadata;
/**
* List of possible reasons the request associated with this load info
* may have been blocked, set by various content blocking checkers.

View File

@ -164,7 +164,6 @@ struct LoadInfoArgs
bool allowListFutureDocumentsCreatedFromThisRedirectChain;
bool needForCheckingAntiTrackingHeuristic;
nsString cspNonce;
nsString integrityMetadata;
bool skipContentSniffing;
uint32_t httpsOnlyStatus;
bool hstsStatus;

View File

@ -0,0 +1,8 @@
implementation-status: backlog
[script-src-report-only-policy-works-with-external-hash-policy.html]
[External script in a script tag with matching SRI hash should run.]
expected: FAIL
[Should fire securitypolicyviolation event]
expected: FAIL

View File

@ -0,0 +1,14 @@
[script-src-sri_hash.sub.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[matching integrity]
expected: FAIL
[multiple matching integrity]
expected: FAIL
[matching plus unsupported integrity]
expected: FAIL
[External script in a script tag with matching SRI hash should run.]
expected: FAIL

View File

@ -1,109 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>External scripts with matching SRI hash (in default-src) should be allowed.</title>
<script src='/resources/testharness.js' nonce='dummy'></script>
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
<!-- CSP served: default-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=='; style-src 'unsafe-inline' -->
<!-- ShA256 is intentionally mixed case -->
</head>
<body>
<h1>External scripts with matching SRI hash (in default-src) should be allowed.</h1>
<div id='log'></div>
<script nonce='dummy'>
var port = "{{ports[http][0]}}";
if (location.protocol === "https:")
port = "{{ports[https][0]}}";
var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port;
// Test name, src, integrity, expected to run.
var test_cases = [
[ 'matching integrity',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ],
[ 'matching integrity (case-insensitive algorithm)',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ],
[ 'multiple matching integrity',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==',
true ],
[ 'no integrity',
'./simpleSourcedScript.js',
'',
false ],
[ 'matching plus unsupported integrity',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha999-xyz',
true ],
[ 'mismatched integrity',
'./simpleSourcedScript.js',
'sha256-xyz',
false ],
[ 'multiple mismatched integrity',
'./simpleSourcedScript.js',
'sha256-xyz sha256-zyx',
false ],
[ 'partially matching integrity',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha256-xyz',
false ],
[ 'crossorigin no integrity but allowed host',
crossorigin_base + '/content-security-policy/script-src/crossoriginScript.js',
'',
true ],
[ 'crossorigin mismatched integrity but allowed host',
crossorigin_base + '/content-security-policy/script-src/crossoriginScript.js',
'sha256-kKJ5c48yxzaaSBupJSCmY50hkD8xbVgZgLHLtmnkeAo=',
true ],
];
test(_ => {
for (item of test_cases) {
async_test(t => {
var s = document.createElement('script');
s.id = item[0].replace(' ', '-');
s.src = item[1];
s.integrity = item[2];
s.setAttribute('crossorigin', 'anonymous');
if (item[3]) {
s.onerror = t.unreached_func("Script should load! " + s.src);
window.addEventListener('message', t.step_func(e => {
if (e.data == s.id)
t.done();
}));
} else {
s.onerror = t.step_func_done();
window.addEventListener('message', t.step_func(e => {
if (e.data == s.id)
assert_unreached("Script should not execute!");
}));
}
document.body.appendChild(s);
}, item[0]);
}
}, "Load all the tests.");
</script>
<script nonce='dummy'>
var externalRan = false;
</script>
<script src='./externalScript.js'
integrity="sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0="></script>
<script nonce='dummy'>
test(function() {
assert_true(externalRan, 'External script ran.');
}, 'External script in a script tag with matching SRI hash should run.');
</script>
</body>
</html>

View File

@ -1,5 +0,0 @@
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
Content-Security-Policy: default-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=='; style-src 'unsafe-inline'

View File

@ -1 +0,0 @@
window.postMessage(document.currentScript.id, "*");

View File

@ -6,8 +6,7 @@
<script src='/resources/testharness.js' nonce='dummy'></script>
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
<!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==' -->
<!-- ShA256 is intentionally mixed case -->
<!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=' -->
</head>
<body>
@ -26,13 +25,9 @@
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ],
[ 'matching integrity (case-insensitive algorithm)',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ],
[ 'multiple matching integrity',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=',
true ],
[ 'no integrity',
'./simpleSourcedScript.js',

View File

@ -2,4 +2,4 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
Content-Security-Policy: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=='
Content-Security-Policy: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA='