зеркало из https://github.com/mozilla/gecko-dev.git
Bug 671389 - Part 3: Tests for CSP sandbox directive r=grobinson,smaug
This commit is contained in:
Родитель
88942a6436
Коммит
2ab90798ef
|
@ -30,16 +30,25 @@ function handleRequest(request, response)
|
|||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
var csp = unescape(query['csp']);
|
||||
var file = unescape(query['file']);
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// Deliver the CSP policy encoded in the URI
|
||||
response.setHeader("Content-Security-Policy", csp, false);
|
||||
if (query['csp']) {
|
||||
var csp = unescape(query['csp']);
|
||||
// Deliver the CSP policy encoded in the URI
|
||||
response.setHeader("Content-Security-Policy", csp, false);
|
||||
}
|
||||
|
||||
// Send HTML to test allowed/blocked behaviors
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(loadHTMLFromFile(file));
|
||||
if (query['cspRO']) {
|
||||
var cspRO = unescape(query['cspRO']);
|
||||
// Deliver the CSP report-only policy encoded in the URI
|
||||
response.setHeader("Content-Security-Policy-Report-Only", cspRO, false);
|
||||
}
|
||||
|
||||
if (query['file']) {
|
||||
var file = unescape(query['file']);
|
||||
// Send HTML to test allowed/blocked behaviors
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.write(loadHTMLFromFile(file));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head> <meta charset="utf-8"> </head>
|
||||
<script type="text/javascript">
|
||||
function ok(result, desc) {
|
||||
window.parent.postMessage({ok: result, desc: desc}, "*");
|
||||
}
|
||||
function doStuff() {
|
||||
var beforePrincipal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
document.open();
|
||||
document.write("rewritten sandboxed document");
|
||||
document.close();
|
||||
var afterPrincipal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
ok(beforePrincipal.equals(afterPrincipal),
|
||||
"document.write() does not change underlying principal");
|
||||
}
|
||||
</script>
|
||||
<body onLoad='doStuff();'>
|
||||
sandboxed with allow-scripts
|
||||
</body>
|
||||
</html>
|
|
@ -105,6 +105,8 @@ support-files =
|
|||
file_worker_redirect.sjs
|
||||
file_csp_referrerdirective.html
|
||||
referrerdirective.sjs
|
||||
test_iframe_sandbox_csp_top_1.html^headers^
|
||||
file_iframe_sandbox_csp_document_write.html
|
||||
|
||||
[test_base-uri.html]
|
||||
[test_connect-src.html]
|
||||
|
@ -130,6 +132,8 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'and
|
|||
[test_nonce_source.html]
|
||||
[test_CSP_bug941404.html]
|
||||
[test_form-action.html]
|
||||
[test_iframe_sandbox_csp.html]
|
||||
[test_iframe_sandbox_csp_top_1.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observers are not available in child processes
|
||||
[test_hash_source.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=671389
|
||||
Bug 671389 - Implement CSP sandbox directive
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests for Bug 671389</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Check if two sandbox flags are the same, ignoring case-sensitivity.
|
||||
// getSandboxFlags returns a list of sandbox flags (if any) or
|
||||
// null if the flag is not set.
|
||||
// This function checks if two flags are the same, i.e., they're
|
||||
// either not set or have the same flags.
|
||||
function eqFlags(a, b) {
|
||||
if (a === null && b === null) { return true; }
|
||||
if (a === null || b === null) { return false; }
|
||||
if (a.length !== b.length) { return false; }
|
||||
var a_sorted = a.map(function(e) { return e.toLowerCase(); }).sort();
|
||||
var b_sorted = b.map(function(e) { return e.toLowerCase(); }).sort();
|
||||
for (var i in a_sorted) {
|
||||
if (a_sorted[i] !== b_sorted[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the sandbox flags of document doc.
|
||||
// If the flag is not set sandboxFlagsAsString returns null,
|
||||
// this function also returns null.
|
||||
// If the flag is set it may have some flags; in this case
|
||||
// this function returns the (potentially empty) list of flags.
|
||||
function getSandboxFlags(doc) {
|
||||
var flags = doc.sandboxFlagsAsString;
|
||||
if (flags === null) { return null; }
|
||||
return flags? flags.split(" "):[];
|
||||
}
|
||||
|
||||
// Constructor for a CSP sandbox flags test. The constructor
|
||||
// expectes a description 'desc' and set of options 'opts':
|
||||
// - sandboxAttribute: [null] or string corresponding to the iframe sandbox attributes
|
||||
// - csp: [null] or string corresponding to the CSP sandbox flags
|
||||
// - cspReportOnly: [null] or string corresponding to the CSP report-only sandbox flags
|
||||
// - file: [null] or string corresponding to file the server should serve
|
||||
// Above, we use [brackets] to denote default values.
|
||||
function CSPFlagsTest(desc, opts) {
|
||||
function ifundef(x, v) {
|
||||
return (x !== undefined) ? x : v;
|
||||
}
|
||||
|
||||
function intersect(as, bs) { // Intersect two csp attributes:
|
||||
as = as === null ? null
|
||||
: as.split(' ').filter(function(x) { return !!x; });
|
||||
bs = bs === null ? null
|
||||
: bs.split(' ').filter(function(x) { return !!x; });
|
||||
|
||||
if (as === null) { return bs; }
|
||||
if (bs === null) { return as; }
|
||||
|
||||
var cs = [];
|
||||
as.forEach(function(a) {
|
||||
if (a && bs.indexOf(a) != -1)
|
||||
cs.push(a);
|
||||
});
|
||||
return cs;
|
||||
}
|
||||
|
||||
this.desc = desc || "Untitled test";
|
||||
this.attr = ifundef(opts.sandboxAttribute, null);
|
||||
this.csp = ifundef(opts.csp, null);
|
||||
this.cspRO = ifundef(opts.cspReportOnly, null);
|
||||
this.file = ifundef(opts.file, null);
|
||||
this.expected = intersect(this.attr, this.csp);
|
||||
}
|
||||
|
||||
// Return function that checks that the actual flags are the same as the
|
||||
// expected flags
|
||||
CSPFlagsTest.prototype.checkFlags = function(iframe) {
|
||||
var this_ = this;
|
||||
return function() {
|
||||
try {
|
||||
var actual = getSandboxFlags(SpecialPowers.wrap(iframe).contentDocument);
|
||||
ok(eqFlags(actual, this_.expected),
|
||||
this_.desc, 'expected: "' + this_.expected + '", got: "' + actual + '"');
|
||||
} catch (e) {
|
||||
ok(false, this_.desc, 'expected: "' + this_.expected + '", failed with: "' + e + '"');
|
||||
}
|
||||
runNextTest();
|
||||
};
|
||||
};
|
||||
|
||||
// Set the iframe src and sandbox attribute
|
||||
CSPFlagsTest.prototype.runTest = function () {
|
||||
var iframe = document.createElement('iframe');
|
||||
document.getElementById("content").appendChild(iframe);
|
||||
iframe.onload = this.checkFlags(iframe);
|
||||
|
||||
// set sandbox attribute
|
||||
if (this.attr === null) {
|
||||
iframe.removeAttribute('sandbox');
|
||||
} else {
|
||||
iframe.sandbox = this.attr;
|
||||
}
|
||||
|
||||
// set query string
|
||||
var src = 'file_csp_testserver.sjs';
|
||||
|
||||
var delim = '?';
|
||||
|
||||
if (this.csp !== null) {
|
||||
src += delim + 'csp=' + escape('sandbox ' + this.csp);
|
||||
delim = '&';
|
||||
}
|
||||
|
||||
if (this.cspRO !== null) {
|
||||
src += delim + 'cspRO=' + escape('sandbox ' + this.cspRO);
|
||||
delim = '&';
|
||||
}
|
||||
|
||||
if (this.file !== null) {
|
||||
src += delim + 'file=' + escape(this.file);
|
||||
delim = '&';
|
||||
}
|
||||
|
||||
iframe.src = src;
|
||||
iframe.width = iframe.height = 10;
|
||||
|
||||
}
|
||||
|
||||
testCases = [
|
||||
{
|
||||
desc: "Test 1: Header should not override attribute",
|
||||
sandboxAttribute: "",
|
||||
csp: "allow-forms aLLOw-POinter-lock alLOW-popups aLLOW-SAME-ORIGin ALLOW-SCRIPTS allow-top-navigation"
|
||||
},
|
||||
{
|
||||
desc: "Test 2: Attribute should not override header",
|
||||
sandboxAttribute: "sandbox allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation",
|
||||
csp: ""
|
||||
},
|
||||
{
|
||||
desc: "Test 3: Header and attribute intersect",
|
||||
sandboxAttribute: "allow-same-origin allow-scripts",
|
||||
csp: "allow-forms allow-same-origin allow-scripts"
|
||||
},
|
||||
{
|
||||
desc: "Test 4: CSP sandbox sets the right flags (pt 1)",
|
||||
csp: "alLOW-FORms ALLOW-pointer-lock allow-popups allow-same-origin allow-scripts ALLOW-TOP-NAVIGation"
|
||||
},
|
||||
{
|
||||
desc: "Test 5: CSP sandbox sets the right flags (pt 2)",
|
||||
csp: "allow-same-origin allow-TOP-navigation"
|
||||
},
|
||||
{
|
||||
desc: "Test 6: CSP sandbox sets the right flags (pt 3)",
|
||||
csp: "allow-FORMS ALLOW-scripts"
|
||||
},
|
||||
{
|
||||
desc: "Test 7: CSP sandbox sets the right flags (pt 4)",
|
||||
csp: ""
|
||||
},
|
||||
{
|
||||
desc: "Test 8: CSP sandbox sets the right flags (pt 5)",
|
||||
csp: null
|
||||
},
|
||||
{
|
||||
desc: "Test 9: Read-only header should not override attribute",
|
||||
sandboxAttribute: "",
|
||||
cspReportOnly: "allow-forms ALLOW-pointer-lock allow-POPUPS allow-same-origin ALLOW-scripts allow-top-NAVIGATION"
|
||||
},
|
||||
{
|
||||
desc: "Test 10: Read-only header should not override CSP header",
|
||||
csp: "allow-forms allow-scripts",
|
||||
cspReportOnly: "allow-forms aLlOw-PoInTeR-lOcK aLLow-pOPupS aLLoW-SaME-oRIgIN alLow-scripts allow-tOp-navigation"
|
||||
},
|
||||
{
|
||||
desc: "Test 11: Read-only header should not override attribute or CSP header",
|
||||
sandboxAttribute: "allow-same-origin allow-scripts",
|
||||
csp: "allow-forms allow-same-origin allow-scripts",
|
||||
cspReportOnly: "allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation"
|
||||
},
|
||||
{
|
||||
desc: "Test 12: CSP sandbox not affected by document.write()",
|
||||
csp: "allow-scripts",
|
||||
file: 'tests/dom/base/test/csp/file_iframe_sandbox_csp_document_write.html'
|
||||
},
|
||||
].map(function(t) { return (new CSPFlagsTest(t.desc,t)); });
|
||||
|
||||
|
||||
var testCaseIndex = 0;
|
||||
|
||||
// Track ok messages from iframes
|
||||
var childMessages = 0;
|
||||
var totalChildMessages = 1;
|
||||
|
||||
|
||||
// Check to see if we ran all the tests and received all messges
|
||||
// from child iframes. If so, finish.
|
||||
function tryFinish() {
|
||||
if (testCaseIndex === testCases.length && childMessages === totalChildMessages){
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
|
||||
tryFinish();
|
||||
|
||||
if (testCaseIndex < testCases.length) {
|
||||
testCases[testCaseIndex].runTest();
|
||||
testCaseIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
function receiveMessage(event) {
|
||||
ok(event.data.ok, event.data.desc);
|
||||
childMessages++;
|
||||
tryFinish();
|
||||
}
|
||||
|
||||
window.addEventListener("message", receiveMessage, false);
|
||||
|
||||
addLoadEvent(runNextTest);
|
||||
</script>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671389">Mozilla Bug 671389</a> - Implement CSP sandbox directive
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=671389
|
||||
Bug 671389 - Implement CSP sandbox directive
|
||||
|
||||
Tests CSP sandbox attribute on top-level page.
|
||||
|
||||
Minimal flags: allow-same-origin allow-scripts:
|
||||
Since we need to load the SimpleTest files, we have to set the
|
||||
allow-same-origin flag. Additionally, we set the allow-scripts flag
|
||||
since we need JS to check the flags.
|
||||
|
||||
Though not necessary, for this test we also set the allow-forms flag.
|
||||
We may later wish to extend the testing suite with sandbox_csp_top_*
|
||||
tests that set different permutations of the flags.
|
||||
|
||||
CSP header: Content-Security-Policy: sandbox allow-forms allow-scripts allow-same-origin
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Tests for Bug 671389</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Check if two sandbox flags are the same.
|
||||
// getSandboxFlags returns a list of sandbox flags (if any) or
|
||||
// null if the flag is not set.
|
||||
// This function checks if two flags are the same, i.e., they're
|
||||
// either not set or have the same flags.
|
||||
function eqFlags(a, b) {
|
||||
if (a === null && b === null) { return true; }
|
||||
if (a === null || b === null) { return false; }
|
||||
if (a.length !== b.length) { return false; }
|
||||
var a_sorted = a.sort();
|
||||
var b_sorted = b.sort();
|
||||
for (var i in a_sorted) {
|
||||
if (a_sorted[i] !== b_sorted[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the sandbox flags of document doc.
|
||||
// If the flag is not set sandboxFlagsAsString returns null,
|
||||
// this function also returns null.
|
||||
// If the flag is set it may have some flags; in this case
|
||||
// this function returns the (potentially empty) list of flags.
|
||||
function getSandboxFlags(doc) {
|
||||
var flags = doc.sandboxFlagsAsString;
|
||||
if (flags === null) { return null; }
|
||||
return flags? flags.split(" "):[];
|
||||
}
|
||||
|
||||
function checkFlags(expected) {
|
||||
try {
|
||||
var flags = getSandboxFlags(SpecialPowers.wrap(document));
|
||||
ok(eqFlags(flags, expected), name + ' expected: "' + expected + '", got: "' + flags + '"');
|
||||
} catch (e) {
|
||||
ok(false, name + ' expected "' + expected + ', but failed with ' + e);
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<body onLoad='checkFlags(["allow-forms", "allow-scripts", "allow-same-origin"]);'>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671389">Mozilla Bug 671389</a> - Implement CSP sandbox directive
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
I am a top-level page sandboxed with "allow-scripts allow-forms
|
||||
allow-same-origin".
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: sAnDbOx aLLow-FOrms aLlOw-ScRiPtS ALLOW-same-origin
|
Загрузка…
Ссылка в новой задаче