Update web-platform-tests to revision 3137d1d2d7757366a69f8a449b458b5057e0e81e

This commit is contained in:
Ms2ger 2016-12-28 09:51:21 +01:00
parent 81ca858678
commit d6ba94ca28
2339 changed files with 89274 additions and 9328 deletions

View file

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Allow-CSP-From 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": "Same origin iframes are always allowed.",
"origin": Host.SAME_ORIGIN,
"csp": "style-src 'unsafe-inline'; script-src 'unsafe-inline'",
"allow_csp_from": "¢¥§",
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Same origin iframes are allowed even if the Allow-CSP-From is empty.",
"origin": Host.SAME_ORIGIN,
"csp": "style-src 'unsafe-inline'; script-src 'unsafe-inline'",
"allow_csp_from": "",
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Same origin iframes are allowed even if the Allow-CSP-From is not present.",
"origin": Host.SAME_ORIGIN,
"csp": "style-src 'unsafe-inline'; script-src 'unsafe-inline'",
"allow_csp_from": null,
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Same origin iframes are allowed even if Allow-CSP-From does not match origin.",
"origin": Host.SAME_ORIGIN,
"csp": "style-src 'unsafe-inline'; script-src 'unsafe-inline'",
"allow_csp_from": "http://example.com:888",
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Cross origin iframe with an empty Allow-CSP-From header gets blocked.",
"origin": Host.CROSS_ORIGIN,
"csp": "script-src 'unsafe-inline'",
"allow_csp_from": "",
"expected": IframeLoad.EXPECT_BLOCK,
"blockedURI": null},
{ "name": "Cross origin iframe without Allow-CSP-From header gets blocked.",
"origin": Host.CROSS_ORIGIN,
"csp": "script-src 'unsafe-inline'",
"allow_csp_from": null,
"expected": IframeLoad.EXPECT_BLOCK,
"blockedURI": null},
{ "name": "iframe from cross origin does not load without Allow-CSP-From header.",
"origin": Host.CROSS_ORIGIN,
"csp": "style-src 'unsafe-inline'; script-src 'unsafe-inline'",
"allow_csp_from": getOrigin(),
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Iframe with improper Allow-CSP-From header gets blocked.",
"origin": Host.CROSS_ORIGIN,
"csp": "script-src 'unsafe-inline'",
"allow_csp_from": "* ¢¥§",
"expected": IframeLoad.EXPECT_BLOCK,
"blockedURI": null},
{ "name": "Allow-CSP-From header with a star value can be returned.",
"origin": Host.CROSS_ORIGIN,
"csp": "script-src 'unsafe-inline'",
"allow_csp_from": "*",
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": null},
{ "name": "Star Allow-CSP-From header enforces EmbeddingCSP.",
"origin": Host.CROSS_ORIGIN,
"csp": "script-src 'nonce-123'",
"allow_csp_from": "*",
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": "inline"},
{ "name": "Allow-CSP-From header enforces EmbeddingCSP.",
"origin": Host.CROSS_ORIGIN,
"csp": "style-src 'none'; script-src 'nonce-123'",
"allow_csp_from": getOrigin(),
"expected": IframeLoad.EXPECT_LOAD,
"blockedURI": "inline"},
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithAllowCSPFrom(test.origin, test.allow_csp_from);
assert_iframe_with_csp(t, url, test.csp, test.expected, test.name, test.blockedURI);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,78 @@
<!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'" },
{ "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

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<script>
test(t => {
var i = document.createElement('iframe');
assert_equals('', i.csp);
assert_true('csp' in i);
assert_equals('string', typeof i.csp);
}, "<iframe> has a 'csp' attibute which is an empty string if undefined.");
test(t => {
var i = document.createElement('iframe');
i.setAttribute('csp', 123456);
assert_equals('123456', i.csp);
}, "<iframe>'s csp attribute is always a string.");
test(t => {
var i = document.createElement('iframe');
i.csp = 'value';
assert_equals('value', i.getAttribute('csp'));
}, "<iframe>'s 'csp content attribute reflects the IDL attribute.");
test(t => {
var i = document.createElement('iframe');
i.setAttribute('csp', 'value');
assert_equals('value', i.csp);
}, "<iframe>'s IDL attribute reflects the DOM attribute.");
</script>
</body>
</html>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Basic implementation.</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": "If there is no required csp, iframe should load.",
"required_csp": null,
"returned_csp": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Iframe with empty returned CSP should be blocked.",
"required_csp": "style-src 'none';",
"returned_csp": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Iframe with matching CSP should load.",
"required_csp": "style-src 'none'; script-src 'unsafe-inline'",
"returned_csp": "style-src 'none'; script-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Iframe with more restricting CSP should load.",
"required_csp": "script-src 'nonce-abc' 'nonce-123'",
"returned_csp": "script-src 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Iframe with less restricting CSP should be blocked.",
"required_csp": "style-src 'none'; script-src 'none'",
"returned_csp": "style-src 'none'; script-src 'self'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Iframe with a different CSP should be blocked.",
"required_csp": "script-src 'nonce-abc' 'nonce-123'",
"returned_csp": "style-src 'none'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Iframe with a matching and more restrictive ports should load.",
"required_csp": "frame-src http://c.com:443 http://b.com",
"returned_csp": "frame-src http://b.com:80 http://c.com:443",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Iframe should load even if the ports are different but are default for the protocols.",
"required_csp": "frame-src http://b.com:80",
"returned_csp": "child-src https://b.com:443",
"expected": IframeLoad.EXPECT_LOAD },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Hashes.</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": "'sha256-abc123' is properly subsumed.",
"required_csp": "style-src 'sha256-abc123'",
"returned_csp_1": "style-src 'sha256-abc123'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned should not include hashes not present in required csp.",
"required_csp": "style-src http://example.com",
"returned_csp_1": "style-src 'sha256-abc123'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "'sha256-abc123' is properly subsumed with other sources.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes' 'strict-dynamic' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/bar.html 'sha256-abc123'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Hashes do not have to be present in returned csp.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Hashes do not have to be present in returned csp but must not allow all inline behavior.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Other expressions have to be subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-eval' 'sha256-abc123'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Other expressions have to be subsumed but 'unsafe-inline' gets ignored.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'sha256-abc123'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Effective policy is properly found.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-hashed-attributes' 'sha256-abc123'",
"returned_csp_2": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required csp must allow 'sha256-abc123'.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src http://example1.com/foo/ 'self' 'sha256-abc123'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found where 'sha256-abc123' is not subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'sha256-abc123'",
"returned_csp_2": "style-src 'sha256-abc123' 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "'sha256-abc123' is not subsumed by 'sha256-abc456'.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc456'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'sha256-abc123'",
"returned_csp_2": "style-src 'sha256-abc123' 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy now does not allow 'sha256-abc123'.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'sha256-abc456'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'sha256-abc123' 'sha256-abc456'",
"returned_csp_2": "style-src 'sha256-abc456' 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Effective policy is properly found where 'sha256-abc123' is not part of it.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'self'",
"returned_csp_2": "style-src 'sha256-abc123' 'self'",
"expected": IframeLoad.EXPECT_LOAD },
];
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

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Host parts in host source expressions.</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": "Host must match.",
"required_csp": "img-src http://c.com",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Hosts without wildcards must match.",
"required_csp": "img-src http://c.com:* http://inner.b.com",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "More specific subdomain should not match.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src http://inner.b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Specified host should not match a wildcard host.",
"required_csp": "img-src http://c.com:* http://inner.b.com",
"returned_csp": "img-src http://*.b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "A wildcard host should match a more specific host.",
"required_csp": "img-src http://c.com:* http://*.b.com",
"returned_csp": "img-src https://inner.b.com",
"expected": IframeLoad.EXPECT_LOAD },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Path parts in host source expressions.</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": "Returned CSP must specify a path.",
"required_csp": "img-src http://c.com:* http://b.com/example.html",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned CSP has a more specific path.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src http://b.com/example.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Matching paths.",
"required_csp": "img-src http://c.com:* http://b.com/example.html",
"returned_csp": "img-src http://b.com/example.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Empty path is not subsumed by specified paths.",
"required_csp": "img-src http://b.com/page1.html http://b.com/page2.html http://b.com/page3.html",
"returned_csp": "img-src http://b.com/",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "All specific paths match except the order.",
"required_csp": "img-src http://b.com/page1.html http://b.com/page2.html http://b.com/page3.html",
"returned_csp": "img-src http://b.com/page2.html http://b.com/page3.html http://b.com/page1.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP allows only one path.",
"required_csp": "img-src http://b.com/page1.html http://b.com/page2.html http://b.com/page3.html",
"returned_csp": "img-src http://b.com/page2.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "`/` path should be subsumed by an empty path.",
"required_csp": "img-src http://b.com",
"returned_csp": "img-src http://b.com/",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Unspecified path should be subsumed by `/`.",
"required_csp": "img-src http://b.com/",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "That should not be true when required csp specifies a specific page.",
"required_csp": "img-src http://b.com/path.html",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_BLOCK },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Port parts in host source expressions.</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": "Specified ports must match.",
"required_csp": "img-src http://c.com:* http://b.com:80",
"returned_csp": "img-src http://b.com:36",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned CSP should be subsumed even if the port is not specified but is a default port for a scheme.",
"required_csp": "img-src http://c.com:* http://b.com:80",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP should be subsumed even if the port is not specified but is a default port for a more secure scheme.",
"required_csp": "img-src http://c.com:* http://b.com:80",
"returned_csp": "img-src https://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "The same should hold for `ws` case.",
"required_csp": "img-src http://c.com:* ws://b.com:80",
"returned_csp": "img-src wss://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Unspecified ports must match if schemes match.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src https://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP should be subsumed if the port is specified.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src http://b.com:80",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP should be subsumed if the port is specified but the scheme is more secure.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src https://b.com:443",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP should be subsumed if the port is specified but is not default for a more secure scheme.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src https://b.com:36",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned CSP should be subsumed if the ports match but schemes are not identical.",
"required_csp": "img-src http://c.com:* http://b.com:36",
"returned_csp": "img-src https://b.com:36",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP should be subsumed if the ports match but schemes are not identical for `ws`.",
"required_csp": "img-src http://c.com:* ws://b.com:36",
"returned_csp": "img-src wss://b.com:36",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Wildcard port should match unspecified port.",
"required_csp": "img-src http://c.com:* ws://b.com:*",
"returned_csp": "img-src wss://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Wildcard port should match any specific port.",
"required_csp": "img-src http://c.com:* ws://b.com:*",
"returned_csp": "img-src wss://b.com:36",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Wildcard port should match a wildcard.",
"required_csp": "img-src http://c.com:* ws://b.com:*",
"returned_csp": "img-src wss://b.com:*",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Wildcard port should not be subsumed by a default port.",
"required_csp": "img-src http://c.com:* ws://b.com",
"returned_csp": "img-src ws://b.com:*",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Wildcard port should not be subsumed by a spcified port.",
"required_csp": "img-src http://c.com:* ws://b.com:80",
"returned_csp": "img-src ws://b.com:*",
"expected": IframeLoad.EXPECT_BLOCK },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - Scheme parts in host source expressions.</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": "`https` is more restrictive than `http`.",
"required_csp": "img-src http://c.com:* https://b.com",
"returned_csp": "img-src http://b.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "The reverse allows iframe be to be loaded.",
"required_csp": "img-src http://c.com:* http://b.com",
"returned_csp": "img-src https://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Matching `https` protocols.",
"required_csp": "img-src http://c.com:* https://b.com",
"returned_csp": "img-src https://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "`http:` should subsume all host source expressions with this protocol.",
"required_csp": "img-src http:",
"returned_csp": "img-src http://c.com:* https://b.com http://c.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "`http:` should subsume all host source expressions with `https:`.",
"required_csp": "img-src http:",
"returned_csp": "img-src https://c.com:* https://b.com http://c.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "`http:` does not subsume other protocols.",
"required_csp": "img-src http:",
"returned_csp": "img-src https://c.com:* wss://b.com http://c.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "If scheme source is present in returned csp, it must be specified in required csp too.",
"required_csp": "img-src https://c.com:* wss://b.com http://c.com",
"returned_csp": "img-src http:",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "`http:` subsumes other `http:` source expression.",
"required_csp": "img-src http:",
"returned_csp": "img-src http: https://c.com:* https://b.com http://c.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "`http:` subsumes other `https:` source expression and expressions with `http:`.",
"required_csp": "img-src http:",
"returned_csp": "img-src https: https://c.com:* http://b.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "All scheme sources must be subsumed.",
"required_csp": "img-src http: wss:",
"returned_csp": "img-src https: ws:",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "All scheme sources are subsumed by their stronger variants.",
"required_csp": "img-src http: wss:",
"returned_csp": "img-src https: wss:",
"expected": IframeLoad.EXPECT_LOAD },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'none' keyword.</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": "Empty required csp subsumes empty list of returned policies.",
"required_csp": "",
"returned_csp_1": "",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Empty required csp subsumes any list of policies.",
"required_csp": "",
"returned_csp_1": "img-src http://example.com",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Empty required csp subsumes a policy with `none`.",
"required_csp": "",
"returned_csp_1": "img-src 'none'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required policy that allows `none` does not subsume empty list of policies.",
"required_csp": "img-src ",
"returned_csp_1": "",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with effective `none` does not subsume a host source expression.",
"required_csp": "img-src ",
"returned_csp_1": "img-src http://example.com",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with `none` does not subsume a host source expression.",
"required_csp": "img-src 'none'",
"returned_csp_1": "img-src http://example.com",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with effective `none` does not subsume `none` of another directive.",
"required_csp": "img-src ",
"returned_csp_1": "frame-src 'none'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with `none` does not subsume `none` of another directive.",
"required_csp": "img-src 'none'",
"returned_csp_1": "frame-src 'none'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with `none` does not subsume `none` of different directives.",
"required_csp": "img-src ",
"returned_csp_1": "img-src http://*.one.com",
"returned_csp_2": "frame-src https://two.com",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp with `none` subsumes effective list of `none`.",
"required_csp": "img-src ",
"returned_csp_1": "img-src http://*.one.com",
"returned_csp_2": "img-src https://two.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required csp with `none` subsumes effective list of `none` despite other keywords.",
"required_csp": "img-src 'none'",
"returned_csp_1": "img-src http://*.one.com",
"returned_csp_2": "img-src 'self'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Source list with exprssions other than `none` make `none` ineffective.",
"required_csp": "img-src http://example.com 'none'",
"returned_csp_1": "img-src http://example.com",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned csp with `none` is subsumed by any required csp.",
"required_csp": "img-src http://example.com",
"returned_csp_1": "img-src 'none'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned csp with effective `none` is subsumed by any required csp.",
"required_csp": "img-src http://example.com",
"returned_csp_1": "img-src http://example.com",
"returned_csp_2": "img-src http://non-example.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Both required and returned csp are `none`.",
"required_csp": "img-src 'none'",
"returned_csp_1": "img-src 'none'",
"returned_csp_2": "img-src http://non-example.com",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Both required and returned csp are `none` for only one directive.",
"required_csp": "default-src 'none'",
"returned_csp_1": "img-src 'none'",
"returned_csp_2": "script-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Both required and returned csp are empty.",
"required_csp": "img-src ",
"returned_csp_1": "img-src ",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Both required and returned csp are effectively 'none'.",
"required_csp": "img-src ",
"returned_csp_1": "img-src http://a.com",
"returned_csp_2": "img-src http://b.com",
"expected": IframeLoad.EXPECT_LOAD },
];
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

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'self' keyword.</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": "'self' keywords should match.",
"required_csp": "img-src 'self' http://b.com:*",
"returned_csp": "img-src 'self' http://b.com:*",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP does not have to specify 'self'.",
"required_csp": "img-src 'self' http://b.com:*",
"returned_csp": "img-src http://b.com:*",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned CSP must not allow 'self' if required CSP does not.",
"required_csp": "img-src http://b.com:*",
"returned_csp": "img-src 'self' http://b.com:*",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned 'self' should match to an origin's url.",
"required_csp": "img-src 'self' http://b.com:*",
"returned_csp": "img-src " + getCrossOrigin(),
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required 'self' should match to a origin's url.",
"required_csp": "img-src " + getCrossOrigin() + " http://b.com:*",
"returned_csp": "img-src 'self'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required 'self' should subsume a more secure version of origin's url.",
"required_csp": "img-src 'self' http://b.com:*",
"returned_csp": "img-src " + getSecureCrossOrigin(),
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned 'self' should not be subsumed by a more secure version of origin's url.",
"required_csp": "img-src " + getSecureCrossOrigin() + " http://b.com:*",
"returned_csp": "img-src 'self'",
"expected": IframeLoad.EXPECT_BLOCK },
];
tests.forEach(test => {
async_test(t => {
var url = generateUrlWithPolicies(Host.CROSS_ORIGIN, test.returned_csp);
assert_iframe_with_csp(t, url, test.required_csp, test.expected, test.name, null);
}, test.name);
});
</script>
</body>
</html>

