tor-browser

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

fetch-canvas-tainting-video-with-range-request.https.html (5286B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>Canvas tainting due to video whose responses are fetched via a service worker including range requests</title>
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script src="resources/test-helpers.sub.js?pipe=sub"></script>
      7 <script src="/common/get-host-info.sub.js"></script>
      8 <body>
      9 <script>
     10 // These tests try to test canvas tainting due to a <video> element. The video
     11 // src URL is same-origin as the page, but the response is fetched via a service
     12 // worker that does tricky things like returning opaque responses from another
     13 // origin. Furthermore, this tests range requests so there are multiple
     14 // responses.
     15 //
     16 // We test range requests by having the server return 206 Partial Content to the
     17 // first request (which doesn't necessarily have a "Range" header or one with a
     18 // byte range). Then the <video> element automatically makes ranged requests
     19 // (the "Range" HTTP request header specifies a byte range). The server responds
     20 // to these with 206 Partial Content for the given range.
     21 let unique = 0; // See https://bugzilla.mozilla.org/show_bug.cgi?id=1129121
     22 function range_request_test(script, expected, description,
     23                            {remote_origin_src} = {}) {
     24  promise_test(t => {
     25      let frame;
     26      let registration;
     27      add_result_callback(() => {
     28          if (frame) frame.remove();
     29          if (registration) registration.unregister();
     30        });
     31 
     32      const scope = 'resources/fetch-canvas-tainting-iframe.html';
     33      return service_worker_unregister_and_register(t, script, scope)
     34        .then(r => {
     35            registration = r;
     36            return wait_for_state(t, registration.installing, 'activated');
     37          })
     38        .then(() => {
     39            return with_iframe(scope);
     40          })
     41        .then(f => {
     42            frame = f;
     43            // Add "?PartialContent&VIDEO" to get a video resource from the
     44            // server using range requests.
     45            let video_url =
     46              'fetch-access-control.py?PartialContent&VIDEO=' + unique++;
     47            if (remote_origin_src) {
     48              video_url = get_host_info().HTTPS_REMOTE_ORIGIN +
     49                base_path() + 'resources/' + video_url;
     50            }
     51            return frame.contentWindow.create_test_case_promise(video_url);
     52          })
     53        .then(result => {
     54            assert_equals(result, expected);
     55          });
     56    }, description);
     57 }
     58 
     59 // We want to consider a number of scenarios:
     60 // (1) Range responses come from a single origin, the same-origin as the page.
     61 //     The canvas should not be tainted.
     62 range_request_test(
     63  'resources/fetch-event-network-fallback-worker.js',
     64  'NOT_TAINTED',
     65  'range responses from single origin (same-origin)');
     66 
     67 // (2) Range responses come from a single origin, cross-origin from the page
     68 //     (and without CORS sharing). This is not possible to test, since service
     69 //     worker can't make a request with a "Range" HTTP header in no-cors mode.
     70 
     71 // (3) Range responses come from multiple origins. The first response comes from
     72 //     cross-origin (and without CORS sharing, so is opaque). Subsequent
     73 //     responses come from same-origin. This should result in a load error, as regardless of canvas
     74 //     loading range requests from multiple opaque origins can reveal information across those origins.
     75 range_request_test(
     76  'resources/range-request-to-different-origins-worker.js',
     77  'LOAD_ERROR',
     78  'range responses from multiple origins (cross-origin first)');
     79 
     80 // (4) Range responses come from multiple origins. The first response comes from
     81 //     same-origin. Subsequent responses come from cross-origin (and without
     82 //     CORS sharing). Like (2) this is not possible since the service worker
     83 //     cannot make range requests cross-origin.
     84 
     85 // (5) Range responses come from a single origin, with a mix of opaque and
     86 //     non-opaque responses. The first request uses 'no-cors' mode to
     87 //     receive an opaque response, and subsequent range requests use 'cors'
     88 //     to receive non-opaque responses. The canvas should be tainted.
     89 range_request_test(
     90  'resources/range-request-with-different-cors-modes-worker.js',
     91  'TAINTED',
     92  'range responses from single origin with both opaque and non-opaque responses');
     93 
     94 // (6) Range responses come from a single origin, with a mix of opaque and
     95 //     non-opaque responses. The first request uses 'cors' mode to
     96 //     receive an non-opaque response, and subsequent range requests use
     97 //     'no-cors' to receive non-opaque responses. Like (2) this is not possible.
     98 
     99 // (7) The first Range response is synthesized using the Response constructor.
    100 //     Subsequent responses are same-origin, not handled by the service worker.
    101 range_request_test(
    102  'resources/range-request-with-synth-head-worker.js',
    103  'NOT_TAINTED',
    104  'synth and same-origin fallback range responses');
    105 
    106 // (8) The first Range response is synthesized using the Response constructor.
    107 //     Subsequent responses are cross-origin, not handled by the service worker,
    108 //     no-cors and opaque.
    109 range_request_test(
    110  'resources/range-request-with-synth-head-worker.js',
    111  'LOAD_ERROR',
    112  'synth and cross-origin fallback range responses',
    113  {remote_origin_src: true});
    114 </script>
    115 </body>