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 aeeb6edb4f
commit bd48e8269c
23 changed files with 117 additions and 389 deletions

View File

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

View File

@@ -344,10 +344,11 @@ interface nsIContentSecurityPolicy : nsISerializable
*/ */
short shouldLoad(in nsContentPolicyType aContentType, short shouldLoad(in nsContentPolicyType aContentType,
in nsICSPEventListener aCSPEventListener, in nsICSPEventListener aCSPEventListener,
in nsILoadInfo aLoadInfo,
in nsIURI aContentLocation, in nsIURI aContentLocation,
in nsIURI aOriginalURIIfRedirect, in nsIURI aOriginalURIIfRedirect,
in bool aSendViolationReports); in bool aSendViolationReports,
in AString aNonce,
in boolean aParserCreated);
%{ C++ %{ C++
// nsIObserver topic to fire when the policy encounters a violation. // 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, requestingNode, nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
contentPolicyType); contentPolicyType);
secCheckLoadInfo->SetIntegrityMetadata(
aRequest->mIntegrity.GetIntegrityString());
// snapshot the nonce at load start time for performing CSP checks // snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT || if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT ||
contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) { contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) {
@@ -626,9 +623,6 @@ nsresult ScriptLoader::StartLoadInternal(
NS_ENSURE_SUCCESS(rv, rv); 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 // snapshot the nonce at load start time for performing CSP checks
if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT || if (contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_SCRIPT ||
contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) { contentPolicyType == nsIContentPolicy::TYPE_INTERNAL_MODULE) {
@@ -636,6 +630,7 @@ nsresult ScriptLoader::StartLoadInternal(
nsString* cspNonce = nsString* cspNonce =
static_cast<nsString*>(context->GetProperty(nsGkAtoms::nonce)); static_cast<nsString*>(context->GetProperty(nsGkAtoms::nonce));
if (cspNonce) { if (cspNonce) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->LoadInfo();
loadInfo->SetCspNonce(*cspNonce); loadInfo->SetCspNonce(*cspNonce);
} }
} }

View File

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

View File

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

View File

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

View File

@@ -21,16 +21,12 @@
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsSandboxFlags.h" #include "nsSandboxFlags.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsWhitespaceTokenizer.h"
#include "mozilla/Components.h" #include "mozilla/Components.h"
#include "mozilla/dom/CSPDictionariesBinding.h" #include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/dom/Document.h" #include "mozilla/dom/Document.h"
#include "mozilla/dom/SRIMetadata.h"
#include "mozilla/StaticPrefs_security.h" #include "mozilla/StaticPrefs_security.h"
using mozilla::dom::SRIMetadata;
#define DEFAULT_PORT -1 #define DEFAULT_PORT -1
static mozilla::LogModule* GetCspUtilsLog() { static mozilla::LogModule* GetCspUtilsLog() {
@@ -1080,151 +1076,14 @@ nsCSPDirective::~nsCSPDirective() {
} }
} }
// This check only considers types "script-like" bool nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce,
// (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 aWasRedirected, bool aReportOnly, bool aWasRedirected, bool aReportOnly,
bool aUpgradeInsecure, bool aParserCreated) const { bool aUpgradeInsecure, bool aParserCreated) const {
MOZ_ASSERT(equals(aDirective) || isDefaultDirective());
if (CSPUTILSLOGENABLED()) { if (CSPUTILSLOGENABLED()) {
CSPUTILSLOG( CSPUTILSLOG(
("nsCSPDirective::permits, aUri: %s", aUri->GetSpecOrDefault().get())); ("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++) { for (uint32_t i = 0; i < mSrcs.Length(); i++) {
if (mSrcs[i]->permits(aUri, aNonce, aWasRedirected, aReportOnly, if (mSrcs[i]->permits(aUri, aNonce, aWasRedirected, aReportOnly,
aUpgradeInsecure, aParserCreated)) { aUpgradeInsecure, aParserCreated)) {
@@ -1540,8 +1399,9 @@ nsCSPPolicy::~nsCSPPolicy() {
} }
} }
bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo, bool nsCSPPolicy::permits(CSPDirective aDir, nsIURI* aUri,
nsIURI* aUri, bool aWasRedirected, bool aSpecific, const nsAString& aNonce, bool aWasRedirected,
bool aSpecific, bool aParserCreated,
nsAString& outViolatedDirective) const { nsAString& outViolatedDirective) const {
if (CSPUTILSLOGENABLED()) { if (CSPUTILSLOGENABLED()) {
CSPUTILSLOG(("nsCSPPolicy::permits, aUri: %s, aDir: %d, aSpecific: %s", 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!"); NS_ASSERTION(aUri, "permits needs an uri to perform the check!");
outViolatedDirective.Truncate(); outViolatedDirective.Truncate();
bool parserCreated = false;
nsAutoString nonce;
if (aLoadInfo) {
parserCreated = aLoadInfo->GetParserCreatedScript();
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->GetCspNonce(nonce));
}
nsCSPDirective* defaultDir = nullptr; nsCSPDirective* defaultDir = nullptr;
// Try to find a relevant directive // Try to find a relevant directive
@@ -1566,9 +1419,8 @@ bool nsCSPPolicy::permits(CSPDirective aDir, nsILoadInfo* aLoadInfo,
// hashtable. // hashtable.
for (uint32_t i = 0; i < mDirectives.Length(); i++) { for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->equals(aDir)) { if (mDirectives[i]->equals(aDir)) {
if (!mDirectives[i]->permits(aDir, aLoadInfo, aUri, nonce, aWasRedirected, if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected, mReportOnly,
mReportOnly, mUpgradeInsecDir, mUpgradeInsecDir, aParserCreated)) {
parserCreated)) {
mDirectives[i]->getDirName(outViolatedDirective); mDirectives[i]->getDirName(outViolatedDirective);
return false; 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. // If the above loop runs through, we haven't found a matching directive.
// Avoid relooping, just store the result of default-src while looping. // Avoid relooping, just store the result of default-src while looping.
if (!aSpecific && defaultDir) { if (!aSpecific && defaultDir) {
if (!defaultDir->permits(aDir, aLoadInfo, aUri, nonce, aWasRedirected, if (!defaultDir->permits(aUri, aNonce, aWasRedirected, mReportOnly,
mReportOnly, mUpgradeInsecDir, parserCreated)) { mUpgradeInsecDir, aParserCreated)) {
defaultDir->getDirName(outViolatedDirective); defaultDir->getDirName(outViolatedDirective);
return false; return false;
} }
@@ -1670,9 +1522,8 @@ bool nsCSPPolicy::allowsNavigateTo(nsIURI* aURI, bool aWasRedirected,
return true; return true;
} }
// Otherwise, check against the allowlist. // Otherwise, check against the allowlist.
if (!mDirectives[i]->permits( if (!mDirectives[i]->permits(aURI, u""_ns, aWasRedirected, false, false,
nsIContentSecurityPolicy::NAVIGATE_TO_DIRECTIVE, nullptr, aURI, false)) {
u""_ns, aWasRedirected, false, false, false)) {
allowsNavigateTo = false; allowsNavigateTo = false;
} }
} }

View File

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

View File

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

View File

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

View File

@@ -611,7 +611,6 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
mNeedForCheckingAntiTrackingHeuristic( mNeedForCheckingAntiTrackingHeuristic(
rhs.mNeedForCheckingAntiTrackingHeuristic), rhs.mNeedForCheckingAntiTrackingHeuristic),
mCspNonce(rhs.mCspNonce), mCspNonce(rhs.mCspNonce),
mIntegrityMetadata(rhs.mIntegrityMetadata),
mSkipContentSniffing(rhs.mSkipContentSniffing), mSkipContentSniffing(rhs.mSkipContentSniffing),
mHttpsOnlyStatus(rhs.mHttpsOnlyStatus), mHttpsOnlyStatus(rhs.mHttpsOnlyStatus),
mHstsStatus(rhs.mHstsStatus), mHstsStatus(rhs.mHstsStatus),
@@ -665,8 +664,7 @@ LoadInfo::LoadInfo(
bool aServiceWorkerTaintingSynthesized, bool aDocumentHasUserInteracted, bool aServiceWorkerTaintingSynthesized, bool aDocumentHasUserInteracted,
bool aAllowListFutureDocumentsCreatedFromThisRedirectChain, bool aAllowListFutureDocumentsCreatedFromThisRedirectChain,
bool aNeedForCheckingAntiTrackingHeuristic, const nsAString& aCspNonce, bool aNeedForCheckingAntiTrackingHeuristic, const nsAString& aCspNonce,
const nsAString& aIntegrityMetadata, bool aSkipContentSniffing, bool aSkipContentSniffing, uint32_t aHttpsOnlyStatus, bool aHstsStatus,
uint32_t aHttpsOnlyStatus, bool aHstsStatus,
bool aHasValidUserGestureActivation, bool aAllowDeprecatedSystemRequests, bool aHasValidUserGestureActivation, bool aAllowDeprecatedSystemRequests,
bool aIsInDevToolsContext, bool aParserCreatedScript, bool aIsInDevToolsContext, bool aParserCreatedScript,
nsILoadInfo::StoragePermissionState aStoragePermission, bool aIsMetaRefresh, nsILoadInfo::StoragePermissionState aStoragePermission, bool aIsMetaRefresh,
@@ -732,7 +730,6 @@ LoadInfo::LoadInfo(
mNeedForCheckingAntiTrackingHeuristic( mNeedForCheckingAntiTrackingHeuristic(
aNeedForCheckingAntiTrackingHeuristic), aNeedForCheckingAntiTrackingHeuristic),
mCspNonce(aCspNonce), mCspNonce(aCspNonce),
mIntegrityMetadata(aIntegrityMetadata),
mSkipContentSniffing(aSkipContentSniffing), mSkipContentSniffing(aSkipContentSniffing),
mHttpsOnlyStatus(aHttpsOnlyStatus), mHttpsOnlyStatus(aHttpsOnlyStatus),
mHstsStatus(aHstsStatus), mHstsStatus(aHstsStatus),
@@ -1806,20 +1803,6 @@ LoadInfo::SetCspNonce(const nsAString& aCspNonce) {
return NS_OK; 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 NS_IMETHODIMP
LoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) { LoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) {
*aSkipContentSniffing = mSkipContentSniffing; *aSkipContentSniffing = mSkipContentSniffing;

View File

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

View File

@@ -539,16 +539,6 @@ TRRLoadInfo::SetCspNonce(const nsAString& aCspNonce) {
return NS_ERROR_NOT_IMPLEMENTED; 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 NS_IMETHODIMP
TRRLoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) { TRRLoadInfo::GetSkipContentSniffing(bool* aSkipContentSniffing) {
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;

View File

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

View File

@@ -164,7 +164,6 @@ struct LoadInfoArgs
bool allowListFutureDocumentsCreatedFromThisRedirectChain; bool allowListFutureDocumentsCreatedFromThisRedirectChain;
bool needForCheckingAntiTrackingHeuristic; bool needForCheckingAntiTrackingHeuristic;
nsString cspNonce; nsString cspNonce;
nsString integrityMetadata;
bool skipContentSniffing; bool skipContentSniffing;
uint32_t httpsOnlyStatus; uint32_t httpsOnlyStatus;
bool hstsStatus; 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/testharness.js' nonce='dummy'></script>
<script src='/resources/testharnessreport.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==' --> <!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=' -->
<!-- ShA256 is intentionally mixed case -->
</head> </head>
<body> <body>
@@ -26,13 +25,9 @@
'./simpleSourcedScript.js', './simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=', 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ], true ],
[ 'matching integrity (case-insensitive algorithm)',
'./simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=',
true ],
[ 'multiple matching integrity', [ 'multiple matching integrity',
'./simpleSourcedScript.js', './simpleSourcedScript.js',
'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==', 'sha256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c= sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=',
true ], true ],
[ 'no integrity', [ 'no integrity',
'./simpleSourcedScript.js', './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: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache 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='