View file

@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'strict-dynamic' keyword.</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": "'strict-dynamic' is ineffective for `style-src`.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'strict-dynamic' http://example1.com/foo/bar.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' is ineffective for `img-src`.",
"required_csp": "img-src http://example1.com/foo/ 'self'",
"returned_csp_1": "img-src 'strict-dynamic' http://example1.com/foo/bar.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' is ineffective for `frame-src`.",
"required_csp": "frame-src http://example1.com/foo/ 'self'",
"returned_csp_1": "frame-src 'strict-dynamic' http://example1.com/foo/bar.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' is ineffective for `child-src`.",
"required_csp": "child-src http://example1.com/foo/ 'self'",
"returned_csp_1": "child-src 'strict-dynamic' http://example1.com/foo/bar.html",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' is effective only for `script-src`.",
"required_csp": "script-src http://example1.com/foo/ 'self'",
"returned_csp_1": "script-src 'strict-dynamic' http://example1.com/foo/bar.html",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "'strict-dynamic' is proper handled for finding effective policy.",
"required_csp": "script-src http://example1.com/foo/ 'self'",
"returned_csp_1": "script-src 'strict-dynamic' http://example1.com/foo/bar.html",
"returned_csp_2": "script-src 'strict-dynamic' 'nonce-abc'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "'strict-dynamic' makes host source expressions ineffective.",
"required_csp": "script-src 'strict-dynamic' 'nonce-abc'",
"returned_csp_1": "script-src http://example.com 'strict-dynamic' 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' makes scheme source expressions ineffective.",
"required_csp": "script-src 'strict-dynamic' 'nonce-abc'",
"returned_csp_1": "script-src http: 'strict-dynamic' 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' makes 'self' ineffective.",
"required_csp": "script-src 'strict-dynamic' 'nonce-abc'",
"returned_csp_1": "script-src 'self' 'strict-dynamic' 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' makes 'unsafe-inline' ineffective.",
"required_csp": "script-src 'strict-dynamic' 'nonce-abc'",
"returned_csp_1": "script-src 'unsafe-inline' 'strict-dynamic' 'nonce-abc'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'strict-dynamic' has to be allowed by required csp if it is present in returned csp.",
"required_csp": "script-src 'nonce-abc'",
"returned_csp_1": "script-src 'strict-dynamic' 'nonce-abc'",
"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

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'unsafe-eval' keyword.</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": "'unsafe-eval' is properly subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes' 'strict-dynamic' 'unsafe-eval'",
"returned_csp_1": "style-src http://example1.com/foo/bar.html 'unsafe-eval'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "No other keyword has the same effect as 'unsafe-eval'.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Other expressions have to be subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'unsafe-eval'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-hashed-attributes' 'unsafe-eval'",
"returned_csp_2": "style-src http://example1.com/foo/ 'self' 'unsafe-eval'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required csp must allow 'unsafe-eval'.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src http://example1.com/foo/ 'self' 'unsafe-eval'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found where 'unsafe-eval' is not subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'unsafe-eval'",
"returned_csp_2": "style-src 'unsafe-eval' 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found where 'unsafe-eval' is not part of it.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-hashed-attributes' 'self'",
"returned_csp_2": "style-src 'unsafe-eval' 'self'",
"expected": IframeLoad.EXPECT_LOAD },
];
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

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'unsafe-hashed-attributes' keyword.</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": "'unsafe-hashed-attributes' is properly subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-eval' 'strict-dynamic' 'unsafe-hashed-attributes'",
"returned_csp_1": "style-src http://example1.com/foo/bar.html 'unsafe-hashed-attributes'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "No other keyword has the same effect as 'unsafe-hashed-attributes'.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Other expressions have to be subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'unsafe-hashed-attributes'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-eval' 'unsafe-hashed-attributes'",
"returned_csp_2": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required csp must allow 'unsafe-hashed-attributes'.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src http://example1.com/foo/ 'self' 'unsafe-hashed-attributes'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found where 'unsafe-hashed-attributes' is not subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-eval' 'unsafe-hashed-attributes'",
"returned_csp_2": "style-src 'unsafe-hashed-attributes' 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective policy is properly found where 'unsafe-hashed-attributes' is not part of it.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-eval' 'self'",
"returned_csp_2": "style-src 'unsafe-hashed-attributes' 'self'",
"expected": IframeLoad.EXPECT_LOAD },
];
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

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title>Embedded Enforcement: Subsumption Algorithm - 'unsafe-inline' keyword.</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": "'strict-dynamic' is ineffective for `style-src`.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline' 'strict-dynamic'",
"returned_csp_1": "style-src 'unsafe-inline' http://example1.com/foo/bar.html",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is properly subsumed in `style-src`.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is only ineffective if the effective returned csp has nonces in `style-src`.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src 'unsafe-inline' 'nonce-yay'",
"returned_csp_2": "style-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is only ineffective if the effective returned csp has hashes in `style-src`.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src 'unsafe-inline' 'sha256-abc123'",
"returned_csp_2": "style-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned csp does not have to allow 'unsafe-inline' in `style-src` to be subsumed.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src 'self'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' does not matter if returned csp is effectively `none`.",
"required_csp": "style-src 'unsafe-inline'",
"returned_csp_1": "style-src ",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is properly subsumed in `script-src`.",
"required_csp": "script-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "script-src http://example1.com/foo/ 'unsafe-inline'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Returned csp only loads 'unsafe-inline' scripts with 'nonce-abc'.",
"required_csp": "script-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "script-src 'nonce-abc'",
"returned_csp_2": "script-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is ineffective when nonces are present.",
"required_csp": "script-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "script-src 'unsafe-inline' 'nonce-abc'",
"returned_csp_2": "script-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "'unsafe-inline' is only ineffective if the effective returned csp has hashes in `script-src`.",
"required_csp": "script-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "script-src 'unsafe-inline' 'sha256-abc123' 'nonce-abc'",
"returned_csp_2": "script-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_LOAD },
{ "name": "Required csp allows `strict-dynamic`, but retuned csp does.",
"required_csp": "script-src http://example1.com/foo/ 'unsafe-inline' 'strict-dynamic'",
"returned_csp_1": "script-src 'unsafe-inline' http://example1.com/foo/bar.html",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Required csp does not allow `unsafe-inline`, but retuned csp does.",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-inline'",
"returned_csp_2": null,
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned csp whitelists a nonce.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src 'unsafe-inline' 'nonce-abc'",
"returned_csp_2": "style-src 'nonce-abc'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Returned csp whitelists a hash.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline'",
"returned_csp_1": "style-src 'unsafe-inline' 'sha256-abc123'",
"returned_csp_2": "style-src 'sha256-abc123'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective returned csp allows 'unsafe-inline'",
"required_csp": "style-src http://example1.com/foo/ 'self'",
"returned_csp_1": "style-src 'unsafe-inline' https://example.test/",
"returned_csp_2": "style-src 'unsafe-inline'",
"expected": IframeLoad.EXPECT_BLOCK },
{ "name": "Effective returned csp does not allow 'sha512-321cba' hash.",
"required_csp": "style-src http://example1.com/foo/ 'self' 'unsafe-inline' 'sha512-321cba'",
"returned_csp_1": "style-src http://example1.com/foo/ 'unsafe-inline' 'nonce-yay'",
"returned_csp_2": "style-src http://example1.com/foo/ 'unsafe-inline' 'sha512-321cba'",
"expected": IframeLoad.EXPECT_LOAD },
];
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

