tor-browser

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

window-location-and-location-href-cross-realm-set.html (6213B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Cross-realm [[Set]] to window.location and location.href throws an error of correct realm</title>
      4 <link rel="help" href="https://html.spec.whatwg.org/multipage/#window">
      5 <link rel="help" href="https://webidl.spec.whatwg.org/#Unforgeable">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="/common/get-host-info.sub.js"></script>
      9 <body>
     10 <script>
     11 const URL_SAME_ORIGIN = get_host_info().ORIGINAL_HOST;
     12 const URL_CROSS_ORIGIN = get_host_info().HTTP_REMOTE_ORIGIN;
     13 const URL_VALID = "#foo";
     14 const URL_INVALID = "http://#";
     15 
     16 const { get: locationGet, set: locationSet } = Object.getOwnPropertyDescriptor(window, "location");
     17 const { get: hrefGet, set: hrefSet } = Object.getOwnPropertyDescriptor(location, "href");
     18 
     19 
     20 promise_test(async t => {
     21    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     22    assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow).location; });
     23    assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.get(sameOriginWindow, "location", {}); });
     24    assert_throws_js(TypeError, () => { locationGet.call({}); });
     25 }, "Same-origin window.location getter throws TypeError in holder's realm on invalid |this| value");
     26 
     27 promise_test(async t => {
     28    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     29    assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow.location).href; });
     30    assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.get(sameOriginWindow.location, "href", {}); });
     31    assert_throws_js(TypeError, () => { hrefGet(); });
     32 }, "Same-origin location.href getter throws TypeError in holder's realm on invalid |this| value");
     33 
     34 promise_test(async t => {
     35    const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
     36    assert_throws_dom("SECURITY_ERR", () => { crossOriginWindow.location.href; });
     37    assert_throws_dom("SECURITY_ERR", () => { hrefGet.call(crossOriginWindow.location); });
     38    assert_equals(Object.getOwnPropertyDescriptor(crossOriginWindow.location, "href").get, undefined);
     39 }, "Cross-origin location.href getter throws SecurityError in lexical realm");
     40 
     41 
     42 promise_test(async t => {
     43    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     44    assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow).location = URL_VALID; });
     45    assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.set(sameOriginWindow, "location", URL_VALID, {}); });
     46    assert_throws_js(TypeError, () => { locationSet.call(() => {}, URL_VALID); });
     47 }, "Same-origin window.location setter throws TypeError in holder's realm on invalid |this| value");
     48 
     49 promise_test(async t => {
     50    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     51    assert_throws_js(sameOriginWindow.TypeError, () => { Object.create(sameOriginWindow.location).href = URL_VALID; });
     52    assert_throws_js(sameOriginWindow.TypeError, () => { Reflect.set(sameOriginWindow.location, "href", URL_VALID, {}); });
     53    assert_throws_js(TypeError, () => { hrefSet.call(undefined, URL_VALID); });
     54 }, "Same-origin location.href setter throws TypeError in holder's realm on invalid |this| value");
     55 
     56 promise_test(async t => {
     57    const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
     58    assert_throws_js(TypeError, () => { Object.create(crossOriginWindow).location = URL_VALID; });
     59    assert_throws_js(TypeError, () => { Reflect.set(crossOriginWindow, "location", URL_VALID, {}); });
     60    assert_throws_js(TypeError, () => { locationSet.call([], URL_VALID); });
     61 }, "Cross-origin window.location setter throws TypeError in lexical realm on invalid |this| value");
     62 
     63 promise_test(async t => {
     64    const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
     65    assert_throws_js(TypeError, () => { Object.create(crossOriginWindow.location).href = URL_VALID; });
     66    assert_throws_js(TypeError, () => { Reflect.set(crossOriginWindow.location, "href", URL_VALID, {}); });
     67    assert_throws_js(TypeError, () => { hrefSet.call(null, URL_VALID); });
     68 }, "Cross-origin location.href setter throws TypeError in lexical realm on invalid |this| value");
     69 
     70 
     71 promise_test(async t => {
     72    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     73    assert_throws_js(sameOriginWindow.TypeError, () => { sameOriginWindow.location = Symbol(); });
     74 
     75    // The error originates in sameOriginWindow.location.href setter, hence it's not in realm of locationSet.
     76    assert_throws_js(sameOriginWindow.TypeError, () => { locationSet.call(sameOriginWindow, Symbol()); });
     77 }, "Same-origin window.location` setter throws TypeError in holder's realm on non-coercible URL argument");
     78 
     79 promise_test(async t => {
     80    const sameOriginWindow = await makeWindow(t, URL_SAME_ORIGIN);
     81    assert_throws_js(sameOriginWindow.TypeError, () => { sameOriginWindow.location.href = Symbol(); });
     82    assert_throws_js(TypeError, () => { hrefSet.call(sameOriginWindow.location, Symbol()); });
     83 }, "Same-origin location.href setter throws TypeError in holder's realm on non-coercible URL argument");
     84 
     85 promise_test(async t => {
     86    const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
     87    assert_throws_js(TypeError, () => { crossOriginWindow.location = Symbol(); });
     88    assert_throws_js(TypeError, () => { locationSet.call(crossOriginWindow, Symbol()); });
     89 }, "Cross-origin window.location setter throws TypeError in lexical realm on non-coercible URL argument");
     90 
     91 promise_test(async t => {
     92    const crossOriginWindow = await makeWindow(t, URL_CROSS_ORIGIN);
     93    assert_throws_js(TypeError, () => { crossOriginWindow.location.href = Symbol(); });
     94    assert_throws_js(TypeError, () => { hrefSet.call(crossOriginWindow.location, Symbol()); });
     95 }, "Cross-origin location.href setter throws TypeError in lexical realm on non-coercible URL argument");
     96 
     97 function makeWindow(t, src) {
     98    return new Promise(resolve => {
     99        const iframe = document.createElement("iframe");
    100        t.add_cleanup(() => { iframe.remove(); });
    101        iframe.onload = () => { resolve(iframe.contentWindow); };
    102        iframe.src = src;
    103        document.body.append(iframe);
    104    });
    105 }
    106 </script>