file_upgrade_insecure_report_only_server.sjs (3869B)
1 // Custom *.sjs specifically for the needs of Bug 1832249 - Consider report-only flag when upgrading insecure requests 2 3 const { NetUtil } = ChromeUtils.importESModule( 4 "resource://gre/modules/NetUtil.sys.mjs" 5 ); 6 7 // small red image 8 const IMG_BYTES = atob( 9 "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + 10 "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" 11 ); 12 13 const POLICY_CSP = 14 "upgrade-insecure-requests; default-src https: 'unsafe-inline'"; 15 const POLICY_CSP_RO = 16 "default-src https: 'unsafe-inline'; upgrade-insecure-requests; report-uri https://example.com/tests/dom/security/test/csp/file_upgrade_insecure_report_only_server.sjs?report"; 17 18 function loadHTMLFromFile(path) { 19 // Load the HTML to return in the response from file. 20 // Since it's relative to the cwd of the test runner, we start there and 21 // append to get to the actual path of the file. 22 var testHTMLFile = Cc["@mozilla.org/file/directory_service;1"] 23 .getService(Ci.nsIProperties) 24 .get("CurWorkD", Ci.nsIFile); 25 var dirs = path.split("/"); 26 for (var i = 0; i < dirs.length; i++) { 27 testHTMLFile.append(dirs[i]); 28 } 29 var testHTMLFileStream = Cc[ 30 "@mozilla.org/network/file-input-stream;1" 31 ].createInstance(Ci.nsIFileInputStream); 32 testHTMLFileStream.init(testHTMLFile, -1, 0, 0); 33 var testHTML = NetUtil.readInputStreamToString( 34 testHTMLFileStream, 35 testHTMLFileStream.available() 36 ); 37 return testHTML; 38 } 39 40 function handleRequest(request, response) { 41 // avoid confusing cache behaviors 42 response.setHeader("Cache-Control", "no-cache", false); 43 44 // (1) Store the query that will report back whether the violation report was 45 // received 46 if (request.queryString.startsWith("queryresult-")) { 47 let route = request.queryString.substring("queryresult-".length); 48 response.processAsync(); 49 setObjectState(`queryResult-${route}`, response); 50 return; 51 } 52 53 // (2) We load a page using a report only CSP 54 if (request.queryString.endsWith("=true")) { 55 let route = request.queryString.split("=")[0]; 56 if (route === "enforce") { 57 response.setHeader("Content-Security-Policy", POLICY_CSP, false); 58 } 59 response.setHeader( 60 "Content-Security-Policy-Report-Only", 61 POLICY_CSP_RO + "-" + route, 62 false 63 ); 64 response.setHeader("Content-Type", "text/html", false); 65 response.write( 66 loadHTMLFromFile( 67 "tests/dom/security/test/csp/file_upgrade_insecure_report_only.html" 68 ) 69 ); 70 return; 71 } 72 73 // (3a) Return the image back to the client if http and refuse if https for 74 // report only image 75 if (request.queryString.startsWith("img-")) { 76 let route = request.queryString.substring("img-".length); 77 if ( 78 (request.scheme === "http" && route === "reportonly") || 79 (request.scheme === "https" && route === "enforce") 80 ) { 81 response.setHeader("Content-Type", "image/png"); 82 response.write(IMG_BYTES); 83 return; 84 } else { 85 response.setStatusLine(metadata.httpVersion, 404, "NO"); 86 response.write("Aww, 404, I wanted a peanut."); 87 return; 88 } 89 } 90 91 // (4) Once we receive the report send it to the client via the saved 92 // queryresult response object 93 if (request.queryString.startsWith("report-")) { 94 let route = request.queryString.substring("report-".length); 95 getObjectState(`queryResult-${route}`, function (queryResponse) { 96 if (!queryResponse) { 97 return; 98 } 99 queryResponse.setHeader("Content-Type", "application/json"); 100 queryResponse.write( 101 NetUtil.readInputStreamToString( 102 request.bodyInputStream, 103 request.bodyInputStream.available() 104 ) 105 ); 106 queryResponse.finish(); 107 }); 108 return; 109 } 110 111 // we should never get here, but just in case ... 112 response.setHeader("Content-Type", "text/plain"); 113 response.write("doh!"); 114 }