зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1386214 - Remove require-sri from the CSP-Module r=ckerschb,qdot
Differential Revision: https://phabricator.services.mozilla.com/D24880 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
92b55dddb6
Коммит
82fb5d3ddf
|
@ -60,9 +60,8 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
const unsigned short UPGRADE_IF_INSECURE_DIRECTIVE = 16;
|
const unsigned short UPGRADE_IF_INSECURE_DIRECTIVE = 16;
|
||||||
const unsigned short CHILD_SRC_DIRECTIVE = 17;
|
const unsigned short CHILD_SRC_DIRECTIVE = 17;
|
||||||
const unsigned short BLOCK_ALL_MIXED_CONTENT = 18;
|
const unsigned short BLOCK_ALL_MIXED_CONTENT = 18;
|
||||||
const unsigned short REQUIRE_SRI_FOR = 19;
|
const unsigned short SANDBOX_DIRECTIVE = 19;
|
||||||
const unsigned short SANDBOX_DIRECTIVE = 20;
|
const unsigned short WORKER_SRC_DIRECTIVE = 20;
|
||||||
const unsigned short WORKER_SRC_DIRECTIVE = 21;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessor method for a read-only string version of the policy at a given
|
* Accessor method for a read-only string version of the policy at a given
|
||||||
|
@ -232,12 +231,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
||||||
*/
|
*/
|
||||||
[noscript] void ensureEventTarget(in nsIEventTarget aEventTarget);
|
[noscript] void ensureEventTarget(in nsIEventTarget aEventTarget);
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if a CSP requires Subresource Integrity (SRI)
|
|
||||||
* for a given nsContentPolicyType.
|
|
||||||
*/
|
|
||||||
bool requireSRIForType(in nsContentPolicyType aContentType);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies ancestry as permitted by the policy.
|
* Verifies ancestry as permitted by the policy.
|
||||||
*
|
*
|
||||||
|
|
|
@ -83,7 +83,7 @@ notSupportingDirective = Not supporting directive ‘%1$S’. Directive and valu
|
||||||
# %1$S is the URL of the blocked resource load.
|
# %1$S is the URL of the blocked resource load.
|
||||||
blockAllMixedContent = Blocking insecure request ‘%1$S’.
|
blockAllMixedContent = Blocking insecure request ‘%1$S’.
|
||||||
# LOCALIZATION NOTE (ignoringDirectiveWithNoValues):
|
# LOCALIZATION NOTE (ignoringDirectiveWithNoValues):
|
||||||
# %1$S is the name of a CSP directive that requires additional values (e.g., 'require-sri-for')
|
# %1$S is the name of a CSP directive that requires additional values
|
||||||
ignoringDirectiveWithNoValues = Ignoring ‘%1$S’ since it does not contain any parameters.
|
ignoringDirectiveWithNoValues = Ignoring ‘%1$S’ since it does not contain any parameters.
|
||||||
# LOCALIZATION NOTE (ignoringReportOnlyDirective):
|
# LOCALIZATION NOTE (ignoringReportOnlyDirective):
|
||||||
# %1$S is the directive that is ignored in report-only mode.
|
# %1$S is the directive that is ignored in report-only mode.
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
"upgrade-insecure-requests"
|
"upgrade-insecure-requests"
|
||||||
"child-src"
|
"child-src"
|
||||||
"block-all-mixed-content"
|
"block-all-mixed-content"
|
||||||
"require-sri-for"
|
|
||||||
"sandbox"
|
"sandbox"
|
||||||
"worker-src"
|
"worker-src"
|
||||||
"plugin-types"
|
"plugin-types"
|
||||||
|
|
|
@ -679,12 +679,6 @@ nsCSPContext::LogViolationDetails(
|
||||||
SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC);
|
SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC);
|
||||||
CASE_CHECK_AND_REPORT(HASH_STYLE, STYLESHEET, aContent, CSP_UNSAFE_INLINE,
|
CASE_CHECK_AND_REPORT(HASH_STYLE, STYLESHEET, aContent, CSP_UNSAFE_INLINE,
|
||||||
STYLE_HASH_VIOLATION_OBSERVER_TOPIC);
|
STYLE_HASH_VIOLATION_OBSERVER_TOPIC);
|
||||||
CASE_CHECK_AND_REPORT(REQUIRE_SRI_FOR_STYLE, STYLESHEET,
|
|
||||||
NS_LITERAL_STRING(""), CSP_REQUIRE_SRI_FOR,
|
|
||||||
REQUIRE_SRI_STYLE_VIOLATION_OBSERVER_TOPIC);
|
|
||||||
CASE_CHECK_AND_REPORT(REQUIRE_SRI_FOR_SCRIPT, SCRIPT,
|
|
||||||
NS_LITERAL_STRING(""), CSP_REQUIRE_SRI_FOR,
|
|
||||||
REQUIRE_SRI_SCRIPT_VIOLATION_OBSERVER_TOPIC);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NS_ASSERTION(false, "LogViolationDetails with invalid type");
|
NS_ASSERTION(false, "LogViolationDetails with invalid type");
|
||||||
|
@ -1386,22 +1380,6 @@ nsresult nsCSPContext::AsyncReportViolation(
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsCSPContext::RequireSRIForType(nsContentPolicyType aContentType,
|
|
||||||
bool* outRequiresSRIForType) {
|
|
||||||
EnsureIPCPoliciesRead();
|
|
||||||
*outRequiresSRIForType = false;
|
|
||||||
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
|
|
||||||
if (mPolicies[i]->hasDirective(REQUIRE_SRI_FOR)) {
|
|
||||||
if (mPolicies[i]->requireSRIForType(aContentType)) {
|
|
||||||
*outRequiresSRIForType = true;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on the given docshell, determines if this CSP context allows the
|
* Based on the given docshell, determines if this CSP context allows the
|
||||||
* ancestry.
|
* ancestry.
|
||||||
|
|
|
@ -60,9 +60,6 @@ static const uint32_t kSubHostPathCharacterCutoff = 512;
|
||||||
static const char* const kHashSourceValidFns[] = {"sha256", "sha384", "sha512"};
|
static const char* const kHashSourceValidFns[] = {"sha256", "sha384", "sha512"};
|
||||||
static const uint32_t kHashSourceValidFnsLen = 3;
|
static const uint32_t kHashSourceValidFnsLen = 3;
|
||||||
|
|
||||||
static const char* const kStyle = "style";
|
|
||||||
static const char* const kScript = "script";
|
|
||||||
|
|
||||||
/* ===== nsCSPParser ==================== */
|
/* ===== nsCSPParser ==================== */
|
||||||
|
|
||||||
nsCSPParser::nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI,
|
nsCSPParser::nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI,
|
||||||
|
@ -758,52 +755,6 @@ void nsCSPParser::sourceList(nsTArray<nsCSPBaseSrc*>& outSrcs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCSPParser::requireSRIForDirectiveValue(nsRequireSRIForDirective* aDir) {
|
|
||||||
CSPPARSERLOG(("nsCSPParser::requireSRIForDirectiveValue"));
|
|
||||||
|
|
||||||
// directive-value = "style" / "script"
|
|
||||||
// directive name is token 0, we need to examine the remaining tokens
|
|
||||||
for (uint32_t i = 1; i < mCurDir.Length(); i++) {
|
|
||||||
// mCurToken is only set here and remains the current token
|
|
||||||
// to be processed, which avoid passing arguments between functions.
|
|
||||||
mCurToken = mCurDir[i];
|
|
||||||
resetCurValue();
|
|
||||||
CSPPARSERLOG(
|
|
||||||
("nsCSPParser:::directive (require-sri-for directive), "
|
|
||||||
"mCurToken: %s (valid), mCurValue: %s",
|
|
||||||
NS_ConvertUTF16toUTF8(mCurToken).get(),
|
|
||||||
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
|
||||||
// add contentPolicyTypes to the CSP's required-SRI list for this token
|
|
||||||
if (mCurToken.LowerCaseEqualsASCII(kScript)) {
|
|
||||||
aDir->addType(nsIContentPolicy::TYPE_SCRIPT);
|
|
||||||
} else if (mCurToken.LowerCaseEqualsASCII(kStyle)) {
|
|
||||||
aDir->addType(nsIContentPolicy::TYPE_STYLESHEET);
|
|
||||||
} else {
|
|
||||||
const char16_t* invalidTokenName[] = {mCurToken.get()};
|
|
||||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
|
||||||
"failedToParseUnrecognizedSource",
|
|
||||||
invalidTokenName, ArrayLength(invalidTokenName));
|
|
||||||
CSPPARSERLOG(
|
|
||||||
("nsCSPParser:::directive (require-sri-for directive), "
|
|
||||||
"mCurToken: %s (invalid), mCurValue: %s",
|
|
||||||
NS_ConvertUTF16toUTF8(mCurToken).get(),
|
|
||||||
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(aDir->hasType(nsIContentPolicy::TYPE_STYLESHEET)) &&
|
|
||||||
!(aDir->hasType(nsIContentPolicy::TYPE_SCRIPT))) {
|
|
||||||
const char16_t* directiveName[] = {mCurToken.get()};
|
|
||||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
|
||||||
"ignoringDirectiveWithNoValues", directiveName,
|
|
||||||
ArrayLength(directiveName));
|
|
||||||
delete aDir;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mPolicy->addDirective(aDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsCSPParser::reportURIList(nsCSPDirective* aDir) {
|
void nsCSPParser::reportURIList(nsCSPDirective* aDir) {
|
||||||
CSPPARSERLOG(("nsCSPParser::reportURIList"));
|
CSPPARSERLOG(("nsCSPParser::reportURIList"));
|
||||||
|
|
||||||
|
@ -902,9 +853,7 @@ nsCSPDirective* nsCSPParser::directiveName() {
|
||||||
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
||||||
|
|
||||||
// Check if it is a valid directive
|
// Check if it is a valid directive
|
||||||
if (!CSP_IsValidDirective(mCurToken) ||
|
if (!CSP_IsValidDirective(mCurToken)) {
|
||||||
(!StaticPrefs::security_csp_experimentalEnabled() &&
|
|
||||||
CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR))) {
|
|
||||||
const char16_t* params[] = {mCurToken.get()};
|
const char16_t* params[] = {mCurToken.get()};
|
||||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
||||||
"couldNotProcessUnknownDirective", params,
|
"couldNotProcessUnknownDirective", params,
|
||||||
|
@ -1001,10 +950,6 @@ nsCSPDirective* nsCSPParser::directiveName() {
|
||||||
return mScriptSrc;
|
return mScriptSrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
|
|
||||||
return new nsRequireSRIForDirective(CSP_StringToCSPDirective(mCurToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new nsCSPDirective(CSP_StringToCSPDirective(mCurToken));
|
return new nsCSPDirective(CSP_StringToCSPDirective(mCurToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1069,13 +1014,6 @@ void nsCSPParser::directive() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case handling for require-sri-for, which has directive values that
|
|
||||||
// are well-defined tokens but are not sources
|
|
||||||
if (cspDir->equals(nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
|
|
||||||
requireSRIForDirectiveValue(static_cast<nsRequireSRIForDirective*>(cspDir));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// special case handling for report-uri directive (since it doesn't contain
|
// special case handling for report-uri directive (since it doesn't contain
|
||||||
// a valid source list but rather actual URIs)
|
// a valid source list but rather actual URIs)
|
||||||
if (CSP_IsDirective(mCurDir[0],
|
if (CSP_IsDirective(mCurDir[0],
|
||||||
|
|
|
@ -40,7 +40,6 @@ class nsCSPParser {
|
||||||
void directive();
|
void directive();
|
||||||
nsCSPDirective* directiveName();
|
nsCSPDirective* directiveName();
|
||||||
void directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs);
|
void directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs);
|
||||||
void requireSRIForDirectiveValue(nsRequireSRIForDirective* aDir);
|
|
||||||
void referrerDirectiveValue(nsCSPDirective* aDir);
|
void referrerDirectiveValue(nsCSPDirective* aDir);
|
||||||
void reportURIList(nsCSPDirective* aDir);
|
void reportURIList(nsCSPDirective* aDir);
|
||||||
void sandboxFlagList(nsCSPDirective* aDir);
|
void sandboxFlagList(nsCSPDirective* aDir);
|
||||||
|
|
|
@ -1092,8 +1092,6 @@ void nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const {
|
||||||
outCSP.mWorker_src.Value() = std::move(srcs);
|
outCSP.mWorker_src.Value() = std::move(srcs);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// REQUIRE_SRI_FOR is handled in nsCSPPolicy::toDomCSPStruct()
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NS_ASSERTION(false, "cannot find directive to convert CSP to JSON");
|
NS_ASSERTION(false, "cannot find directive to convert CSP to JSON");
|
||||||
}
|
}
|
||||||
|
@ -1239,51 +1237,6 @@ void nsUpgradeInsecureDirective::getDirName(nsAString& outStr) const {
|
||||||
nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
|
nsIContentSecurityPolicy::UPGRADE_IF_INSECURE_DIRECTIVE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== nsRequireSRIForDirective ========================= */
|
|
||||||
|
|
||||||
nsRequireSRIForDirective::nsRequireSRIForDirective(CSPDirective aDirective)
|
|
||||||
: nsCSPDirective(aDirective) {}
|
|
||||||
|
|
||||||
nsRequireSRIForDirective::~nsRequireSRIForDirective() {}
|
|
||||||
|
|
||||||
void nsRequireSRIForDirective::toString(nsAString& outStr) const {
|
|
||||||
outStr.AppendASCII(
|
|
||||||
CSP_CSPDirectiveToString(nsIContentSecurityPolicy::REQUIRE_SRI_FOR));
|
|
||||||
for (uint32_t i = 0; i < mTypes.Length(); i++) {
|
|
||||||
if (mTypes[i] == nsIContentPolicy::TYPE_SCRIPT) {
|
|
||||||
outStr.AppendLiteral(" script");
|
|
||||||
} else if (mTypes[i] == nsIContentPolicy::TYPE_STYLESHEET) {
|
|
||||||
outStr.AppendLiteral(" style");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsRequireSRIForDirective::hasType(nsContentPolicyType aType) const {
|
|
||||||
for (uint32_t i = 0; i < mTypes.Length(); i++) {
|
|
||||||
if (mTypes[i] == aType) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsRequireSRIForDirective::restrictsContentType(
|
|
||||||
const nsContentPolicyType aType) const {
|
|
||||||
return this->hasType(aType);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool nsRequireSRIForDirective::allows(enum CSPKeyword aKeyword,
|
|
||||||
const nsAString& aHashOrNonce,
|
|
||||||
bool aParserCreated) const {
|
|
||||||
// can only disallow CSP_REQUIRE_SRI_FOR.
|
|
||||||
return (aKeyword != CSP_REQUIRE_SRI_FOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsRequireSRIForDirective::getDirName(nsAString& outStr) const {
|
|
||||||
outStr.AppendASCII(
|
|
||||||
CSP_CSPDirectiveToString(nsIContentSecurityPolicy::REQUIRE_SRI_FOR));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== nsCSPPolicy ========================= */
|
/* ===== nsCSPPolicy ========================= */
|
||||||
|
|
||||||
nsCSPPolicy::nsCSPPolicy()
|
nsCSPPolicy::nsCSPPolicy()
|
||||||
|
@ -1523,13 +1476,3 @@ bool nsCSPPolicy::visitDirectiveSrcs(CSPDirective aDir,
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsCSPPolicy::requireSRIForType(nsContentPolicyType aContentType) {
|
|
||||||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
|
||||||
if (mDirectives[i]->equals(nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
|
|
||||||
return static_cast<nsRequireSRIForDirective*>(mDirectives[i])
|
|
||||||
->hasType(aContentType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
|
@ -55,10 +55,6 @@ void CSP_LogMessage(const nsAString& aMessage, const nsAString& aSourceName,
|
||||||
#define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
|
#define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
|
||||||
#define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
|
#define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
|
||||||
#define STYLE_HASH_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid hash"
|
#define STYLE_HASH_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid hash"
|
||||||
#define REQUIRE_SRI_SCRIPT_VIOLATION_OBSERVER_TOPIC \
|
|
||||||
"Missing required Subresource Integrity for Script"
|
|
||||||
#define REQUIRE_SRI_STYLE_VIOLATION_OBSERVER_TOPIC \
|
|
||||||
"Missing required Subresource Integrity for Style"
|
|
||||||
|
|
||||||
// these strings map to the CSPDirectives in nsIContentSecurityPolicy
|
// these strings map to the CSPDirectives in nsIContentSecurityPolicy
|
||||||
// NOTE: When implementing a new directive, you will need to add it here but
|
// NOTE: When implementing a new directive, you will need to add it here but
|
||||||
|
@ -87,7 +83,6 @@ static const char* CSPStrDirectives[] = {
|
||||||
"upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
|
"upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
|
||||||
"child-src", // CHILD_SRC_DIRECTIVE
|
"child-src", // CHILD_SRC_DIRECTIVE
|
||||||
"block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
|
"block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
|
||||||
"require-sri-for", // REQUIRE_SRI_FOR
|
|
||||||
"sandbox", // SANDBOX_DIRECTIVE
|
"sandbox", // SANDBOX_DIRECTIVE
|
||||||
"worker-src" // WORKER_SRC_DIRECTIVE
|
"worker-src" // WORKER_SRC_DIRECTIVE
|
||||||
};
|
};
|
||||||
|
@ -110,14 +105,13 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
|
||||||
return nsIContentSecurityPolicy::NO_DIRECTIVE;
|
return nsIContentSecurityPolicy::NO_DIRECTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
||||||
MACRO(CSP_SELF, "'self'") \
|
MACRO(CSP_SELF, "'self'") \
|
||||||
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
||||||
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
||||||
MACRO(CSP_NONE, "'none'") \
|
MACRO(CSP_NONE, "'none'") \
|
||||||
MACRO(CSP_NONCE, "'nonce-") \
|
MACRO(CSP_NONCE, "'nonce-") \
|
||||||
MACRO(CSP_REQUIRE_SRI_FOR, "require-sri-for") \
|
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
|
||||||
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
|
|
||||||
MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'")
|
MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'")
|
||||||
|
|
||||||
enum CSPKeyword {
|
enum CSPKeyword {
|
||||||
|
@ -607,26 +601,6 @@ class nsUpgradeInsecureDirective : public nsCSPDirective {
|
||||||
void getDirName(nsAString& outStr) const override;
|
void getDirName(nsAString& outStr) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ===== nsRequireSRIForDirective ========================= */
|
|
||||||
|
|
||||||
class nsRequireSRIForDirective : public nsCSPDirective {
|
|
||||||
public:
|
|
||||||
explicit nsRequireSRIForDirective(CSPDirective aDirective);
|
|
||||||
~nsRequireSRIForDirective();
|
|
||||||
|
|
||||||
void toString(nsAString& outStr) const override;
|
|
||||||
|
|
||||||
void addType(nsContentPolicyType aType) { mTypes.AppendElement(aType); }
|
|
||||||
bool hasType(nsContentPolicyType aType) const;
|
|
||||||
bool restrictsContentType(nsContentPolicyType aType) const override;
|
|
||||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
|
|
||||||
bool aParserCreated) const override;
|
|
||||||
void getDirName(nsAString& outStr) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
nsTArray<nsContentPolicyType> mTypes;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* =============== nsCSPPolicy ================== */
|
/* =============== nsCSPPolicy ================== */
|
||||||
|
|
||||||
class nsCSPPolicy {
|
class nsCSPPolicy {
|
||||||
|
@ -677,8 +651,6 @@ class nsCSPPolicy {
|
||||||
|
|
||||||
uint32_t getSandboxFlags() const;
|
uint32_t getSandboxFlags() const;
|
||||||
|
|
||||||
bool requireSRIForType(nsContentPolicyType aContentType);
|
|
||||||
|
|
||||||
inline uint32_t getNumDirectives() const { return mDirectives.Length(); }
|
inline uint32_t getNumDirectives() const { return mDirectives.Length(); }
|
||||||
|
|
||||||
bool visitDirectiveSrcs(CSPDirective aDir, nsCSPSrcVisitor* aVisitor) const;
|
bool visitDirectiveSrcs(CSPDirective aDir, nsCSPSrcVisitor* aVisitor) const;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
var foo = 24;
|
|
|
@ -1,54 +0,0 @@
|
||||||
// custom *.sjs for Bug 1277557
|
|
||||||
// META CSP: require-sri-for script;
|
|
||||||
|
|
||||||
const PRE_INTEGRITY =
|
|
||||||
"<!DOCTYPE HTML>" +
|
|
||||||
"<html><head><meta charset=\"utf-8\">" +
|
|
||||||
"<title>Bug 1277557 - CSP require-sri-for does not block when CSP is in meta tag</title>" +
|
|
||||||
"<meta http-equiv=\"Content-Security-Policy\" content=\"require-sri-for script; script-src 'unsafe-inline' *\">" +
|
|
||||||
"</head>" +
|
|
||||||
"<body>" +
|
|
||||||
"<script id=\"testscript\"" +
|
|
||||||
// Using math.random() to avoid confusing cache behaviors within the test
|
|
||||||
" src=\"http://mochi.test:8888/tests/dom/security/test/csp/file_require_sri_meta.js?" + Math.random() + "\"";
|
|
||||||
|
|
||||||
const WRONG_INTEGRITY =
|
|
||||||
" integrity=\"sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC\"";
|
|
||||||
|
|
||||||
const CORRECT_INEGRITY =
|
|
||||||
" integrity=\"sha384-PkcuZQHmjBQKRyv1v3x0X8qFmXiSyFyYIP+f9SU86XWvRneifdNCPg2cYFWBuKsF\"";
|
|
||||||
|
|
||||||
const POST_INTEGRITY =
|
|
||||||
" onload=\"window.parent.postMessage({result: 'script-loaded'}, '*');\"" +
|
|
||||||
" onerror=\"window.parent.postMessage({result: 'script-blocked'}, '*');\"" +
|
|
||||||
"></script>" +
|
|
||||||
"</body>" +
|
|
||||||
"</html>";
|
|
||||||
|
|
||||||
function handleRequest(request, response)
|
|
||||||
{
|
|
||||||
// avoid confusing cache behaviors
|
|
||||||
response.setHeader("Cache-Control", "no-cache", false);
|
|
||||||
response.setHeader("Content-Type", "text/html", false);
|
|
||||||
|
|
||||||
var queryString = request.queryString;
|
|
||||||
|
|
||||||
if (queryString === "no-sri") {
|
|
||||||
response.write(PRE_INTEGRITY + POST_INTEGRITY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryString === "wrong-sri") {
|
|
||||||
response.write(PRE_INTEGRITY + WRONG_INTEGRITY + POST_INTEGRITY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queryString === "correct-sri") {
|
|
||||||
response.write(PRE_INTEGRITY + CORRECT_INEGRITY + POST_INTEGRITY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we should never get here, but just in case
|
|
||||||
// return something unexpected
|
|
||||||
response.write("do'h");
|
|
||||||
}
|
|
|
@ -191,8 +191,6 @@ support-files =
|
||||||
file_sandbox_11.html
|
file_sandbox_11.html
|
||||||
file_sandbox_12.html
|
file_sandbox_12.html
|
||||||
file_sandbox_13.html
|
file_sandbox_13.html
|
||||||
file_require_sri_meta.sjs
|
|
||||||
file_require_sri_meta.js
|
|
||||||
file_sendbeacon.html
|
file_sendbeacon.html
|
||||||
file_upgrade_insecure_docwrite_iframe.sjs
|
file_upgrade_insecure_docwrite_iframe.sjs
|
||||||
file_data-uri_blocked.html
|
file_data-uri_blocked.html
|
||||||
|
@ -317,7 +315,6 @@ tags = mcb
|
||||||
[test_iframe_sandbox_top_1.html]
|
[test_iframe_sandbox_top_1.html]
|
||||||
[test_sandbox.html]
|
[test_sandbox.html]
|
||||||
[test_ping.html]
|
[test_ping.html]
|
||||||
[test_require_sri_meta.html]
|
|
||||||
[test_sendbeacon.html]
|
[test_sendbeacon.html]
|
||||||
[test_upgrade_insecure_docwrite_iframe.html]
|
[test_upgrade_insecure_docwrite_iframe.html]
|
||||||
[test_bug1242019.html]
|
[test_bug1242019.html]
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Bug 1277557 - CSP require-sri-for does not block when CSP is in meta tag</title>
|
|
||||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<iframe style="width:100%;" id="testframe"></iframe>
|
|
||||||
|
|
||||||
<script class="testbody" type="text/javascript">
|
|
||||||
|
|
||||||
/* Description of the test:
|
|
||||||
* We load scripts within an iframe and make sure that meta-csp of
|
|
||||||
* require-sri-for applies correctly to preloaded scripts.
|
|
||||||
* Please note that we have to use <script src=""> to kick
|
|
||||||
* off the html preloader.
|
|
||||||
*/
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
|
|
||||||
|
|
||||||
var curTest;
|
|
||||||
var counter = -1;
|
|
||||||
|
|
||||||
const tests = [
|
|
||||||
{ // test 1
|
|
||||||
description: "script with *no* SRI should be blocked",
|
|
||||||
query: "no-sri",
|
|
||||||
expected: "script-blocked"
|
|
||||||
},
|
|
||||||
{ // test 2
|
|
||||||
description: "script-with *incorrect* SRI should be blocked",
|
|
||||||
query: "wrong-sri",
|
|
||||||
expected: "script-blocked"
|
|
||||||
},
|
|
||||||
{ // test 3
|
|
||||||
description: "script-with *correct* SRI should be loaded",
|
|
||||||
query: "correct-sri",
|
|
||||||
expected: "script-loaded"
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
function finishTest() {
|
|
||||||
window.removeEventListener("message", receiveMessage);
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkResults(result) {
|
|
||||||
is(result, curTest.expected, curTest.description);
|
|
||||||
loadNextTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("message", receiveMessage);
|
|
||||||
function receiveMessage(event) {
|
|
||||||
checkResults(event.data.result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadNextTest() {
|
|
||||||
counter++;
|
|
||||||
if (counter == tests.length) {
|
|
||||||
finishTest();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
curTest = tests[counter];
|
|
||||||
var testframe = document.getElementById("testframe");
|
|
||||||
testframe.src = "file_require_sri_meta.sjs?" + curTest.query;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadNextTest();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -209,8 +209,6 @@ TEST(CSPParser, Directives) {
|
||||||
"script-src 'sha256-a'" },
|
"script-src 'sha256-a'" },
|
||||||
{ "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='",
|
{ "script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='",
|
||||||
"script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" },
|
"script-src 'sha256-siVR8vAcqP06h2ppeNwqgjr0yZ6yned4X2VF84j4GmI='" },
|
||||||
{ "require-sri-for script style",
|
|
||||||
"require-sri-for script style"},
|
|
||||||
{ "script-src 'nonce-foo' 'unsafe-inline' ",
|
{ "script-src 'nonce-foo' 'unsafe-inline' ",
|
||||||
"script-src 'nonce-foo' 'unsafe-inline'" },
|
"script-src 'nonce-foo' 'unsafe-inline'" },
|
||||||
{ "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https: ",
|
{ "script-src 'nonce-foo' 'strict-dynamic' 'unsafe-inline' https: ",
|
||||||
|
@ -287,8 +285,6 @@ TEST(CSPParser, IgnoreUpperLowerCasePolicies) {
|
||||||
"upgrade-insecure-requests" },
|
"upgrade-insecure-requests" },
|
||||||
{ "sanDBox alloW-foRMs",
|
{ "sanDBox alloW-foRMs",
|
||||||
"sandbox allow-forms"},
|
"sandbox allow-forms"},
|
||||||
{ "require-SRI-for sCript stYle",
|
|
||||||
"require-sri-for script style"},
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -553,8 +549,6 @@ TEST(CSPParser, PoliciesWithInvalidSrc) {
|
||||||
"connect-src 'none'" },
|
"connect-src 'none'" },
|
||||||
{ "script-src https://foo.com/%$",
|
{ "script-src https://foo.com/%$",
|
||||||
"script-src 'none'" },
|
"script-src 'none'" },
|
||||||
{ "require-SRI-for script elephants",
|
|
||||||
"require-sri-for script"},
|
|
||||||
{ "sandbox foo",
|
{ "sandbox foo",
|
||||||
"sandbox"},
|
"sandbox"},
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -576,10 +570,10 @@ TEST(CSPParser, BadPolicies) {
|
||||||
{ "defaut-src asdf", "" },
|
{ "defaut-src asdf", "" },
|
||||||
{ "default-src: aaa", "" },
|
{ "default-src: aaa", "" },
|
||||||
{ "asdf http://test.com", ""},
|
{ "asdf http://test.com", ""},
|
||||||
{ "require-sri-for", ""},
|
|
||||||
{ "require-sri-for foo", ""},
|
|
||||||
{ "report-uri", ""},
|
{ "report-uri", ""},
|
||||||
{ "report-uri http://:foo", ""},
|
{ "report-uri http://:foo", ""},
|
||||||
|
{ "require-sri-for", ""},
|
||||||
|
{ "require-sri-for style", ""},
|
||||||
// clang-format on
|
// clang-format on
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<!-- file should be loaded (text is blue), but subsequent files shouldn't (text is red) -->
|
|
||||||
<link rel="stylesheet" href="style_importing.css"
|
|
||||||
integrity="sha384-m5Q2GOhAtLrdiv6rCmxY3GjEFMVInALcdTyDnEddUUiDH2uQvJSX5GSJYQiatpTK"
|
|
||||||
onload="parent.postMessage('finish', '*');"
|
|
||||||
onerror="parent.postMessage('finish', '*');">
|
|
||||||
<p id="text-for-import-test">blue text</p>
|
|
|
@ -1 +0,0 @@
|
||||||
content-security-policy: require-sri-for script style
|
|
|
@ -1,47 +0,0 @@
|
||||||
<script>
|
|
||||||
window.hasCORSLoaded = false; // set through script_crossdomain1.js
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- script tag cors-enabled. should be loaded -->
|
|
||||||
<script src="http://example.com/tests/dom/security/test/sri/script_crossdomain1.js"
|
|
||||||
crossorigin=""
|
|
||||||
integrity="sha512-9Tv2DL1fHvmPQa1RviwKleE/jq72jgxj8XGLyWn3H6Xp/qbtfK/jZINoPFAv2mf0Nn1TxhZYMFULAbzJNGkl4Q=="
|
|
||||||
onload="parent.postMessage('good_sriLoaded', '*');"></script>
|
|
||||||
|
|
||||||
<!-- script tag cors but not using SRI. should trigger onerror -->
|
|
||||||
<script src="http://example.com/tests/dom/security/test/sri/script_crossdomain5.js"
|
|
||||||
onload="parent.postMessage('bad_nonsriLoaded', '*');"
|
|
||||||
onerror="parent.postMessage('good_nonsriBlocked', '*');"></script>
|
|
||||||
|
|
||||||
<!-- svg:script tag with cors but not using SRI. should trigger onerror -->
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<script xlink:href="http://example.com/tests/dom/security/test/sri/script_crossdomain3.js"
|
|
||||||
onload="parent.postMessage('bad_svg_nonsriLoaded', '*');"
|
|
||||||
onerror="parent.postMessage('good_svg_nonsriBlocked', '*');"></script>
|
|
||||||
></script>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
<!-- stylesheet with cors and integrity. it should just load fine. -->
|
|
||||||
<link rel="stylesheet" href="style1.css"
|
|
||||||
integrity="sha256-qs8lnkunWoVldk5d5E+652yth4VTSHohlBKQvvgGwa8="
|
|
||||||
onload="parent.postMessage('good_sriLoaded', '*');">
|
|
||||||
|
|
||||||
<!-- stylesheet not using SRI, should trigger onerror -->
|
|
||||||
<link rel="stylesheet" href="style3.css"
|
|
||||||
onload="parent.postMessage('bad_nonsriLoaded', '*');"
|
|
||||||
onerror="parent.postMessage('good_nonsriBlocked', '*');">
|
|
||||||
|
|
||||||
|
|
||||||
<p id="black-text">black text</p>
|
|
||||||
<script>
|
|
||||||
// this worker should not load,
|
|
||||||
// given that we can not provide integrity metadata through the constructor
|
|
||||||
w = new Worker("rsf_worker.js");
|
|
||||||
w.onerror = function(e) {
|
|
||||||
if (typeof w == "object") {
|
|
||||||
parent.postMessage("finish", '*');
|
|
||||||
} else {
|
|
||||||
parent.postMessage("error", "*")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1 +0,0 @@
|
||||||
content-security-policy: require-sri-for script style
|
|
|
@ -1,5 +0,0 @@
|
||||||
<script>
|
|
||||||
w = new Worker("rsf_csp_worker.js");
|
|
||||||
// use the handler function in the parent frame (test_require-sri-for_csp_directive.html)
|
|
||||||
w.onmessage = parent.handler;
|
|
||||||
</script>
|
|
|
@ -1,20 +1,11 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
support-files =
|
support-files =
|
||||||
file_bug_1271796.css
|
file_bug_1271796.css
|
||||||
iframe_csp_directive_style_imports.html
|
|
||||||
iframe_csp_directive_style_imports.html^headers^
|
|
||||||
iframe_require-sri-for_main.html
|
|
||||||
iframe_require-sri-for_main.html^headers^
|
|
||||||
iframe_require-sri-for_no_csp.html
|
|
||||||
iframe_script_crossdomain.html
|
iframe_script_crossdomain.html
|
||||||
iframe_script_sameorigin.html
|
iframe_script_sameorigin.html
|
||||||
iframe_sri_disabled.html
|
iframe_sri_disabled.html
|
||||||
iframe_style_crossdomain.html
|
iframe_style_crossdomain.html
|
||||||
iframe_style_sameorigin.html
|
iframe_style_sameorigin.html
|
||||||
rsf_csp_worker.js
|
|
||||||
rsf_csp_worker.js^headers^
|
|
||||||
rsf_imported.js
|
|
||||||
rsf_worker.js
|
|
||||||
script_crossdomain1.js
|
script_crossdomain1.js
|
||||||
script_crossdomain1.js^headers^
|
script_crossdomain1.js^headers^
|
||||||
script_crossdomain2.js
|
script_crossdomain2.js
|
||||||
|
@ -51,8 +42,5 @@ support-files =
|
||||||
[test_sri_disabled.html]
|
[test_sri_disabled.html]
|
||||||
[test_style_crossdomain.html]
|
[test_style_crossdomain.html]
|
||||||
[test_style_sameorigin.html]
|
[test_style_sameorigin.html]
|
||||||
[test_require-sri-for_csp_directive.html]
|
|
||||||
[test_require-sri-for_csp_directive_disabled.html]
|
|
||||||
[test_bug_1271796.html]
|
[test_bug_1271796.html]
|
||||||
[test_csp_directive_style_imports.html]
|
|
||||||
[test_bug_1364262.html]
|
[test_bug_1364262.html]
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
postMessage("good_worker_could_load");
|
|
||||||
try {
|
|
||||||
importScripts('rsf_imported.js');
|
|
||||||
} catch(e) {
|
|
||||||
postMessage("good_worker_after_importscripts");
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
postMessage("finish");
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
content-security-policy: require-sri-for script style
|
|
|
@ -1 +0,0 @@
|
||||||
postMessage('bad_worker_could_load_via_importScripts');
|
|
|
@ -1,3 +0,0 @@
|
||||||
w = new Worker("rsf_csp_worker.js");
|
|
||||||
// use the handler function in test_require-sri-for_csp_directive.html
|
|
||||||
w.onmessage = parent.handler;
|
|
|
@ -1,2 +0,0 @@
|
||||||
parent.postMessage('bad_worker_could_load', '*');
|
|
||||||
importScripts('rsf_imported.js');
|
|
|
@ -1,42 +0,0 @@
|
||||||
<!--
|
|
||||||
Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for SRI require-sri-for CSP directive</title>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a><br>
|
|
||||||
<iframe style="width:200px;height:200px;" id="test_frame"></iframe><br>
|
|
||||||
</body>
|
|
||||||
<script type="application/javascript">
|
|
||||||
var finished = 0;
|
|
||||||
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
function handler(event) {
|
|
||||||
console.log(event);
|
|
||||||
switch (event.data) {
|
|
||||||
case 'finish':
|
|
||||||
// need finish message from iframe_require-sri-for_main onload event and
|
|
||||||
// from iframe_require-sri-for_no_csp, which spawns a Worker
|
|
||||||
var importText = frame.contentDocument.getElementById('text-for-import-test');
|
|
||||||
var importColor = frame.contentWindow.getComputedStyle(importText).getPropertyValue('color');
|
|
||||||
ok(importColor == 'rgb(0, 0, 255)', "The import should not work without integrity. The text is now red, but should not.");
|
|
||||||
removeEventListener('message', handler);
|
|
||||||
SimpleTest.finish();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ok(false, 'Something is wrong here');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addEventListener("message", handler);
|
|
||||||
// This frame has a CSP that requires SRI
|
|
||||||
var frame = document.getElementById("test_frame");
|
|
||||||
frame.src = "iframe_csp_directive_style_imports.html";
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -1,76 +0,0 @@
|
||||||
<!--
|
|
||||||
Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for SRI require-sri-for CSP directive</title>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a><br>
|
|
||||||
<iframe style="width:200px;height:200px;" id="test_frame"></iframe><br>
|
|
||||||
<iframe style="width:200px;height:200px;" id="test_frame_no_csp"></iframe>
|
|
||||||
</body>
|
|
||||||
<script type="application/javascript">
|
|
||||||
var finished = 0;
|
|
||||||
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", true);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
function handler(event) {
|
|
||||||
switch (event.data) {
|
|
||||||
case 'good_sriLoaded':
|
|
||||||
ok(true, "Eligible SRI resources was correctly loaded.");
|
|
||||||
break;
|
|
||||||
case 'bad_nonsriLoaded':
|
|
||||||
ok(false, "Eligible non-SRI resource should be blocked by the CSP!");
|
|
||||||
break;
|
|
||||||
case 'good_nonsriBlocked':
|
|
||||||
ok(true, "Eligible non-SRI resources was correctly blocked by the CSP.");
|
|
||||||
break;
|
|
||||||
case 'bad_svg_nonsriLoaded':
|
|
||||||
ok(false, 'Eligible non-SRI resource should be blocked by the CSP.');
|
|
||||||
break;
|
|
||||||
case 'good_svg_nonsriBlocked':
|
|
||||||
ok(true, 'Eligible non-SRI svg script was correctly blocked by the CSP.');
|
|
||||||
break;
|
|
||||||
case 'bad_worker_could_load':
|
|
||||||
ok(false, 'require-sri-for failed to block loading a Worker with no integrity metadata.');
|
|
||||||
break;
|
|
||||||
case 'good_worker_could_load':
|
|
||||||
ok(true, "Loaded a worker that has require-sri-for set (but its parent doesnt).")
|
|
||||||
break;
|
|
||||||
case 'bad_worker_could_load_via_importScripts':
|
|
||||||
ok(false, 'require-sri-for failed to block loading importScript in a worker though we require SRI via CSP');
|
|
||||||
break;
|
|
||||||
case 'good_worker_after_importscripts':
|
|
||||||
ok(true, 'Worker continued after failed importScript due to require-sri-for');
|
|
||||||
break;
|
|
||||||
case 'finish':
|
|
||||||
finished++;
|
|
||||||
if (finished > 1) {
|
|
||||||
// need finish message from iframe_require-sri-for_main onload event and
|
|
||||||
// from iframe_require-sri-for_no_csp, which spawns a Worker
|
|
||||||
var blackText = frame.contentDocument.getElementById('black-text');
|
|
||||||
var blackTextColor = frame.contentWindow.getComputedStyle(blackText).getPropertyValue('color');
|
|
||||||
ok(blackTextColor == 'rgb(0, 0, 0)', "The second part should not be black.");
|
|
||||||
removeEventListener('message', handler);
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ok(false, 'Something is wrong here');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addEventListener("message", handler);
|
|
||||||
// This frame has a CSP that requires SRI
|
|
||||||
var frame = document.getElementById("test_frame");
|
|
||||||
frame.src = "iframe_require-sri-for_main.html";
|
|
||||||
// This frame has no CSP to require SRI.
|
|
||||||
// Used for testing require-sri-for in a Worker.
|
|
||||||
var frame_no_csp = document.getElementById("test_frame_no_csp");
|
|
||||||
frame_no_csp.src = "iframe_require-sri-for_no_csp.html";
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -1,46 +0,0 @@
|
||||||
<!--
|
|
||||||
Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
-->
|
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for diabled SRI require-sri-for CSP directive</title>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1265318">Mozilla Bug 1265318</a>
|
|
||||||
<iframe style="width:200px;height:200px;" id="test_frame"></iframe>
|
|
||||||
</body>
|
|
||||||
<script type="application/javascript">
|
|
||||||
SpecialPowers.setBoolPref("security.csp.experimentalEnabled", false);
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
function handler(event) {
|
|
||||||
switch (event.data) {
|
|
||||||
case 'good_sriLoaded':
|
|
||||||
ok(true, "Eligible SRI resources was correctly loaded.");
|
|
||||||
break;
|
|
||||||
case 'bad_nonsriLoaded':
|
|
||||||
ok(true, "Eligible non-SRI resource should be blocked by the CSP!");
|
|
||||||
break;
|
|
||||||
case 'good_nonsriBlocked':
|
|
||||||
ok(false, "Eligible non-SRI resources was correctly blocked by the CSP.");
|
|
||||||
break;
|
|
||||||
case 'finish':
|
|
||||||
var blackText = frame.contentDocument.getElementById('black-text');
|
|
||||||
var blackTextColor = frame.contentWindow.getComputedStyle(blackText).getPropertyValue('color');
|
|
||||||
ok(blackTextColor != 'rgb(0, 0, 0)', "The second part should still be black.");
|
|
||||||
removeEventListener('message', handler);
|
|
||||||
SimpleTest.finish();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ok(false, 'Something is wrong here');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addEventListener("message", handler);
|
|
||||||
var frame = document.getElementById("test_frame");
|
|
||||||
frame.src = "iframe_require-sri-for_main.html";
|
|
||||||
</script>
|
|
||||||
</html>
|
|
|
@ -28,7 +28,6 @@ dictionary CSP {
|
||||||
sequence<DOMString> upgrade-insecure-requests;
|
sequence<DOMString> upgrade-insecure-requests;
|
||||||
sequence<DOMString> child-src;
|
sequence<DOMString> child-src;
|
||||||
sequence<DOMString> block-all-mixed-content;
|
sequence<DOMString> block-all-mixed-content;
|
||||||
sequence<DOMString> require-sri-for;
|
|
||||||
sequence<DOMString> sandbox;
|
sequence<DOMString> sandbox;
|
||||||
sequence<DOMString> worker-src;
|
sequence<DOMString> worker-src;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2193,11 +2193,6 @@ VARCACHE_PREF(
|
||||||
bool, true
|
bool, true
|
||||||
)
|
)
|
||||||
|
|
||||||
VARCACHE_PREF(
|
|
||||||
"security.csp.experimentalEnabled",
|
|
||||||
security_csp_experimentalEnabled,
|
|
||||||
bool, false
|
|
||||||
)
|
|
||||||
|
|
||||||
VARCACHE_PREF(
|
VARCACHE_PREF(
|
||||||
"security.csp.enableStrictDynamic",
|
"security.csp.enableStrictDynamic",
|
||||||
|
|
|
@ -282,35 +282,6 @@ LoadInfo::LoadInfo(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If CSP requires SRI (require-sri-for), then store that information
|
|
||||||
// in the loadInfo so we can enforce SRI before loading the subresource.
|
|
||||||
if (!mEnforceSRI) {
|
|
||||||
// do not look into the CSP if already true:
|
|
||||||
// a CSP saying that SRI isn't needed should not
|
|
||||||
// overrule GetVerifySignedContent
|
|
||||||
if (aLoadingPrincipal) {
|
|
||||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
|
||||||
aLoadingPrincipal->GetCsp(getter_AddRefs(csp));
|
|
||||||
uint32_t externalType =
|
|
||||||
nsContentUtils::InternalContentPolicyTypeToExternal(
|
|
||||||
aContentPolicyType);
|
|
||||||
// csp could be null if loading principal is system principal
|
|
||||||
if (csp) {
|
|
||||||
csp->RequireSRIForType(externalType, &mEnforceSRI);
|
|
||||||
}
|
|
||||||
// if CSP is delivered via a meta tag, it's speculatively available
|
|
||||||
// as 'preloadCSP'. If we are preloading a script or style, we have
|
|
||||||
// to apply that speculative 'preloadCSP' for such loads.
|
|
||||||
if (!mEnforceSRI && nsContentUtils::IsPreloadType(aContentPolicyType)) {
|
|
||||||
nsCOMPtr<nsIContentSecurityPolicy> preloadCSP;
|
|
||||||
aLoadingPrincipal->GetPreloadCsp(getter_AddRefs(preloadCSP));
|
|
||||||
if (preloadCSP) {
|
|
||||||
preloadCSP->RequireSRIForType(externalType, &mEnforceSRI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mOriginAttributes = mLoadingPrincipal->OriginAttributesRef();
|
mOriginAttributes = mLoadingPrincipal->OriginAttributesRef();
|
||||||
|
|
||||||
// We need to do this after inheriting the document's origin attributes
|
// We need to do this after inheriting the document's origin attributes
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>import() doesn't have any integrity metadata when initiated by compiled strings inside a classic script</title>
|
|
||||||
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="require-sri-for script">
|
|
||||||
|
|
||||||
<script src="/resources/testharness.js" integrity="sha384-{{file_hash(sha384, resources/testharness.js)}}"></script>
|
|
||||||
<script src="/resources/testharnessreport.js" integrity="sha384-{{file_hash(sha384, resources/testharnessreport.js)}}"></script>
|
|
||||||
|
|
||||||
<div id="dummy"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function createTestPromise() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
window.continueTest = resolve;
|
|
||||||
window.errorTest = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const dummyDiv = document.querySelector("#dummy");
|
|
||||||
|
|
||||||
const evaluators = {
|
|
||||||
eval,
|
|
||||||
setTimeout,
|
|
||||||
"the Function constructor"(x) {
|
|
||||||
Function(x)();
|
|
||||||
},
|
|
||||||
"reflected inline event handlers"(x) {
|
|
||||||
dummyDiv.setAttribute("onclick", x);
|
|
||||||
dummyDiv.onclick();
|
|
||||||
},
|
|
||||||
"inline event handlers triggered via UA code"(x) {
|
|
||||||
dummyDiv.setAttribute("onclick", x);
|
|
||||||
dummyDiv.click(); // different from .**on**click()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [label, evaluator] of Object.entries(evaluators)) {
|
|
||||||
promise_test(t => {
|
|
||||||
t.add_cleanup(() => {
|
|
||||||
dummyDiv.removeAttribute("onclick");
|
|
||||||
delete window.evaluated_imports_a;
|
|
||||||
});
|
|
||||||
|
|
||||||
const promise = createTestPromise();
|
|
||||||
|
|
||||||
evaluator(`import('../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
|
|
||||||
|
|
||||||
return promise_rejects(t, new TypeError(), promise);
|
|
||||||
}, label + " should fail to import");
|
|
||||||
};
|
|
||||||
</script>
|
|
|
@ -1,52 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>import() doesn't have any integrity metadata when initiated by compiled strings inside a module script</title>
|
|
||||||
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="require-sri-for script">
|
|
||||||
|
|
||||||
<script src="/resources/testharness.js" integrity="sha384-{{file_hash(sha384, resources/testharness.js)}}"></script>
|
|
||||||
<script src="/resources/testharnessreport.js" integrity="sha384-{{file_hash(sha384, resources/testharnessreport.js)}}"></script>
|
|
||||||
|
|
||||||
<div id="dummy"></div>
|
|
||||||
|
|
||||||
<script type="module">
|
|
||||||
function createTestPromise() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
window.continueTest = resolve;
|
|
||||||
window.errorTest = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const dummyDiv = document.querySelector("#dummy");
|
|
||||||
|
|
||||||
const evaluators = {
|
|
||||||
eval,
|
|
||||||
setTimeout,
|
|
||||||
"the Function constructor"(x) {
|
|
||||||
Function(x)();
|
|
||||||
},
|
|
||||||
"reflected inline event handlers"(x) {
|
|
||||||
dummyDiv.setAttribute("onclick", x);
|
|
||||||
dummyDiv.onclick();
|
|
||||||
},
|
|
||||||
"inline event handlers triggered via UA code"(x) {
|
|
||||||
dummyDiv.setAttribute("onclick", x);
|
|
||||||
dummyDiv.click(); // different from .**on**click()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [label, evaluator] of Object.entries(evaluators)) {
|
|
||||||
promise_test(t => {
|
|
||||||
t.add_cleanup(() => {
|
|
||||||
dummyDiv.removeAttribute("onclick");
|
|
||||||
delete window.evaluated_imports_a;
|
|
||||||
});
|
|
||||||
|
|
||||||
const promise = createTestPromise();
|
|
||||||
|
|
||||||
evaluator(`import('../imports-a.js?label=${label}').then(window.continueTest, window.errorTest);`);
|
|
||||||
|
|
||||||
return promise_rejects(t, new TypeError(), promise);
|
|
||||||
}, label + " should fail to import");
|
|
||||||
};
|
|
||||||
</script>
|
|
Загрузка…
Ссылка в новой задаче