tor-browser

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

test_bug337744.js (3606B)


      1 /* verify that certain invalid URIs are not parsed by the resource
      2   protocol handler */
      3 
      4 "use strict";
      5 
      6 const specs = [
      7  "resource://res-test//",
      8  "resource://res-test/?foo=http:",
      9  "resource://res-test/?foo=" + encodeURIComponent("http://example.com/"),
     10  "resource://res-test/?foo=" + encodeURIComponent("x\\y"),
     11  "resource://res-test/..%2F",
     12  "resource://res-test/..%2f",
     13  "resource://res-test/..%2F..",
     14  "resource://res-test/..%2f..",
     15  "resource://res-test/../../",
     16  "resource://res-test/http://www.mozilla.org/",
     17  "resource://res-test/file:///",
     18 ];
     19 
     20 const error_specs = [
     21  "resource://res-test/..\\",
     22  "resource://res-test/..\\..\\",
     23  "resource://res-test/..%5C",
     24  "resource://res-test/..%5c",
     25 ];
     26 
     27 // Create some fake principal that has not enough
     28 // privileges to access any resource: uri.
     29 var uri = NetUtil.newURI("http://www.example.com");
     30 var principal = Services.scriptSecurityManager.createContentPrincipal(uri, {});
     31 
     32 function get_channel(spec) {
     33  var channel = NetUtil.newChannel({
     34    uri: NetUtil.newURI(spec),
     35    loadingPrincipal: principal,
     36    securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
     37    contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
     38  });
     39 
     40  Assert.throws(
     41    () => {
     42      channel.asyncOpen(null);
     43    },
     44    /NS_ERROR_DOM_BAD_URI/,
     45    `asyncOpen() of uri: ${spec} should throw`
     46  );
     47  Assert.throws(
     48    () => {
     49      channel.open();
     50    },
     51    /NS_ERROR_DOM_BAD_URI/,
     52    `Open() of uri: ${spec} should throw`
     53  );
     54 
     55  return channel;
     56 }
     57 
     58 function check_safe_resolution(spec, rootURI) {
     59  info(`Testing URL "${spec}"`);
     60 
     61  let channel = get_channel(spec);
     62 
     63  ok(
     64    channel.name.startsWith(rootURI),
     65    `URL resolved safely to ${channel.name}`
     66  );
     67  let startOfQuery = channel.name.indexOf("?");
     68  if (startOfQuery == -1) {
     69    ok(!/%2f/i.test(channel.name), `URL contains no escaped / characters`);
     70  } else {
     71    // Escaped slashes are allowed in the query or hash part of the URL
     72    ok(
     73      !channel.name.replace(/\?.*/, "").includes("%2f"),
     74      `URL contains no escaped slashes before the query ${channel.name}`
     75    );
     76  }
     77 }
     78 
     79 function check_resolution_error(spec) {
     80  Assert.throws(
     81    () => {
     82      get_channel(spec);
     83    },
     84    /NS_ERROR_MALFORMED_URI/,
     85    "Expected a malformed URI error"
     86  );
     87 }
     88 
     89 function run_test() {
     90  // resource:/// and resource://gre/ are resolved specially, so we need
     91  // to create a temporary resource package to test the standard logic
     92  // with.
     93 
     94  let resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(
     95    Ci.nsIResProtocolHandler
     96  );
     97  let rootFile = Services.dirsvc.get("GreD", Ci.nsIFile);
     98  let rootURI = Services.io.newFileURI(rootFile);
     99 
    100  rootFile.append("directory-that-does-not-exist");
    101  let inexistentURI = Services.io.newFileURI(rootFile);
    102 
    103  resProto.setSubstitution("res-test", rootURI);
    104  resProto.setSubstitution("res-inexistent", inexistentURI);
    105  registerCleanupFunction(() => {
    106    resProto.setSubstitution("res-test", null);
    107    resProto.setSubstitution("res-inexistent", null);
    108  });
    109 
    110  let baseRoot = resProto.resolveURI(Services.io.newURI("resource:///"));
    111  let greRoot = resProto.resolveURI(Services.io.newURI("resource://gre/"));
    112 
    113  for (let spec of specs) {
    114    check_safe_resolution(spec, rootURI.spec);
    115    check_safe_resolution(
    116      spec.replace("res-test", "res-inexistent"),
    117      inexistentURI.spec
    118    );
    119    check_safe_resolution(spec.replace("res-test", ""), baseRoot);
    120    check_safe_resolution(spec.replace("res-test", "gre"), greRoot);
    121  }
    122 
    123  for (let spec of error_specs) {
    124    check_resolution_error(spec);
    125  }
    126 }