tor-browser

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

inheritance-from-initiator.sub.html (6761B)


      1 <!DOCTYPE html>
      2 <script src="/resources/testharness.js"></script>
      3 <script src="/resources/testharnessreport.js"></script>
      4 
      5 <meta http-equiv="Content-Security-Policy" content="img-src http://{{hosts[][www]}}:{{ports[http][0]}}">
      6 <body>
      7  <script>
      8    let message_from = w => {
      9      return new Promise(resolve => {
     10        window.addEventListener('message', msg => {
     11          if (msg.source == w) {
     12            resolve(msg.data);
     13          }
     14        });
     15      });
     16    };
     17 
     18    // `iframe_a` and `iframe_b` are two helper iframes with different
     19    // CSPs.
     20    let iframe_a, iframe_b;
     21 
     22    // Setup `iframe_a` and `iframe_b`.
     23    promise_setup(async () => {
     24      iframe_a = document.createElement('iframe');
     25      iframe_a.src = "./support/iframe-do.sub.html?" +
     26        "img-src=http://{{hosts[][www1]}}:{{ports[http][0]}}";
     27      document.body.appendChild(iframe_a);
     28      await message_from(iframe_a.contentWindow);
     29 
     30      iframe_b = document.createElement('iframe');
     31      iframe_b.id = 'iframe_b';
     32      iframe_b.src = "./support/iframe-do.sub.html?" +
     33        "img-src=http://{{hosts[][www2]}}:{{ports[http][0]}}";
     34      document.body.appendChild(iframe_b);
     35      await message_from(iframe_b.contentWindow);
     36    });
     37 
     38    let test_iframe_id_counter = 0;
     39 
     40    // Helper function to create the target iframe of a navigation.
     41    let create_test_iframe = async () => {
     42      let test_iframe = document.createElement('iframe');
     43      test_iframe.id = "test_iframe_" + test_iframe_id_counter++;
     44      test_iframe.name = test_iframe.id;
     45      document.body.appendChild(test_iframe);
     46      return test_iframe;
     47    }
     48 
     49    // The following code will try loading several images and check
     50    // whether CSP has been inherited by the parent ("p"), `iframe_a`
     51    // ("a") or `iframe_b` ("b"). It will post a message to the top
     52    // with the result.
     53    let data_payload = `
     54      <body><script>
     55        new Promise(async (resolve, reject) => {
     56          const img_path = "/content-security-policy/support/pass.png";
     57 
     58          let img_loaded = (origin) => new Promise(resolve => {
     59            let img = document.createElement('img');
     60            img.onerror = () => resolve(false);
     61            img.onload = () => resolve(true);
     62            img.src = origin + img_path;
     63            document.body.appendChild(img);
     64          });
     65 
     66          inherited_from_p = await img_loaded(
     67            "http://{{hosts[][www]}}:{{ports[http][0]}}");
     68          inherited_from_a = await img_loaded(
     69            "http://{{hosts[][www1]}}:{{ports[http][0]}}");
     70          inherited_from_b = await img_loaded(
     71            "http://{{hosts[][www2]}}:{{ports[http][0]}}");
     72 
     73          if (inherited_from_a + inherited_from_b +
     74               inherited_from_p !== 1) {
     75            reject("Exactly one CSP should be inherited");
     76          }
     77          if (inherited_from_a) resolve("a");
     78          if (inherited_from_b) resolve("b");
     79          if (inherited_from_p) resolve("p");
     80        }).then(from => top.postMessage(from, '*'),
     81                error => top.postMessage(error, '*'));
     82      </scr`+`ipt></body>
     83    `;
     84 
     85    let data_url = "data:text/html;base64," + btoa(data_payload);
     86 
     87    promise_test(async t => {
     88      let test_iframe = await create_test_iframe();
     89      iframe_a.contentWindow.postMessage(
     90        `parent.document.getElementById('${test_iframe.id}').src = '${data_url}'`);
     91 
     92      assert_equals(await message_from(test_iframe.contentWindow), "p");
     93    }, "Setting src inherits from parent.");
     94 
     95    promise_test(async t => {
     96      let test_iframe = await create_test_iframe();
     97      iframe_a.contentWindow.postMessage(
     98        `parent.document.getElementById('${test_iframe.id}').contentWindow.location = '${data_url}'`);
     99 
    100      assert_equals(await message_from(test_iframe.contentWindow), "a");
    101    }, "Changing contentWindow.location inherits from who changed it.");
    102 
    103    promise_test(async t => {
    104      let test_iframe = await create_test_iframe();
    105      window.navigate_test_iframe = () => {
    106        test_iframe.contentWindow.location = data_url;
    107      };
    108      iframe_a.contentWindow.postMessage(`parent.navigate_test_iframe();`);
    109      assert_equals(await message_from(test_iframe.contentWindow), "p");
    110    }, "Changing contentWindow.location indirectly inherits from who changed it directly.");
    111 
    112    promise_test(async t => {
    113      let test_iframe = await create_test_iframe();
    114      iframe_a.contentWindow.postMessage(
    115        `window.open('${data_url}', "${test_iframe.name}")`);
    116 
    117      assert_equals(await message_from(test_iframe.contentWindow), "a");
    118    }, "window.open() inherits from caller.");
    119 
    120    promise_test(async t => {
    121      let test_iframe = await create_test_iframe();
    122      let a = iframe_b.contentDocument.createElement('a');
    123      a.id = 'a';
    124      a.href = data_url;
    125      a.target = test_iframe.name;
    126      iframe_b.contentDocument.body.appendChild(a);
    127 
    128      iframe_a.contentWindow.postMessage(
    129        `parent.document.getElementById('iframe_b').contentDocument.getElementById('a').click();`);
    130 
    131      assert_equals(await message_from(test_iframe.contentWindow), "b");
    132      iframe_b.contentDocument.body.removeChild(a);
    133    }, "Click on anchor inherits from owner of the anchor.");
    134 
    135    promise_test(async t => {
    136      let test_iframe = await create_test_iframe();
    137      let form = iframe_b.contentDocument.createElement('form');
    138      form.id = 'form';
    139      form.action = data_url;
    140      form.target = test_iframe.name;
    141      form.method = "POST";
    142      iframe_b.contentDocument.body.appendChild(form);
    143 
    144      iframe_a.contentWindow.postMessage(
    145        `parent.document.getElementById('iframe_b').contentDocument.getElementById('form').submit();`);
    146 
    147      assert_equals(await message_from(test_iframe.contentWindow), "b");
    148      iframe_b.contentDocument.body.removeChild(form);
    149    }, "Form submission through submit() inherits from owner of form.");
    150 
    151    promise_test(async t => {
    152      let test_iframe = await create_test_iframe();
    153      let form = iframe_b.contentDocument.createElement('form');
    154      form.id = 'form';
    155      form.action = data_url;
    156      form.target = test_iframe.name;
    157      form.method = "POST";
    158      iframe_b.contentDocument.body.appendChild(form);
    159      let button = iframe_b.contentDocument.createElement('button');
    160      button.type = "submit";
    161      button.value = "submit";
    162      button.id = "button";
    163      form.appendChild(button);
    164 
    165      iframe_a.contentWindow.postMessage(
    166        `parent.document.getElementById('iframe_b').contentDocument.getElementById('button').click();`);
    167 
    168      assert_equals(await message_from(test_iframe.contentWindow), "b");
    169      iframe_b.contentDocument.body.removeChild(form);
    170    }, "Form submission through button click inherits from owner of form.");
    171 
    172  </script>
    173 </body>