@ -0,0 +1,37 @@
import json
def main(request, response):
headers = [("Content-Type", "text/html")]
if "allow_csp_from" in request.GET:
headers.append(("Allow-CSP-From", request.GET["allow_csp_from"]))
message = request.GET["id"]
return headers, '''
<!DOCTYPE html>
<html>
<head>
<title>This page enforces embedder's policies</title>
<script nonce="123">
document.addEventListener("securitypolicyviolation", function(e) {
var response = {};
response["id"] = "%s";
response["securitypolicyviolation"] = true;
response["blockedURI"] = e.blockedURI;
response["lineNumber"] = e.lineNumber;
window.top.postMessage(response, '*');
});
</script>
</head>
<body>
<style>
body {
background-color: maroon;
}
</style>
<script nonce="abc">
var response = {};
response["id"] = "%s";
response["loaded"] = true;
window.top.postMessage(response, '*');
</script>
</body>
</html>
''' % (message, message)

View file

@ -0,0 +1,15 @@
import json
def main(request, response):
header = request.headers.get("Embedding-CSP");
message = {}
message['embedding_csp'] = header if header else None
return [("Content-Type", "text/html"), ("Allow-CSP-From", "*")], '''
<!DOCTYPE html>
<html>
<head>
<script>
window.parent.postMessage({0}, '*');
</script>
</head>
</html>
'''.format(json.dumps(message))

