tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }