summaryrefslogtreecommitdiffstats
path: root/dom/security/test/csp/test_iframe_sandbox.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/security/test/csp/test_iframe_sandbox.html')
-rw-r--r--dom/security/test/csp/test_iframe_sandbox.html240
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>