Update web-platform-tests to revision a46616a5b18e83587ddbbed756c7b96cbb4b015d

This commit is contained in:
Josh Matthews 2017-06-19 19:07:14 -04:00 committed by Ms2ger
parent 3f07cfec7c
commit 578498ba24
4001 changed files with 159517 additions and 30260 deletions

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="base-uri {{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/">
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script>
var t = async_test("Check that base URIs can be set if they do not violate the page's policy.");
window.addEventListener('securitypolicyviolation', t.step_func(function(t) {
assert_unreached('No CSP violation report should have been fired.');
}));
</script>
<base href="{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/">
<script>
t.step(function() {
assert_equals(document.baseURI, "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/");
t.done();
});
</script>
</head>
<body>
</html>

View file

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="base-uri {{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}/">
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script>
var t = async_test("Check that baseURI fires a securitypolicyviolation event when it does not match the csp directive");
window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
assert_equals(e.blockedURI, "{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/")
assert_equals(e.violatedDirective, "base-uri");
}));
</script>
<base href="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/">
<script>
test(function() {
assert_equals(document.baseURI, window.location.href);
t.done();
}, "Check that the baseURI is not set when it does not match the csp directive");
</script>
</head>
<body>
</html>

View file

@ -2,12 +2,11 @@
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="base-uri {{location[scheme]}}://{{domains[]}}:{{ports[http][0]}}/base/">
<title>base-uri works correctly inside a sandboxed iframe.</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<!-- CSP served: base-uri 'self' -->
</head>
<body>
@ -16,7 +15,7 @@
<script>
window.addEventListener('securitypolicyviolation', function(e) {
assert_unreached('No CSP violation report has fired.');
assert_unreached('No CSP violation report should have been fired.');
});
async_test(function(t) {
@ -24,21 +23,21 @@
i.sandbox = 'allow-scripts';
i.style.display = 'none';
i.srcdoc = `
<script>
window.addEventListener('securitypolicyviolation', function() {
top.postMessage('FAIL', '*');
});
</sc` + `ript>
<base href="{{location[scheme]}}://{{domains[]}}:{{ports[http][0]}}/base/">
<script>
top.postMessage(document.baseURI, '*');
</sc` + `ript>`;
<script>
window.addEventListener('securitypolicyviolation', function() {
top.postMessage('FAIL', '*');
});
</sc` + `ript>
<base href="{{location[scheme]}}://{{domains[]}}:{{ports[http][0]}}/base/">
<script>
top.postMessage(document.baseURI, '*');
</sc` + `ript>`;
window.addEventListener('message', t.step_func(function(e) {
if (e.source === i.contentWindow) {
assert_equals(e.data, location.origin + '/base/');
t.done();
}
if (e.source === i.contentWindow) {
assert_equals(e.data, location.origin + '/base/');
t.done();
}
}));
document.body.appendChild(i);

View file

@ -1,5 +0,0 @@
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
Content-Security-Policy: base-uri 'self'

View file

@ -1,70 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Embedding-CSP header.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testharness-helper.sub.js"></script>
</head>
<body>
<script>
// When this test starts passing please merge with embedding_csp-header.html
var tests = [
{ "name": "Wrong value of `csp` should not trigger sending Embedding-CSP Header.",
"csp": "completely wrong csp",
"expected": null},
];
tests.forEach(test => {
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
assert_embedding_csp(t, url, test.csp, test.expected);
}, "Test same origin: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.SAME_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test same origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect of cross origin iframe: " + test.name);
async_test(t => {
var i = document.createElement('iframe');
if (test.csp)
i.csp = test.csp;
i.src = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var loaded = false;
window.addEventListener('message', t.step_func(e => {
if (e.source != i.contentWindow || !('embedding_csp' in e.data))
return;
if (!loaded) {
assert_equals(test.expected, e.data['embedding_csp']);
loaded = true;
i.csp = "default-src 'unsafe-inline'";
i.src = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.EMBEDDING_CSP);
} else {
// Once iframe has loaded, check that on change of `src` attribute
// Embedding-CSP value is based on latest `csp` attribute value.
assert_equals("default-src 'unsafe-inline'", e.data['embedding_csp']);
t.done();
}
}));
document.body.appendChild(i);
}, "Test Embedding-CSP value on `csp` change: " + test.name);
});
</script>
</body>
</html>

View file

@ -1,75 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Embedding-CSP header.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testharness-helper.sub.js"></script>
</head>
<body>
<script>
var tests = [
{ "name": "Embedding-CSP is not sent if `csp` attribute is not set on <iframe>.",
"csp": null,
"expected": null },
{ "name": "Send Embedding-CSP when `csp` attribute of <iframe> is not empty.",
"csp": "script-src 'unsafe-inline'",
"expected": "script-src 'unsafe-inline'" },
{ "name": "Send Embedding-CSP Header on change of `src` attribute on iframe.",
"csp": "script-src 'unsafe-inline'",
"expected": "script-src 'unsafe-inline'" },
];
tests.forEach(test => {
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
assert_embedding_csp(t, url, test.csp, test.expected);
}, "Test same origin: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.SAME_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test same origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_embedding_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect of cross origin iframe: " + test.name);
async_test(t => {
var i = document.createElement('iframe');
if (test.csp)
i.csp = test.csp;
i.src = generateURLString(Host.SAME_ORIGIN, PolicyHeader.EMBEDDING_CSP);
var loaded = false;
window.addEventListener('message', t.step_func(e => {
if (e.source != i.contentWindow || !('embedding_csp' in e.data))
return;
if (!loaded) {
assert_equals(test.expected, e.data['embedding_csp']);
loaded = true;
i.csp = "default-src 'unsafe-inline'";
i.src = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.EMBEDDING_CSP);
} else {
// Once iframe has loaded, check that on change of `src` attribute
// Embedding-CSP value is based on latest `csp` attribute value.
assert_equals("default-src 'unsafe-inline'", e.data['embedding_csp']);
t.done();
}
}));
document.body.appendChild(i);
}, "Test Embedding-CSP value on `csp` change: " + test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Sec-Required-CSP header.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testharness-helper.sub.js"></script>
</head>
<body>
<script>
var tests = [
{ "name": "Sec-Required-CSP is not sent if `csp` attribute is not set on <iframe>.",
"csp": null,
"expected": null },
{ "name": "Send Sec-Required-CSP when `csp` attribute of <iframe> is not empty.",
"csp": "script-src 'unsafe-inline'",
"expected": "script-src 'unsafe-inline'" },
{ "name": "Send Sec-Required-CSP Header on change of `src` attribute on iframe.",
"csp": "script-src 'unsafe-inline'",
"expected": "script-src 'unsafe-inline'" },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - gibberish csp",
"csp": "completely wrong csp",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - unknown policy name",
"csp": "invalid-policy-name http://example.com",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - unknown policy name in multiple directives",
"csp": "default-src http://example.com; invalid-policy-name http://example.com",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - misspeled 'none'",
"csp": "default-src 'non'",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - query values in path",
"csp": "script-src 127.0.0.1:8000/path?query=string",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - missing semicolon",
"csp": "script-src 'self' object-src 'self' style-src *",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - comma separated",
"csp": "script-src 'none', object-src 'none'",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - html encoded string",
// script-src 127.0.0.1:8000
"csp": "script-src &#x31;&#x32;&#x37;&#x2E;&#x30;&#x2E;&#x30;&#x2E;&#x31;&#x3A;&#x38;&#x30;&#x30;&#x30;",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - url encoded string",
// script-src 127.0.0.1:8000
"csp": "script-src%20127.0.0.1%3A8000",
"expected": null },
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - report-uri present",
"csp": "script-src 'unsafe-inline'; report-uri resources/dummy-report.php",
"expected": null },
// TODO(andypaicu): when `report-to` is implemented, add tests here.
];
tests.forEach(test => {
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.REQUIRED_CSP);
assert_required_csp(t, url, test.csp, test.expected);
}, "Test same origin: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.REQUIRED_CSP);
var redirect_url = generateRedirect(Host.SAME_ORIGIN, url);
assert_required_csp(t, redirect_url, test.csp, test.expected);
}, "Test same origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.SAME_ORIGIN, PolicyHeader.REQUIRED_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_required_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect: " + test.name);
async_test(t => {
var url = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.REQUIRED_CSP);
var redirect_url = generateRedirect(Host.CROSS_ORIGIN, url);
assert_required_csp(t, redirect_url, test.csp, test.expected);
}, "Test cross origin redirect of cross origin iframe: " + test.name);
async_test(t => {
var i = document.createElement('iframe');
if (test.csp)
i.csp = test.csp;
i.src = generateURLString(Host.SAME_ORIGIN, PolicyHeader.REQUIRED_CSP);
var loaded = false;
window.addEventListener('message', t.step_func(e => {
if (e.source != i.contentWindow || !('required_csp' in e.data))
return;
if (!loaded) {
assert_equals(e.data['required_csp'], test.expected);
loaded = true;
i.csp = "default-src 'unsafe-inline'";
i.src = generateURLString(Host.CROSS_ORIGIN, PolicyHeader.REQUIRED_CSP);
} else {
// Once iframe has loaded, check that on change of `src` attribute
// Required-CSP value is based on latest `csp` attribute value.
assert_equals(e.data['required_csp'], "default-src 'unsafe-inline'");
t.done();
}
}));
document.body.appendChild(i);
}, "Test Required-CSP value on `csp` change: " + test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Nonces.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/testharness-helper.sub.js"></script>
</head>
<body>
<script>
var tests = [
{ "name": "Exact nonce subsumes.",
"required_csp": "script-src 'nonce-abc'",
"returned_csp_1": "script-src 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Any nonce subsumes.",
"required_csp": "style-src 'nonce-abc'",
"returned_csp_1": "style-src 'nonce-xyz'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "A nonce has to be returned if required by the embedder.",
"required_csp": "script-src 'nonce-abc'",
"returned_csp_1": "script-src http://example1.com/foo",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Multiples nonces returned subsume.",
"required_csp": "style-src 'nonce-abc'",
"returned_csp_1": "style-src 'nonce-xyz' 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
// nonce intersection
{ "name": "Nonce intersection is still done on exact match - non-matching nonces.",
"required_csp": "script-src 'nonce-abc'",
"returned_csp_1": "script-src 'nonce-def'",
"returned_csp_2": "script-src 'nonce-xyz'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Nonce intersection is still done on exact match - matching nonces.",
"required_csp": "style-src 'nonce-abc'",
"returned_csp_1": "style-src 'nonce-def'",
"returned_csp_2": "style-src 'nonce-def' 'nonce-xyz'",
"expected": IframeLoad.EXPECT_LOAD },
// other expressions still have to work
{ "name": "Other expressions still have to be subsumed - positive test.",
"required_csp": "style-src http://example1.com/foo/ 'nonce-abc'",
"returned_csp_1": "style-src http://example1.com/foo/ 'nonce-xyz'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Other expressions still have to be subsumed - negative test",
"required_csp": "script-src http://example1.com/foo/ 'nonce-abc'",
"returned_csp_1": "script-src http://not-example1.com/foo/ 'nonce-xyz'",
"expected": IframeLoad.EXPECT_BLOCK },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp_1);
if (test.returned_csp_2)
url.searchParams.append("policy2", test.returned_csp_2);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -1,8 +1,8 @@
import json
def main(request, response):
header = request.headers.get("Embedding-CSP");
header = request.headers.get("Sec-Required-CSP");
message = {}
message['embedding_csp'] = header if header else None
message['required_csp'] = header if header else None
return [("Content-Type", "text/html"), ("Allow-CSP-From", "*")], '''
<!DOCTYPE html>
<html>

View file

@ -6,7 +6,7 @@ const Host = {
const PolicyHeader = {
CSP: "echo-policy.py?policy=",
CSP_MULTIPLE: "echo-policy-multiple.py",
EMBEDDING_CSP: "echo-embedding-csp.py",
REQUIRED_CSP: "echo-required-csp.py",
ALLOW_CSP_FROM: "echo-allow-csp-from.py",
};
@ -68,16 +68,16 @@ function generateUrlWithAllowCSPFrom(host, allowCspFrom) {
return url;
}
function assert_embedding_csp(t, url, csp, expected) {
function assert_required_csp(t, url, csp, expected) {
var i = document.createElement('iframe');
if(csp)
i.csp = csp;
i.src = url;
window.addEventListener('message', t.step_func(e => {
if (e.source != i.contentWindow || !('embedding_csp' in e.data))
return;
assert_equals(expected, e.data['embedding_csp']);
if (e.source != i.contentWindow || !('required_csp' in e.data))
return;
assert_equals(e.data['required_csp'], expected);
t.done();
}));

View file

@ -0,0 +1,35 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./support/testharness-helper.sub.js"></script>
<body></body>
<script>
function waitForViolation(el, policy, blocked_origin) {
return new Promise(resolve => {
el.addEventListener('securitypolicyviolation', e => {
if (e.originalPolicy == policy && (new URL(e.blockedURI)).origin == blocked_origin)
resolve(e);
});
});
}
async_test(t => {
var i = document.createElement("iframe");
var redirect = generateCrossOriginRedirectFrame();
i.src = redirect.url;
// Report-only policy should trigger a violation on the original request.
var original_report_only = waitForViolation(window, "frame-src http://foo.test", (new URL(i.src)).origin)
// Report-only policy should trigger a violation on the redirected request.
var redirect_report_only = waitForViolation(window, "frame-src http://foo.test", (new URL(redirect.target)).origin)
// Enforced policy should trigger a violation on the redirected request.
var redirect_enforced = waitForViolation(window, "frame-src 'self'", (new URL(redirect.target)).origin)
Promise.all([original_report_only, redirect_report_only, redirect_enforced]).then(t.step_func(_ => {
t.done();
}));
document.body.appendChild(i);
}, "Redirected iframe src should evaluate both enforced and report-only policies on both original request and when following redirect");
</script>
</html>

View file

@ -0,0 +1,2 @@
Content-Security-Policy: frame-src 'self'
Content-Security-Policy-Report-Only: frame-src http://foo.test

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>frame-src-self-unique-origin</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<p>
The origin of an URL is called "unique" when it is considered to be
different from every origin, including itself. The origin of a
data-url is unique. When the current origin is unique, the CSP source
'self' must not match any URL.
</p>
<script>
var iframe = document.createElement("iframe");
iframe.src = encodeURI(`data:text/html,
<script>
/* Add the CSP: frame-src: 'self'. */
var meta = document.createElement('meta');
meta.httpEquiv = 'Content-Security-Policy';
meta.content = "frame-src 'self'";
document.getElementsByTagName('head')[0].appendChild(meta);
/* Notify the parent the iframe has been blocked. */
window.addEventListener('securitypolicyviolation', e => {
if (e.originalPolicy == "frame-src 'self'")
window.parent.postMessage('Test PASS', '*');
});
</scr`+`ipt>
This iframe should be blocked by CSP:
<iframe src='data:text/html,blocked_iframe'></iframe>
`);
if (window.async_test) {
async_test(t => {
window.addEventListener("message", e => {
if (e.data == "Test PASS")
t.done();
});
}, "Iframe's url must not match with 'self'. It must be blocked.");
}
document.body.appendChild(iframe);
</script>
</body>
</html>

View file

@ -0,0 +1,2 @@
<!doctype html>
</html>

View file

@ -0,0 +1,5 @@
function generateCrossOriginRedirectFrame() {
var target = "http://{{domains[天気の良い日]}}:" + document.location.port + "/content-security-policy/frame-src/support/frame.html";
var url = "/common/redirect.py?location=" + encodeURIComponent(target);
return { url: url, target: target };
}

View file

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>img-src-self-unique-origin</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<p>
The origin of an URL is called "unique" when it is considered to be
different from every origin, including itself. The origin of a
data-url is unique. When the current origin is unique, the CSP source
'self' must not match any URL.
</p>
<script>
var iframe = document.createElement("iframe");
iframe.src = encodeURI(`data:text/html,
<script>
/* Add the CSP: frame-src: 'self'. */
var meta = document.createElement('meta');
meta.httpEquiv = 'Content-Security-Policy';
meta.content = "img-src 'self'";
document.getElementsByTagName('head')[0].appendChild(meta);
/* Notify the parent the image has been blocked. */
window.addEventListener('securitypolicyviolation', e => {
if (e.originalPolicy == "img-src 'self'")
window.parent.postMessage('Test PASS', '*');
});
</scr`+`ipt>
This image should be blocked by CSP:
<img src='data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'></img>
`);
if (window.async_test) {
async_test(t => {
window.addEventListener("message", e => {
if (e.data == "Test PASS")
t.done();
});
}, "Image's url must not match with 'self'. Image must be blocked.");
}
document.body.appendChild(iframe);
</script>
</body>
</html>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta http-equiv="Content-Security-Policy" content="frame-src 'none'">
<body>
<script>
var t = async_test("<iframe src='javascript:...'> not blocked by 'frame-src'");
var i = document.createElement('iframe');
i.src = "javascript:window.top.t.done();";
document.body.appendChild(i);
</script>

View file

@ -0,0 +1,130 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'">
<body>
<!-- Basics -->
<script nonce="abc" id="testScript">
document.currentScript.setAttribute('executed', 'yay');
</script>
<script nonce="abc">
var script = document.querySelector('#testScript');
test(t => {
// Query Selector
assert_equals(document.querySelector('body [nonce]'), script);
assert_equals(document.querySelector('body [nonce=""]'), null);
assert_equals(document.querySelector('body [nonce=abc]'), script);
assert_equals(script.getAttribute('nonce'), 'abc');
assert_equals(script.nonce, 'abc');
}, "Reading 'nonce' content attribute and IDL attribute.");
// Clone node.
test(t => {
script.setAttribute('executed', 'boo');
var s2 = script.cloneNode();
assert_equals(s2.nonce, 'abc', 'IDL attribute');
assert_equals(s2.getAttribute('nonce'), 'abc');
}, "Cloned node retains nonce.");
async_test(t => {
var s2 = script.cloneNode();
document.head.appendChild(s2);
assert_equals(s2.nonce, 'abc');
assert_equals(s2.getAttribute('nonce'), 'abc');
window.addEventListener('load', t.step_func_done(_ => {
// The cloned script won't execute, as its 'already started' flag is set.
assert_equals(s2.getAttribute('executed'), 'boo');
}));
}, "Cloned node retains nonce when inserted.");
// Set the content attribute to 'foo'
test(t => {
script.setAttribute('nonce', 'foo');
assert_equals(script.getAttribute('nonce'), 'foo');
assert_equals(script.nonce, 'foo');
}, "Writing 'nonce' content attribute.");
// Set the IDL attribute to 'bar'
test(t => {
script.nonce = 'bar';
assert_equals(script.nonce, 'bar');
assert_equals(script.getAttribute('nonce'), 'foo');
}, "Writing 'nonce' IDL attribute.");
// Fragment parser.
var documentWriteTest = async_test("Document-written script executes.");
document.write(`<script nonce='abc'>
documentWriteTest.done();
test(t => {
var script = document.currentScript;
assert_equals(script.getAttribute('nonce'), 'abc');
assert_equals(script.nonce, 'abc');
}, "Document-written script's nonce value.");
</scr` + `ipt>`);
// Create node.
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.nonce = 'abc';
document.head.appendChild(s);
assert_equals(s.nonce, 'abc');
assert_equals(s.getAttribute('nonce'), null);
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "createElement.nonce.");
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.nonce = 'zyx';
s.setAttribute('nonce', 'abc');
assert_equals(s.nonce, 'abc');
document.head.appendChild(s);
assert_equals(s.nonce, 'abc');
assert_equals(s.getAttribute('nonce'), 'abc');
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "setAttribute('nonce') overwrites '.nonce' upon insertion.");
// Create node.
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.setAttribute('nonce', 'abc');
assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content");
assert_equals(s.nonce, 'abc', "Pre-insertion IDL");
document.head.appendChild(s);
assert_equals(s.nonce, 'abc', "Post-insertion IDL");
assert_equals(s.getAttribute('nonce'), 'abc', "Post-insertion content");
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "createElement.setAttribute.");
</script>
<!-- CSS Leakage -->
<style>
#cssTest { display: block; }
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
</style>
<script nonce="abc" id="cssTest">
async_test(t => {
requestAnimationFrame(t.step_func_done(_ => {
var script = document.querySelector('#cssTest');
var style = getComputedStyle(script);
assert_equals(style['display'], 'block');
assert_equals(style['background-image'], "url(\"http://web-platform.test:8001/security/resources/abe.png\")");
}));
}, "Nonces leak via CSS side-channels.");
</script>

View file

@ -0,0 +1,131 @@
<!DOCTYPE html>
<script src="/resources/testharness.js" nonce="abc"></script>
<script src="/resources/testharnessreport.js" nonce="abc"></script>
<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers -->
<body>
<!-- Basics -->
<script nonce="abc" id="testScript">
document.currentScript.setAttribute('executed', 'yay');
</script>
<script nonce="abc">
var script = document.querySelector('#testScript');
test(t => {
// Query Selector
assert_equals(document.querySelector('body [nonce]'), script);
assert_equals(document.querySelector('body [nonce=""]'), script);
assert_equals(document.querySelector('body [nonce=abc]'), null);
assert_equals(script.getAttribute('nonce'), '');
assert_equals(script.nonce, 'abc');
}, "Reading 'nonce' content attribute and IDL attribute.");
// Clone node.
test(t => {
script.setAttribute('executed', 'boo');
var s2 = script.cloneNode();
assert_equals(s2.nonce, 'abc', 'IDL attribute');
assert_equals(s2.getAttribute('nonce'), '');
}, "Cloned node retains nonce.");
async_test(t => {
var s2 = script.cloneNode();
document.head.appendChild(s2);
assert_equals(s2.nonce, 'abc');
assert_equals(s2.getAttribute('nonce'), '');
window.addEventListener('load', t.step_func_done(_ => {
// The cloned script won't execute, as its 'already started' flag is set.
assert_equals(s2.getAttribute('executed'), 'boo');
}));
}, "Cloned node retains nonce when inserted.");
// Set the content attribute to 'foo'
test(t => {
script.setAttribute('nonce', 'foo');
assert_equals(script.getAttribute('nonce'), 'foo');
assert_equals(script.nonce, 'foo');
}, "Writing 'nonce' content attribute.");
// Set the IDL attribute to 'bar'
test(t => {
script.nonce = 'bar';
assert_equals(script.nonce, 'bar');
assert_equals(script.getAttribute('nonce'), 'foo');
}, "Writing 'nonce' IDL attribute.");
// Fragment parser.
var documentWriteTest = async_test("Document-written script executes.");
document.write(`<script nonce='abc'>
documentWriteTest.done();
test(t => {
var script = document.currentScript;
assert_equals(script.getAttribute('nonce'), '');
assert_equals(script.nonce, 'abc');
}, "Document-written script's nonce value.");
</scr` + `ipt>`);
// Create node.
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.nonce = 'abc';
document.head.appendChild(s);
assert_equals(s.nonce, 'abc');
assert_equals(s.getAttribute('nonce'), null);
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "createElement.nonce.");
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.nonce = 'zyx';
s.setAttribute('nonce', 'abc');
assert_equals(s.nonce, 'abc');
document.head.appendChild(s);
assert_equals(s.nonce, 'abc');
assert_equals(s.getAttribute('nonce'), '');
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "setAttribute('nonce') overwrites '.nonce' upon insertion.");
// Create node.
async_test(t => {
var s = document.createElement('script');
s.innerText = script.innerText;
s.setAttribute('nonce', 'abc');
assert_equals(s.getAttribute('nonce'), 'abc', "Pre-insertion content");
assert_equals(s.nonce, 'abc', "Pre-insertion IDL");
document.head.appendChild(s);
assert_equals(s.nonce, 'abc', "Post-insertion IDL");
assert_equals(s.getAttribute('nonce'), '', "Post-insertion content");
window.addEventListener('load', t.step_func_done(_ => {
assert_equals(s.getAttribute('executed'), 'yay');
}));
}, "createElement.setAttribute.");
</script>
<!-- CSS Leakage -->
<style>
#cssTest { display: block; }
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
</style>
<script nonce="abc" id="cssTest">
async_test(t => {
requestAnimationFrame(t.step_func_done(_ => {
var script = document.querySelector('#cssTest');
var style = getComputedStyle(script);
assert_equals(style['display'], 'block');
assert_equals(style['background-image'], 'none');
}));
}, "Nonces don't leak via CSS side-channels.");
</script>

View file

@ -0,0 +1 @@
Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'

View file

@ -0,0 +1,116 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<meta http-equiv="content-security-policy" content="script-src 'nonce-abc'; img-src 'none'">
<body>
<!-- Basics -->
<svg xmlns="http://www.w3.org/2000/svg">
<script nonce="abc" id="testScript">
document.currentScript.setAttribute('executed', 'yay');
</script>
</svg>
<script nonce="abc">
var script = document.querySelector('#testScript');
test(t => {
// Query Selector
assert_equals(document.querySelector('[nonce]'), script);
assert_equals(document.querySelector('[nonce=""]'), null);
assert_equals(document.querySelector('[nonce=abc]'), script);
assert_equals(script.getAttribute('nonce'), 'abc');
assert_equals(script.nonce, 'abc');
}, "Reading 'nonce' content attribute and IDL attribute.");
// Clone node.
test(t => {
script.setAttribute('executed', 'boo');
var s2 = script.cloneNode();
assert_equals(s2.nonce, 'abc', 'IDL attribute');
assert_equals(s2.getAttribute('nonce'), 'abc');
}, "Cloned node retains nonce.");
async_test(t => {
var s2 = script.cloneNode();
document.head.appendChild(s2);
assert_equals(s2.nonce, 'abc');
assert_equals(s2.getAttribute('nonce'), 'abc');
window.addEventListener('load', t.step_func_done(_ => {
// The cloned script won't execute, as its 'already started' flag is set.
assert_equals(s2.getAttribute('executed'), 'boo');
}));
}, "Cloned node retains nonce when inserted.");
// Set the content attribute to 'foo'
test(t => {
script.setAttribute('nonce', 'foo');
assert_equals(script.getAttribute('nonce'), 'foo');
assert_equals(script.nonce, 'abc');
}, "Writing 'nonce' content attribute.");
// Set the IDL attribute to 'bar'
test(t => {
script.nonce = 'bar';
assert_equals(script.nonce, 'bar');
assert_equals(script.getAttribute('nonce'), 'foo');
}, "Writing 'nonce' IDL attribute.");
// Fragment parser.
var documentWriteTest = async_test("Document-written script executes.");
document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'>
documentWriteTest.done();
test(t => {
var script = document.currentScript;
assert_equals(script.getAttribute('nonce'), 'abc');
assert_equals(script.nonce, 'abc');
}, "Document-written script's nonce value.");
</scr` + `ipt></svg>`);
// Create node.
test(t => {
var s = document.createElement('svg');
var innerScript = document.createElement('innerScript');
innerScript.innerText = script.innerText;
innerScript.nonce = 'abc';
s.appendChild(innerScript);
document.body.appendChild(s);
assert_equals(innerScript.nonce, 'abc');
assert_equals(innerScript.getAttribute('nonce'), null, 'innerScript.getAttribute nonce');
}, "createElement.nonce.");
// Create node.
test(t => {
var s = document.createElement('svg');
var innerScript = document.createElement('script');
innerScript.innerText = script.innerText;
innerScript.setAttribute('nonce', 'abc');
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content");
assert_equals(innerScript.nonce, 'abc', "Pre-insertion IDL");
s.appendChild(innerScript);
document.body.appendChild(s);
assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL");
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Post-insertion content");
}, "createElement.setAttribute.");
</script>
<!-- CSS Leakage -->
<style>
#cssTest { display: block; }
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
</style>
<svg xmlns="http://www.w3.org/2000/svg">
<script nonce="abc" id="cssTest">
async_test(t => {
requestAnimationFrame(t.step_func_done(_ => {
var script = document.querySelector('#cssTest');
var style = getComputedStyle(script);
assert_equals(style['display'], 'block');
assert_equals(style['background-image'], "url(\"http://web-platform.test:8001/security/resources/abe.png\")");
}));
}, "Nonces don't leak via CSS side-channels.");
</script>
</svg>

View file

@ -0,0 +1,116 @@
<!DOCTYPE html>
<script src="/resources/testharness.js" nonce="abc"></script>
<script src="/resources/testharnessreport.js" nonce="abc"></script>
<!-- `Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'` delivered via headers -->
<body>
<!-- Basics -->
<svg xmlns="http://www.w3.org/2000/svg">
<script nonce="abc" id="testScript">
document.currentScript.setAttribute('executed', 'yay');
</script>
</svg>
<script nonce="abc">
var script = document.querySelector('#testScript');
test(t => {
// Query Selector
assert_equals(document.querySelector('body [nonce]'), script);
assert_equals(document.querySelector('body [nonce=""]'), script);
assert_equals(document.querySelector('body [nonce=abc]'), null);
assert_equals(script.getAttribute('nonce'), '');
assert_equals(script.nonce, 'abc');
}, "Reading 'nonce' content attribute and IDL attribute.");
// Clone node.
test(t => {
script.setAttribute('executed', 'boo');
var s2 = script.cloneNode();
assert_equals(s2.nonce, 'abc', 'IDL attribute');
assert_equals(s2.getAttribute('nonce'), '');
}, "Cloned node retains nonce.");
async_test(t => {
var s2 = script.cloneNode();
document.head.appendChild(s2);
assert_equals(s2.nonce, 'abc');
assert_equals(s2.getAttribute('nonce'), '');
window.addEventListener('load', t.step_func_done(_ => {
// The cloned script won't execute, as its 'already started' flag is set.
assert_equals(s2.getAttribute('executed'), 'boo');
}));
}, "Cloned node retains nonce when inserted.");
// Set the content attribute to 'foo'
test(t => {
script.setAttribute('nonce', 'foo');
assert_equals(script.getAttribute('nonce'), 'foo');
assert_equals(script.nonce, 'abc');
}, "Writing 'nonce' content attribute.");
// Set the IDL attribute to 'bar'
test(t => {
script.nonce = 'bar';
assert_equals(script.nonce, 'bar');
assert_equals(script.getAttribute('nonce'), 'foo');
}, "Writing 'nonce' IDL attribute.");
// Fragment parser.
var documentWriteTest = async_test("Document-written script executes.");
document.write(`<svg xmlns="http://www.w3.org/2000/svg"><script nonce='abc'>
documentWriteTest.done();
test(t => {
var script = document.currentScript;
assert_equals(script.getAttribute('nonce'), '');
assert_equals(script.nonce, 'abc');
}, "Document-written script's nonce value.");
</scr` + `ipt></svg>`);
// Create node.
test(t => {
var s = document.createElement('svg');
var innerScript = document.createElement('script');
innerScript.innerText = script.innerText;
innerScript.nonce = 'abc';
s.appendChild(innerScript);
document.body.appendChild(s);
assert_equals(innerScript.nonce, 'abc');
assert_equals(innerScript.getAttribute('nonce'), null);
}, "createElement.nonce.");
// Create node.
test(t => {
var s = document.createElement('svg');
var innerScript = document.createElement('script');
innerScript.innerText = script.innerText;
innerScript.setAttribute('nonce', 'abc');
assert_equals(innerScript.getAttribute('nonce'), 'abc', "Pre-insertion content");
assert_equals(innerScript.nonce, 'abc', "Pre-insertion IDL");
s.appendChild(innerScript);
document.body.appendChild(s);
assert_equals(innerScript.nonce, 'abc', "Post-insertion IDL");
assert_equals(innerScript.getAttribute('nonce'), '', "Post-insertion content");
}, "createElement.setAttribute.");
</script>
<!-- CSS Leakage -->
<style>
#cssTest { display: block; }
#cssTest[nonce=abc] { background: url(/security/resources/abe.png); }
</style>
<svg xmlns="http://www.w3.org/2000/svg">
<script nonce="abc" id="cssTest">
async_test(t => {
requestAnimationFrame(t.step_func_done(_ => {
var script = document.querySelector('#cssTest');
var style = getComputedStyle(script);
assert_equals(style['display'], 'block');
assert_equals(style['background-image'], 'none');
}));
}, "Nonces don't leak via CSS side-channels.");
</script>
</svg>

View file

@ -0,0 +1 @@
Content-Security-Policy: script-src 'nonce-abc'; img-src 'none'

View file

@ -0,0 +1,31 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./support/testharness-helper.sub.js"></script>
<body></body>
<script>
function waitForViolation(el, t, policy, blocked_origin) {
return new Promise(resolve => {
el.addEventListener('securitypolicyviolation', e => {
if (e.originalPolicy == policy && (new URL(e.blockedURI)).origin == blocked_origin)
resolve(e);
else
t.unreached_func("Unexpected violation event for " + e.blockedURI)();
});
});
}
async_test(t => {
var i = document.createElement("img");
var redirect = generateCrossOriginRedirectImage();
i.src = redirect.url;
// Report-only policy should trigger a violation on the redirected request.
waitForViolation(window, t, "img-src https:", (new URL(redirect.target)).origin).then(t.step_func(e => {
t.done();
}));
document.body.appendChild(i);
}, "Image that redirects to http:// URL prohibited by Report-Only must generate a violation report, even with upgrade-insecure-requests");
</script>
</html>

View file

@ -0,0 +1,2 @@
Content-Security-Policy-Report-Only: img-src https:
Content-Security-Policy: upgrade-insecure-requests

View file

@ -0,0 +1,5 @@
function generateCrossOriginRedirectImage() {
var target = "http://{{host}}:{{ports[https][0]}}/content-security-policy/support/pass.png";
var url = "/common/redirect.py?location=" + encodeURIComponent(target);
return { url: url, target: target }
}

View file

@ -0,0 +1,92 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/upgrade-insecure-requests/support/testharness-helper.sub.js"></script>
<body></body>
<script>
function waitForViolation(el, effective_directive) {
return new Promise(resolve => {
el.addEventListener('securitypolicyviolation', e => {
if (e.effectiveDirective == effective_directive)
resolve(e);
});
});
}
async_test(t => {
var url = generateURL(Host.SAME_ORIGIN, Protocol.INSECURE, ResourceType.IMAGE).url;
var i = document.createElement('img');
var loaded = false;
var reported = false;
waitForViolation(window, "img-src")
.then(t.step_func(e => {
reported = true;
if (loaded)
t.done();
}));
i.onload = t.step_func(_ => {
loaded = true;
if (reported)
t.done();
});
i.onerror = t.unreached_func(url + " should load successfully.");
i.src = url;
document.body.appendChild(i);
}, "Upgraded image is reported");
async_test(t => {
var url = generateURL(Host.SAME_ORIGIN, Protocol.INSECURE, ResourceType.FRAME).url;
var i = document.createElement('iframe');
var loaded = false;
var reported = false;
waitForViolation(window, "frame-src")
.then(t.step_func(e => {
reported = true;
if (loaded)
t.done();
}));
window.addEventListener("message", t.step_func(e => {
if (e.source == i.contentWindow) {
i.remove();
loaded = true;
if (reported)
t.done();
}
}));
i.src = url;
document.body.appendChild(i);
}, "Upgraded iframe is reported");
async_test(t => {
// Load an HTTPS iframe, then navigate it to an HTTP URL and check that the HTTP URL is both upgraded and reported.
var url = generateURL(Host.SAME_ORIGIN, Protocol.SECURE, ResourceType.FRAME).url;
var navigate_to = generateURL(Host.CROSS_ORIGIN, Protocol.INSECURE, ResourceType.FRAME).url;
var upgraded = new URL(navigate_to);
upgraded.protocol = "https";
var i = document.createElement('iframe');
var loaded = false;
var reported = false;
window.addEventListener("message", t.step_func(e => {
if (e.source == i.contentWindow) {
if (e.data == (new URL(url)).origin) {
waitForViolation(window, "frame-src")
.then(t.step_func(e => {
reported = true;
if (loaded)
t.done();
}));
i.contentWindow.location.href = navigate_to;
} else if (e.data == (new URL(upgraded)).origin) {
loaded = true;
if (reported)
t.done();
}
}
}));
i.src = url;
document.body.appendChild(i);
}, "Navigated iframe is upgraded and reported");
</script>
</html>

View file

@ -0,0 +1,2 @@
Content-Security-Policy-Report-Only: frame-src https:; img-src https:
Content-Security-Policy: upgrade-insecure-requests