diff options
Diffstat (limited to 'dom/security/test/csp/test_iframe_sandbox.html')
-rw-r--r-- | dom/security/test/csp/test_iframe_sandbox.html | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/dom/security/test/csp/test_iframe_sandbox.html b/dom/security/test/csp/test_iframe_sandbox.html new file mode 100644 index 0000000000..cd7417bc8b --- /dev/null +++ b/dom/security/test/csp/test_iframe_sandbox.html @@ -0,0 +1,240 @@ +<!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 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.includes(a)) + 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 = 'http://mochi.test:8888/tests/dom/security/test/csp/file_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/security/test/csp/file_iframe_sandbox_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); + + 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> |