зеркало из 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 CHILD_SRC_DIRECTIVE = 17;
|
||||
const unsigned short BLOCK_ALL_MIXED_CONTENT = 18;
|
||||
const unsigned short REQUIRE_SRI_FOR = 19;
|
||||
const unsigned short SANDBOX_DIRECTIVE = 20;
|
||||
const unsigned short WORKER_SRC_DIRECTIVE = 21;
|
||||
const unsigned short SANDBOX_DIRECTIVE = 19;
|
||||
const unsigned short WORKER_SRC_DIRECTIVE = 20;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Checks if a CSP requires Subresource Integrity (SRI)
|
||||
* for a given nsContentPolicyType.
|
||||
*/
|
||||
bool requireSRIForType(in nsContentPolicyType aContentType);
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
blockAllMixedContent = Blocking insecure request ‘%1$S’.
|
||||
# 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.
|
||||
# LOCALIZATION NOTE (ignoringReportOnlyDirective):
|
||||
# %1$S is the directive that is ignored in report-only mode.
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
"upgrade-insecure-requests"
|
||||
"child-src"
|
||||
"block-all-mixed-content"
|
||||
"require-sri-for"
|
||||
"sandbox"
|
||||
"worker-src"
|
||||
"plugin-types"
|
||||
|
|
|
@ -679,12 +679,6 @@ nsCSPContext::LogViolationDetails(
|
|||
SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC);
|
||||
CASE_CHECK_AND_REPORT(HASH_STYLE, STYLESHEET, aContent, CSP_UNSAFE_INLINE,
|
||||
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:
|
||||
NS_ASSERTION(false, "LogViolationDetails with invalid type");
|
||||
|
@ -1386,22 +1380,6 @@ nsresult nsCSPContext::AsyncReportViolation(
|
|||
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
|
||||
* ancestry.
|
||||
|
|
|
@ -60,9 +60,6 @@ static const uint32_t kSubHostPathCharacterCutoff = 512;
|
|||
static const char* const kHashSourceValidFns[] = {"sha256", "sha384", "sha512"};
|
||||
static const uint32_t kHashSourceValidFnsLen = 3;
|
||||
|
||||
static const char* const kStyle = "style";
|
||||
static const char* const kScript = "script";
|
||||
|
||||
/* ===== nsCSPParser ==================== */
|
||||
|
||||
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) {
|
||||
CSPPARSERLOG(("nsCSPParser::reportURIList"));
|
||||
|
||||
|
@ -902,9 +853,7 @@ nsCSPDirective* nsCSPParser::directiveName() {
|
|||
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
||||
|
||||
// Check if it is a valid directive
|
||||
if (!CSP_IsValidDirective(mCurToken) ||
|
||||
(!StaticPrefs::security_csp_experimentalEnabled() &&
|
||||
CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR))) {
|
||||
if (!CSP_IsValidDirective(mCurToken)) {
|
||||
const char16_t* params[] = {mCurToken.get()};
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
||||
"couldNotProcessUnknownDirective", params,
|
||||
|
@ -1001,10 +950,6 @@ nsCSPDirective* nsCSPParser::directiveName() {
|
|||
return mScriptSrc;
|
||||
}
|
||||
|
||||
if (CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REQUIRE_SRI_FOR)) {
|
||||
return new nsRequireSRIForDirective(CSP_StringToCSPDirective(mCurToken));
|
||||
}
|
||||
|
||||
return new nsCSPDirective(CSP_StringToCSPDirective(mCurToken));
|
||||
}
|
||||
|
||||
|
@ -1069,13 +1014,6 @@ void nsCSPParser::directive() {
|
|||
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
|
||||
// a valid source list but rather actual URIs)
|
||||
if (CSP_IsDirective(mCurDir[0],
|
||||
|
|
|
@ -40,7 +40,6 @@ class nsCSPParser {
|
|||
void directive();
|
||||
nsCSPDirective* directiveName();
|
||||
void directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs);
|
||||
void requireSRIForDirectiveValue(nsRequireSRIForDirective* aDir);
|
||||
void referrerDirectiveValue(nsCSPDirective* aDir);
|
||||
void reportURIList(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);
|
||||
return;
|
||||
|
||||
// REQUIRE_SRI_FOR is handled in nsCSPPolicy::toDomCSPStruct()
|
||||
|
||||
default:
|
||||
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));
|
||||
}
|
||||
|
||||
/* ===== 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()
|
||||
|
@ -1523,13 +1476,3 @@ bool nsCSPPolicy::visitDirectiveSrcs(CSPDirective aDir,
|
|||
}
|
||||
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 SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script 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
|
||||
// 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
|
||||
"child-src", // CHILD_SRC_DIRECTIVE
|
||||
"block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
|
||||
"require-sri-for", // REQUIRE_SRI_FOR
|
||||
"sandbox", // SANDBOX_DIRECTIVE
|
||||
"worker-src" // WORKER_SRC_DIRECTIVE
|
||||
};
|
||||
|
@ -110,14 +105,13 @@ inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
|
|||
return nsIContentSecurityPolicy::NO_DIRECTIVE;
|
||||
}
|
||||
|
||||
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
||||
MACRO(CSP_SELF, "'self'") \
|
||||
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
||||
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
||||
MACRO(CSP_NONE, "'none'") \
|
||||
MACRO(CSP_NONCE, "'nonce-") \
|
||||
MACRO(CSP_REQUIRE_SRI_FOR, "require-sri-for") \
|
||||
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
|
||||
#define FOR_EACH_CSP_KEYWORD(MACRO) \
|
||||
MACRO(CSP_SELF, "'self'") \
|
||||
MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
|
||||
MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
|
||||
MACRO(CSP_NONE, "'none'") \
|
||||
MACRO(CSP_NONCE, "'nonce-") \
|
||||
MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
|
||||
MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'")
|
||||
|
||||
enum CSPKeyword {
|
||||
|
@ -607,26 +601,6 @@ class nsUpgradeInsecureDirective : public nsCSPDirective {
|
|||
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 ================== */
|
||||
|
||||
class nsCSPPolicy {
|
||||
|
@ -677,8 +651,6 @@ class nsCSPPolicy {
|
|||
|
||||
uint32_t getSandboxFlags() const;
|
||||
|
||||
bool requireSRIForType(nsContentPolicyType aContentType);
|
||||
|
||||
inline uint32_t getNumDirectives() const { return mDirectives.Length(); }
|
||||
|
||||
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_12.html
|
||||
file_sandbox_13.html
|
||||
file_require_sri_meta.sjs
|
||||
file_require_sri_meta.js
|
||||
file_sendbeacon.html
|
||||
file_upgrade_insecure_docwrite_iframe.sjs
|
||||
file_data-uri_blocked.html
|
||||
|
@ -317,7 +315,6 @@ tags = mcb
|
|||
[test_iframe_sandbox_top_1.html]
|
||||
[test_sandbox.html]
|
||||
[test_ping.html]
|
||||
[test_require_sri_meta.html]
|
||||
[test_sendbeacon.html]
|
||||
[test_upgrade_insecure_docwrite_iframe.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-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' 'strict-dynamic' 'unsafe-inline' https: ",
|
||||
|
@ -287,8 +285,6 @@ TEST(CSPParser, IgnoreUpperLowerCasePolicies) {
|
|||
"upgrade-insecure-requests" },
|
||||
{ "sanDBox alloW-foRMs",
|
||||
"sandbox allow-forms"},
|
||||
{ "require-SRI-for sCript stYle",
|
||||
"require-sri-for script style"},
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -553,8 +549,6 @@ TEST(CSPParser, PoliciesWithInvalidSrc) {
|
|||
"connect-src 'none'" },
|
||||
{ "script-src https://foo.com/%$",
|
||||
"script-src 'none'" },
|
||||
{ "require-SRI-for script elephants",
|
||||
"require-sri-for script"},
|
||||
{ "sandbox foo",
|
||||
"sandbox"},
|
||||
// clang-format on
|
||||
|
@ -576,10 +570,10 @@ TEST(CSPParser, BadPolicies) {
|
|||
{ "defaut-src asdf", "" },
|
||||
{ "default-src: aaa", "" },
|
||||
{ "asdf http://test.com", ""},
|
||||
{ "require-sri-for", ""},
|
||||
{ "require-sri-for foo", ""},
|
||||
{ "report-uri", ""},
|
||||
{ "report-uri http://:foo", ""},
|
||||
{ "require-sri-for", ""},
|
||||
{ "require-sri-for style", ""},
|
||||
// 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]
|
||||
support-files =
|
||||
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_sameorigin.html
|
||||
iframe_sri_disabled.html
|
||||
iframe_style_crossdomain.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^headers^
|
||||
script_crossdomain2.js
|
||||
|
@ -51,8 +42,5 @@ support-files =
|
|||
[test_sri_disabled.html]
|
||||
[test_style_crossdomain.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_csp_directive_style_imports.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> child-src;
|
||||
sequence<DOMString> block-all-mixed-content;
|
||||
sequence<DOMString> require-sri-for;
|
||||
sequence<DOMString> sandbox;
|
||||
sequence<DOMString> worker-src;
|
||||
};
|
||||
|
|
|
@ -2193,11 +2193,6 @@ VARCACHE_PREF(
|
|||
bool, true
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
"security.csp.experimentalEnabled",
|
||||
security_csp_experimentalEnabled,
|
||||
bool, false
|
||||
)
|
||||
|
||||
VARCACHE_PREF(
|
||||
"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();
|
||||
|
||||
// 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>
|
Загрузка…
Ссылка в новой задаче