View file

@ -0,0 +1,25 @@
def main(request, response):
headers = [("Content-Type", "text/html")]
if "policy" in request.GET:
headers.append(("Content-Security-Policy", request.GET["policy"]))
if "policy2" in request.GET:
headers.append(("Content-Security-Policy", request.GET["policy2"]))
if "policy3" in request.GET:
headers.append(("Content-Security-Policy", request.GET["policy3"]))
message = request.GET["id"]
return headers, '''
<!DOCTYPE html>
<html>
<head>
<title>This page sets given CSP upon itself.</title>
</head>
<body>
<script nonce="abc">
var response = {};
response["id"] = "%s";
response["loaded"] = true;
window.top.postMessage(response, '*');
</script>
</body>
</html>
''' % (message)

View file

@ -0,0 +1,136 @@
const Host = {
SAME_ORIGIN: "same-origin",
CROSS_ORIGIN: "cross-origin",
};
const PolicyHeader = {
CSP: "echo-policy.py?policy=",
CSP_MULTIPLE: "echo-policy-multiple.py",
EMBEDDING_CSP: "echo-embedding-csp.py",
ALLOW_CSP_FROM: "echo-allow-csp-from.py",
};
const IframeLoad = {
EXPECT_BLOCK: true,
EXPECT_LOAD: false,
};
function getOrigin() {
var url = new URL("http://{{host}}:{{ports[http][0]}}/");
return url.toString();
}
function getCrossOrigin() {
var url = new URL("http://{{domains[天気の良い日]}}:{{ports[http][0]}}/");
return url.toString();
}
function getSecureCrossOrigin() {
// Since wptserve spins up servers on non-default port, 'self' matches
// http://[host]:[specified-port] and https://[host]:[specified-port], but not
// https://[host]:[https-port]. So, we use the http port for this https origin
// in order to verify that a secure variant of a non-secure URL matches 'self'.
var url = new URL("https://{{domains[天気の良い日]}}:{{ports[http][0]}}");
return url.toString();
}
function generateURL(host, path) {
var url = new URL("http://{{host}}:{{ports[http][0]}}/content-security-policy/embedded-enforcement/support/");
url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
url.pathname += path;
return url;
}
function generateURLString(host, path) {
return generateURL(host, path).toString();
}
function generateRedirect(host, target) {
var url = new URL("http://{{host}}:{{ports[http][0]}}/common/redirect.py?location=" +
encodeURIComponent(target));
url.hostname = host == Host.SAME_ORIGIN ? "{{host}}" : "{{domains[天気の良い日]}}";
return url.toString();
}
function generateUrlWithPolicies(host, policy) {
var url = generateURL(host, PolicyHeader.CSP_MULTIPLE);
if (policy != null)
url.searchParams.append("policy", policy);
return url;
}
function generateUrlWithAllowCSPFrom(host, allowCspFrom) {
var url = generateURL(host, PolicyHeader.ALLOW_CSP_FROM);
if (allowCspFrom != null)
url.searchParams.append("allow_csp_from", allowCspFrom);
return url;
}
function assert_embedding_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']);
t.done();
}));
document.body.appendChild(i);
}
function assert_iframe_with_csp(t, url, csp, shouldBlock, urlId, blockedURI) {
var i = document.createElement('iframe');
url.searchParams.append("id", urlId);
i.src = url.toString();
if (csp != null)
i.csp = csp;
var loaded = {};
window.addEventListener("message", function (e) {
if (e.source != i.contentWindow)
return;
if (e.data["loaded"])
loaded[e.data["id"]] = true;
});
if (shouldBlock) {
// Assert iframe does not load and is inaccessible.
window.onmessage = function (e) {
if (e.source != i.contentWindow)
return;
t.unreached_func('No message should be sent from the frame.');
}
i.onload = t.step_func(function () {
// Delay the check until after the postMessage has a chance to execute.
setTimeout(t.step_func_done(function () {
assert_equals(loaded[urlId], undefined);
}), 1);
assert_throws("SecurityError", () => {
var x = i.contentWindow.location.href;
});
});
} else if (blockedURI) {
// Assert iframe loads with an expected violation.
window.addEventListener('message', t.step_func(e => {
if (e.source != i.contentWindow)
return;
assert_equals(e.data["blockedURI"], blockedURI);
t.done();
}));
} else {
// Assert iframe loads.
i.onload = t.step_func(function () {
// Delay the check until after the postMessage has a chance to execute.
setTimeout(t.step_func_done(function () {
assert_true(loaded[urlId]);
}), 1);
});
}
document.body.appendChild(i);
}

