<!DOCTYPE HTML> <html> <head> <title>Bug 1031530 and Bug 1139667 - Test mapping of XMLHttpRequest and fetch() to connect-src</title> <!-- Including SimpleTest.js so we can use waitForExplicitFinish !--> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <p id="display"></p> <div id="content" style="visibility: hidden"> <iframe style="width:100%;" id="testframe"></iframe> </div> <script class="testbody" type="text/javascript"> /* * Description of the test: * We load a page with a given CSP and verify that XMLHttpRequests and fetches are correctly * evaluated through the "connect-src" directive. All XMLHttpRequests are served * using http://mochi.test:8888, which allows the requests to succeed for the first * two policies and to fail for the last policy. Please note that we have to add * 'unsafe-inline' so we can run the JS test code in file_connect-src.html. */ SimpleTest.waitForExplicitFinish(); var tests = [ { file: "file_connect-src.html", result : "allowed", policy : "default-src 'none' script-src 'unsafe-inline'; connect-src http://mochi.test:8888" }, { file: "file_connect-src.html", result : "allowed", policy : "default-src 'none'; script-src 'unsafe-inline'; connect-src *" }, { file: "file_connect-src.html", result : "blocked", policy : "default-src 'none'; script-src 'unsafe-inline'; connect-src http://www.example.com" }, { file: "file_connect-src-fetch.html", result : "allowed", policy : "default-src 'none' script-src 'unsafe-inline'; connect-src http://mochi.test:8888" }, { file: "file_connect-src-fetch.html", result : "allowed", policy : "default-src 'none'; script-src 'unsafe-inline'; connect-src *" }, { file: "file_connect-src-fetch.html", result : "blocked", policy : "default-src 'none'; script-src 'unsafe-inline'; connect-src http://www.example.com" } ]; // initializing to -1 so we start at index 0 when we start the test var counter = -1; function checkResult(aResult) { is(aResult, tests[counter].result, "should be " + tests[counter].result + " in test " + counter + "!"); loadNextTest(); } // We use the examiner to identify requests that hit the wire and requests // that are blocked by CSP and bubble up the result to the including iframe // document (parent). function examiner() { SpecialPowers.addObserver(this, "csp-on-violate-policy", false); SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false); } examiner.prototype = { observe: function(subject, topic, data) { if (topic === "specialpowers-http-notify-request") { // making sure we do not bubble a result for something other // then the request in question. if (!data.includes("file_testserver.sjs?foo")) { return; } checkResult("allowed"); } if (topic === "csp-on-violate-policy") { // making sure we do not bubble a result for something other // then the request in question. var asciiSpec = SpecialPowers.getPrivilegedProps( SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec"); if (!asciiSpec.includes("file_testserver.sjs?foo")) { return; } checkResult("blocked"); } }, remove: function() { SpecialPowers.removeObserver(this, "csp-on-violate-policy"); SpecialPowers.removeObserver(this, "specialpowers-http-notify-request"); } } window.ConnectSrcExaminer = new examiner(); function loadNextTest() { counter++; if (counter == tests.length) { window.ConnectSrcExaminer.remove(); SimpleTest.finish(); return; } var src = "file_testserver.sjs"; // append the file that should be served src += "?file=" + escape("tests/dom/security/test/csp/" + tests[counter].file); // append the CSP that should be used to serve the file src += "&csp=" + escape(tests[counter].policy); document.getElementById("testframe").src = src; } // start running the tests loadNextTest(); </script> </body> </html>