tor-browser

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

test_loadinfo_redirectchain.html (11140B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Bug 1194052 - Append Principal to RedirectChain within LoadInfo before the channel is succesfully openend</title>
      5  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
      8 </head>
      9 <body>
     10 <iframe style="width:100%;" id="testframe"></iframe>
     11 
     12 <script class="testbody" type="text/javascript">
     13 
     14 /*
     15 * We perform the following tests on the redirectchain of the loadinfo:
     16 *  (1) checkLoadInfoWithoutRedirects:
     17 *      checks the length of the redirectchain and tries to pop an element
     18 *      which should result in an exception and not a crash.
     19 *  (2) checkLoadInfoWithTwoRedirects:
     20 *      perform two redirects and confirm that both redirect chains
     21 *      contain the redirected URIs.
     22 *  (3) checkLoadInfoWithInternalRedirects:
     23 *      perform two redirects including CSPs upgrade-insecure-requests
     24 *      so that the redirectchain which includes internal redirects differs.
     25 *  (4) checkLoadInfoWithInternalRedirectsAndFallback
     26 *      perform two redirects including CSPs upgrade-insecure-requests
     27 *      including a 404 repsonse and hence a fallback.
     28 *  (5) checkHTTPURITruncation
     29 *      perform a redirect to a URI with an HTTP scheme to check that unwanted
     30 *      URI components are removed before being added to the redirectchain.
     31 *  (6) checkHTTPSURITruncation
     32 *      perform a redirect to a URI with an HTTPS scheme to check that unwanted
     33 *      URI components are removed before being added to the redirectchain.
     34 */
     35 
     36 SimpleTest.waitForExplicitFinish();
     37 
     38 // ************** HELPERS ***************
     39 
     40 function compareChains(aLoadInfo, aExpectedRedirectChain, aExpectedRedirectChainIncludingInternalRedirects) {
     41  var redirectChain = aLoadInfo.redirectChain;
     42  var redirectChainIncludingInternalRedirects = aLoadInfo.redirectChainIncludingInternalRedirects;
     43 
     44  is(redirectChain.length,
     45    aExpectedRedirectChain.length,
     46    "confirming length of redirectChain is " + aExpectedRedirectChain.length);
     47 
     48  is(redirectChainIncludingInternalRedirects.length,
     49    aExpectedRedirectChainIncludingInternalRedirects.length,
     50    "confirming length of redirectChainIncludingInternalRedirects is " +
     51    aExpectedRedirectChainIncludingInternalRedirects.length);
     52 }
     53 
     54 function compareTruncatedChains(redirectChain, aExpectedRedirectChain) {
     55  is(redirectChain.length,
     56    aExpectedRedirectChain.length,
     57    "confirming length of redirectChain is " + aExpectedRedirectChain.length);
     58 
     59  for (var i = 0; i < redirectChain.length; i++) {
     60    is(redirectChain[i],
     61      aExpectedRedirectChain[i],
     62      "redirect chain should match expected chain");
     63  }
     64 }
     65 
     66 
     67 // *************** TEST 1 ***************
     68 
     69 function checkLoadInfoWithoutRedirects() {
     70  var myXHR = new XMLHttpRequest();
     71  myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-0");
     72 
     73  myXHR.onload = function() {
     74    var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
     75    var redirectChain = loadinfo.redirectChain;
     76    var redirectChainIncludingInternalRedirects = loadinfo.redirectChainIncludingInternalRedirects;
     77 
     78    is(redirectChain.length, 0, "no redirect, length should be 0");
     79    is(redirectChainIncludingInternalRedirects.length, 0, "no redirect, length should be 0");
     80    is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded");
     81 
     82    // try to pop an element from redirectChain
     83    try {
     84      loadinfo.popRedirectedPrincipal(false);
     85      ok(false, "should not be possible to pop from redirectChain");
     86    }
     87    catch(e) {
     88      ok(true, "popping element from empty redirectChain should throw");
     89    }
     90 
     91    // try to pop an element from redirectChainIncludingInternalRedirects
     92    try {
     93      loadinfo.popRedirectedPrincipal(true);
     94      ok(false, "should not be possible to pop from redirectChainIncludingInternalRedirects");
     95    }
     96    catch(e) {
     97      ok(true, "popping element from empty redirectChainIncludingInternalRedirects should throw");
     98    }
     99    // move on to the next test
    100    checkLoadInfoWithTwoRedirects();
    101  }
    102  myXHR.onerror = function() {
    103    ok(false, "xhr problem within checkLoadInfoWithoutRedirect()");
    104  }
    105  myXHR.send();
    106 }
    107 
    108 // *************** TEST 2 ***************
    109 
    110 function checkLoadInfoWithTwoRedirects() {
    111  var myXHR = new XMLHttpRequest();
    112  myXHR.open("GET", "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-2");
    113 
    114  const EXPECTED_REDIRECT_CHAIN = [
    115    "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs",
    116    "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs"
    117  ];
    118 
    119  const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = EXPECTED_REDIRECT_CHAIN;
    120 
    121  // Referrer header will not change when redirect
    122  const EXPECTED_REFERRER =
    123    "http://mochi.test:8888/tests/netwerk/test/mochitests/test_loadinfo_redirectchain.html";
    124  const isAndroid = !!navigator.userAgent.includes("Android");
    125  const EXPECTED_REMOTE_IP = isAndroid ? "10.0.2.2" : "127.0.0.1";
    126 
    127  myXHR.onload = function() {
    128    is(myXHR.responseText, "checking redirectchain", "sanity check to make sure redirects succeeded");
    129 
    130    var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
    131 
    132    compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
    133 
    134    for (var i = 0; i < loadinfo.redirectChain.length; i++) {
    135      is(loadinfo.redirectChain[i].referrerURI.spec, EXPECTED_REFERRER, "referrer should match");
    136      is(loadinfo.redirectChain[i].remoteAddress, EXPECTED_REMOTE_IP, "remote address should match");
    137    }
    138 
    139    // move on to the next test
    140    checkLoadInfoWithInternalRedirects();
    141  }
    142  myXHR.onerror = function() {
    143    ok(false, "xhr problem within checkLoadInfoWithTwoRedirects()");
    144  }
    145  myXHR.send();
    146 }
    147 
    148 // *************** TEST 3 ***************
    149 
    150 function confirmCheckLoadInfoWithInternalRedirects(event) {
    151  const EXPECTED_REDIRECT_CHAIN = [
    152    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
    153    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1"
    154  ];
    155 
    156  const EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [
    157    "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
    158    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-2",
    159    "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1",
    160    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-1",
    161    "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-https-0",
    162  ];
    163 
    164  var loadinfo = JSON.parse(event.data.loadinfo);
    165  compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
    166 
    167  // remove the postMessage listener and move on to the next test
    168  window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirects);
    169  checkLoadInfoWithInternalRedirectsAndFallback();
    170 }
    171 
    172 function checkLoadInfoWithInternalRedirects() {
    173  // load the XHR request into an iframe so we can apply a CSP to the iframe
    174  // a postMessage returns the result back to the main page.
    175  window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirects);
    176  document.getElementById("testframe").src =
    177    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2";
    178 }
    179 
    180 // *************** TEST 4 ***************
    181 
    182 function confirmCheckLoadInfoWithInternalRedirectsAndFallback(event) {
    183  var EXPECTED_REDIRECT_CHAIN = [
    184    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
    185  ];
    186 
    187  var EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS = [
    188    "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
    189    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-2",
    190    "http://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-err-1",
    191  ];
    192 
    193  var loadinfo = JSON.parse(event.data.loadinfo);
    194  compareChains(loadinfo, EXPECTED_REDIRECT_CHAIN, EXPECTED_REDIRECT_CHAIN_INCLUDING_INTERNAL_REDIRECTS);
    195 
    196  // remove the postMessage listener and finish test
    197  window.removeEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback);
    198  checkHTTPURITruncation();
    199 }
    200 
    201 function checkLoadInfoWithInternalRedirectsAndFallback() {
    202  // load the XHR request into an iframe so we can apply a CSP to the iframe
    203  // a postMessage returns the result back to the main page.
    204  window.addEventListener("message", confirmCheckLoadInfoWithInternalRedirectsAndFallback);
    205  document.getElementById("testframe").src =
    206    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-err-2";
    207 }
    208 
    209 // *************** TEST 5 ***************
    210 
    211 function checkHTTPURITruncation() {
    212  var myXHR = new XMLHttpRequest();
    213  myXHR.open("GET", "http://root:toor@mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?redir-1#baz");
    214 
    215  const EXPECTED_REDIRECT_CHAIN = [
    216    "http://mochi.test:8888/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-1
    217  ];
    218 
    219  var loadinfo = SpecialPowers.wrap(myXHR).channel.loadInfo;
    220 
    221  myXHR.onload = function() {
    222    var redirectChain = [];
    223 
    224    for (var i = 0; i < loadinfo.redirectChain.length; i++) {
    225      redirectChain[i] = loadinfo.redirectChain[i].principal.asciiSpec;
    226    }
    227 
    228    compareTruncatedChains(redirectChain, EXPECTED_REDIRECT_CHAIN);
    229 
    230    // move on to the next test
    231    checkHTTPSURITruncation();
    232  }
    233  myXHR.onerror = function(e) {
    234    ok(false, "xhr problem within checkHTTPURITruncation()" + e);
    235  }
    236  myXHR.send();
    237 }
    238 
    239 // *************** TEST 6 ***************
    240 
    241 function confirmCheckHTTPSURITruncation(event) {
    242  const EXPECTED_REDIRECT_CHAIN = [
    243    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-2
    244    "https://example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs", // redir-https-1
    245  ];
    246 
    247  var loadinfo = JSON.parse(event.data.loadinfo);
    248  compareTruncatedChains(loadinfo.redirectChain, EXPECTED_REDIRECT_CHAIN);
    249 
    250  // remove the postMessage listener and move on to the next test
    251  window.removeEventListener("message", confirmCheckHTTPSURITruncation);
    252  SimpleTest.finish();
    253 }
    254 
    255 function checkHTTPSURITruncation() {
    256  // load the XHR request into an iframe so we can apply a CSP to the iframe
    257  // a postMessage returns the result back to the main page.
    258  window.addEventListener("message", confirmCheckHTTPSURITruncation);
    259  document.getElementById("testframe").src =
    260    "https://root:toor@example.com/tests/netwerk/test/mochitests/file_loadinfo_redirectchain.sjs?iframe-redir-https-2#baz";
    261 }
    262 
    263 // *************** START TESTS ***************
    264 
    265 checkLoadInfoWithoutRedirects();
    266 
    267 </script>
    268 </body>
    269 </html>