tor-browser

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

browser_manifest-src-override-default-src.js (3805B)


      1 /*
      2 * Description of the tests:
      3 * Tests check that default-src can be overridden by manifest-src.
      4 */
      5 /*globals Cu, is, ok*/
      6 "use strict";
      7 const { ManifestObtainer } = ChromeUtils.importESModule(
      8  "resource://gre/modules/ManifestObtainer.sys.mjs"
      9 );
     10 const path = "/tests/dom/security/test/csp/";
     11 const testFile = `${path}file_web_manifest.html`;
     12 const mixedContentFile = `${path}file_web_manifest_mixed_content.html`;
     13 const server = `${path}file_testserver.sjs`;
     14 const defaultURL = new URL(`https://example.org${server}`);
     15 const mixedURL = new URL(`http://mochi.test:8888${server}`);
     16 
     17 // Enable web manifest processing.
     18 Services.prefs.setBoolPref("dom.manifest.enabled", true);
     19 
     20 const tests = [
     21  // Check interaction with default-src and another origin,
     22  // CSP allows fetching from example.org, so manifest should load.
     23  {
     24    expected: `CSP manifest-src overrides default-src of elsewhere.com`,
     25    get tabURL() {
     26      const url = new URL(defaultURL);
     27      url.searchParams.append("file", testFile);
     28      url.searchParams.append("cors", "*");
     29      url.searchParams.append(
     30        "csp",
     31        "default-src http://elsewhere.com; manifest-src http://example.org"
     32      );
     33      return url.href;
     34    },
     35    run(manifest) {
     36      is(manifest.name, "loaded", this.expected);
     37    },
     38  },
     39  // Check interaction with default-src none,
     40  // CSP allows fetching manifest from example.org, so manifest should load.
     41  {
     42    expected: `CSP manifest-src overrides default-src`,
     43    get tabURL() {
     44      const url = new URL(mixedURL);
     45      url.searchParams.append("file", mixedContentFile);
     46      url.searchParams.append("cors", "http://test:80");
     47      url.searchParams.append(
     48        "csp",
     49        "default-src 'self'; manifest-src http://test:80"
     50      );
     51      return url.href;
     52    },
     53    run(manifest) {
     54      is(manifest.name, "loaded", this.expected);
     55    },
     56  },
     57 ];
     58 
     59 //jscs:disable
     60 add_task(async function () {
     61  //jscs:enable
     62  const testPromises = tests.map(test => {
     63    const tabOptions = {
     64      gBrowser,
     65      url: test.tabURL,
     66      skipAnimation: true,
     67    };
     68    return BrowserTestUtils.withNewTab(tabOptions, browser =>
     69      testObtainingManifest(browser, test)
     70    );
     71  });
     72  await Promise.all(testPromises);
     73 });
     74 
     75 async function testObtainingManifest(aBrowser, aTest) {
     76  const expectsBlocked = aTest.expected.includes("block");
     77  const observer = expectsBlocked ? createNetObserver(aTest) : null;
     78  // Expect an exception (from promise rejection) if there a content policy
     79  // that is violated.
     80  try {
     81    const manifest = await ManifestObtainer.browserObtainManifest(aBrowser);
     82    aTest.run(manifest);
     83  } catch (e) {
     84    const wasBlocked = e.message.includes(
     85      "NetworkError when attempting to fetch resource"
     86    );
     87    ok(
     88      wasBlocked,
     89      `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`
     90    );
     91    if (observer) {
     92      await observer.untilFinished;
     93    }
     94  }
     95 }
     96 
     97 // Helper object used to observe policy violations. It waits 1 seconds
     98 // for a response, and then times out causing its associated test to fail.
     99 function createNetObserver(test) {
    100  let finishedTest;
    101  let success = false;
    102  const finished = new Promise(resolver => {
    103    finishedTest = resolver;
    104  });
    105  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    106  const timeoutId = setTimeout(() => {
    107    if (!success) {
    108      test.run("This test timed out.");
    109      finishedTest();
    110    }
    111  }, 1000);
    112  var observer = {
    113    get untilFinished() {
    114      return finished;
    115    },
    116    observe(subject, topic) {
    117      SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
    118      test.run(topic);
    119      finishedTest();
    120      clearTimeout(timeoutId);
    121      success = true;
    122    },
    123  };
    124  SpecialPowers.addObserver(observer, "csp-on-violate-policy");
    125  return observer;
    126 }