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:
Sebastian Streich 2019-03-26 21:58:48 +00:00
Родитель 92b55dddb6
Коммит 82fb5d3ddf
32 изменённых файлов: 14 добавлений и 723 удалений

Просмотреть файл

@ -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>