test_sandbox.html (7499B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Tests for bugs 886164 and 671389</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 8 </head> 9 <body> 10 <p id="display"></p> 11 <div id="content"> 12 </div> 13 14 <script class="testbody" type="text/javascript"> 15 16 var testCases = [ 17 { 18 // Test 1: don't load image from non-same-origin; allow loading 19 // images from same-same origin 20 sandboxAttribute: "allow-same-origin", 21 csp: "default-src 'self'", 22 file: "file_sandbox_1.html", 23 results: { img1a_good: -1, img1_bad: -1 } 24 // fails if scripts execute 25 }, 26 { 27 // Test 2: don't load image from non-same-origin; allow loading 28 // images from same-same origin, even without allow-same-origin 29 // flag 30 sandboxAttribute: "", 31 csp: "default-src 'self'", 32 file: "file_sandbox_2.html", 33 results: { img2_bad: -1, img2a_good: -1 } 34 // fails if scripts execute 35 }, 36 { 37 // Test 3: disallow loading images from any host, even with 38 // allow-same-origin flag set 39 sandboxAttribute: "allow-same-origin", 40 csp: "default-src 'none'", 41 file: "file_sandbox_3.html", 42 results: { img3_bad: -1, img3a_bad: -1 }, 43 // fails if scripts execute 44 }, 45 { 46 // Test 4: disallow loading images from any host 47 sandboxAttribute: "", 48 csp: "default-src 'none'", 49 file: "file_sandbox_4.html", 50 results: { img4_bad: -1, img4a_bad: -1 } 51 // fails if scripts execute 52 }, 53 { 54 // Test 5: disallow loading images or scripts, allow inline scripts 55 sandboxAttribute: "allow-scripts", 56 csp: "default-src 'none'; script-src 'unsafe-inline';", 57 file: "file_sandbox_5.html", 58 results: { img5_bad: -1, img5a_bad: -1, script5_bad: -1, script5a_bad: -1 }, 59 nrOKmessages: 2 // sends 2 ok message 60 // fails if scripts execute 61 }, 62 { 63 // Test 6: disallow non-same-origin images, allow inline and same origin scripts 64 sandboxAttribute: "allow-same-origin allow-scripts", 65 csp: "default-src 'self' 'unsafe-inline';", 66 file: "file_sandbox_6.html", 67 results: { img6_bad: -1, script6_bad: -1 }, 68 nrOKmessages: 4 // sends 4 ok message 69 // fails if forms are not disallowed 70 }, 71 { 72 // Test 7: same as Test 1 73 csp: "default-src 'self'; sandbox allow-same-origin", 74 file: "file_sandbox_7.html", 75 results: { img7a_good: -1, img7_bad: -1 } 76 }, 77 { 78 // Test 8: same as Test 2 79 csp: "sandbox allow-same-origin; default-src 'self'", 80 file: "file_sandbox_8.html", 81 results: { img8_bad: -1, img8a_good: -1 } 82 }, 83 { 84 // Test 9: same as Test 3 85 csp: "default-src 'none'; sandbox allow-same-origin", 86 file: "file_sandbox_9.html", 87 results: { img9_bad: -1, img9a_bad: -1 } 88 }, 89 { 90 // Test 10: same as Test 4 91 csp: "default-src 'none'; sandbox allow-same-origin", 92 file: "file_sandbox_10.html", 93 results: { img10_bad: -1, img10a_bad: -1 } 94 }, 95 { 96 // Test 11: same as Test 5 97 csp: "default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts allow-same-origin", 98 file: "file_sandbox_11.html", 99 results: { img11_bad: -1, img11a_bad: -1, script11_bad: -1, script11a_bad: -1 }, 100 nrOKmessages: 2 // sends 2 ok message 101 }, 102 { 103 // Test 12: same as Test 6 104 csp: "sandbox allow-same-origin allow-scripts; default-src 'self' 'unsafe-inline';", 105 file: "file_sandbox_12.html", 106 results: { img12_bad: -1, script12_bad: -1 }, 107 nrOKmessages: 4 // sends 4 ok message 108 }, 109 { 110 // Test 13: same as Test 5 and Test 11, but: 111 // * using sandbox flag 'allow-scripts' in CSP and not as iframe attribute 112 // * not using allow-same-origin in CSP (so a new NullPrincipal is created). 113 csp: "default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts", 114 file: "file_sandbox_13.html", 115 results: { img13_bad: -1, img13a_bad: -1, script13_bad: -1, script13a_bad: -1 }, 116 nrOKmessages: 2 // sends 2 ok message 117 }, 118 ]; 119 120 // a postMessage handler that is used by sandboxed iframes without 121 // 'allow-same-origin' to communicate pass/fail back to this main page. 122 // it expects to be called with an object like: 123 // { ok: true/false, 124 // desc: <description of the test> which it then forwards to ok() } 125 window.addEventListener("message", receiveMessage); 126 127 function receiveMessage(event) { 128 ok_wrapper(event.data.ok, event.data.desc); 129 } 130 131 var completedTests = 0; 132 var passedTests = 0; 133 134 var totalTests = (function() { 135 var nrCSPloadTests = 0; 136 for(var i = 0; i < testCases.length; i++) { 137 nrCSPloadTests += Object.keys(testCases[i].results).length; 138 if (testCases[i].nrOKmessages) { 139 // + number of expected postMessages from iframe 140 nrCSPloadTests += testCases[i].nrOKmessages; 141 } 142 } 143 return nrCSPloadTests; 144 })(); 145 146 function ok_wrapper(result, desc) { 147 ok(result, desc); 148 149 completedTests++; 150 151 if (result) { 152 passedTests++; 153 } 154 155 if (completedTests === totalTests) { 156 window.examiner.remove(); 157 SimpleTest.finish(); 158 } 159 } 160 161 // Set the iframe src and sandbox attribute 162 function runTest(test) { 163 var iframe = document.createElement('iframe'); 164 165 document.getElementById('content').appendChild(iframe); 166 167 // set sandbox attribute 168 if (test.sandboxAttribute !== undefined) { 169 iframe.sandbox = test.sandboxAttribute; 170 } 171 172 // set query string 173 var src = 'file_testserver.sjs'; 174 // path where the files are 175 var path = '/tests/dom/security/test/csp/'; 176 177 src += '?file=' + escape(path+test.file); 178 179 if (test.csp !== undefined) { 180 src += '&csp=' + escape(test.csp); 181 } 182 183 iframe.src = src; 184 iframe.width = iframe.height = 10; 185 } 186 187 // Examiner related 188 189 // This is used to watch the blocked data bounce off CSP and allowed data 190 // get sent out to the wire. 191 function examiner() { 192 SpecialPowers.addObserver(this, "csp-on-violate-policy"); 193 SpecialPowers.addObserver(this, "specialpowers-http-notify-request"); 194 } 195 196 examiner.prototype = { 197 observe(subject, topic, data) { 198 var testpat = new RegExp("testid=([a-z0-9_]+)"); 199 200 //_good things better be allowed! 201 //_bad things better be stopped! 202 203 if (topic === "specialpowers-http-notify-request") { 204 //these things were allowed by CSP 205 var uri = data; 206 if (!testpat.test(uri)) return; 207 var testid = testpat.exec(uri)[1]; 208 209 if(/_good/.test(testid)) { 210 ok_wrapper(true, uri + " is allowed by csp"); 211 } else { 212 ok_wrapper(false, uri + " should not be allowed by csp"); 213 } 214 } 215 216 if(topic === "csp-on-violate-policy") { 217 //these were blocked... record that they were blocked 218 var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec"); 219 if (!testpat.test(asciiSpec)) return; 220 var testid = testpat.exec(asciiSpec)[1]; 221 if(/_bad/.test(testid)) { 222 ok_wrapper(true, asciiSpec + " was blocked by \"" + data + "\""); 223 } else { 224 ok_wrapper(false, asciiSpec + " should have been blocked by \"" + data + "\""); 225 } 226 } 227 }, 228 229 // must eventually call this to remove the listener, 230 // or mochitests might get borked. 231 remove() { 232 SpecialPowers.removeObserver(this, "csp-on-violate-policy"); 233 SpecialPowers.removeObserver(this, "specialpowers-http-notify-request"); 234 } 235 } 236 237 window.examiner = new examiner(); 238 239 SimpleTest.waitForExplicitFinish(); 240 241 (function() { // Run tests: 242 for(var i = 0; i < testCases.length; i++) { 243 runTest(testCases[i]); 244 } 245 })(); 246 247 </script> 248 </body> 249 </html>