View file

@ -3,26 +3,41 @@
<script src="/resources/testharnessreport.js"></script>
<meta http-equiv="Content-Security-Policy" content="script-src 'nonce-abc'">
<body>
<script nonce="abc">
function assert_csp_event_for_element(test, element) {
assert_equals(typeof SecurityPolicyViolationEvent, "function", "These tests require 'SecurityPolicyViolationEvent'.");
document.addEventListener("securitypolicyviolation", test.step_func(e => {
if (e.target != element)
return;
assert_equals(e.blockedURI, "inline");
assert_equals(e.effectiveDirective, "script-src");
assert_equals(element.contentDocument.body.innerText, "");
element.parentNode.removeChild(element);
assert_equals(element.contentDocument.body.innerText, "", "Ensure that 'Fail' doesn't appear in the child document.");
element.remove();
test.done();
}));
}
function navigate_to_javascript_onload(test, iframe) {
iframe.addEventListener("load", test.step_func(e => {
assert_equals(typeof SecurityPolicyViolationEvent, "function");
iframe.contentDocument.addEventListener(
"securitypolicyviolation",
test.unreached_func("The CSP event should be fired in the embedding document, not in the embedee.")
);
iframe.src = "javascript:'Fail.'";
}));
}
async_test(t => {
var i = document.createElement("iframe");
i.src = "javascript:'Fail.'";
assert_csp_event_for_element(t, i);
i.src = "javascript:'Fail.'";
document.body.appendChild(i);
}, "<iframe src='javascript:'> blocked without 'unsafe-inline'.");
@ -30,28 +45,28 @@
var i = document.createElement("iframe");
assert_csp_event_for_element(t, i);
navigate_to_javascript_onload(t, i);
i.onload = _ => { i.src = "javascript:'Fail.'"; }
document.body.appendChild(i);
}, "<iframe> navigated to 'javascript:' blocked without 'unsafe-inline'.");
async_test(t => {
var i = document.createElement("iframe");
i.src = "../support/echo-policy.py?policy=" + encodeURIComponent("script-src 'unsafe-inline'");
assert_csp_event_for_element(t, i);
navigate_to_javascript_onload(t, i);
i.src = "../support/echo-policy.py?policy=" + encodeURIComponent("script-src 'unsafe-inline'");
i.onload = _ => { i.src = "javascript:'Fail.'"; }
document.body.appendChild(i);
}, "<iframe src='...'> with 'unsafe-inline' navigated to 'javascript:' blocked in this document");
async_test(t => {
var i = document.createElement("iframe");
i.src = "../support/echo-policy.py?policy=" + encodeURIComponent("script-src 'none'");
assert_csp_event_for_element(t, i);
navigate_to_javascript_onload(t, i);
i.src = "../support/echo-policy.py?policy=" + encodeURIComponent("script-src 'none'");
i.onload = _ => { i.src = "javascript:'Fail.'"; }
document.body.appendChild(i);
}, "<iframe src='...'> without 'unsafe-inline' navigated to 'javascript:' blocked in this document.");
</script>

View file

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.</title>
<script src='/resources/testharness.js' nonce='dummy'></script>
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
<!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
</head>
<body>
<h1>Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.</h1>
<div id='log'></div>
<a id='javascriptUri' href='javascript:javascriptUriScriptRan = true;'></a>
<script nonce='dummy'>
var javascriptUriScriptRan = false;
async_test(function(t) {
window.addEventListener('securitypolicyviolation', t.step_func_done(function(e) {
assert_false(javascriptUriScriptRan);
assert_equals(e.effectiveDirective, 'script-src');
}));
document.getElementById('javascriptUri').click();
assert_false(javascriptUriScriptRan);
}, "Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.");
</script>
</body>
</html>

View file

@ -0,0 +1,5 @@
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: script-src 'strict-dynamic' 'nonce-dummy'