tor-browser

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

browser_canvas_rfp_exclusion.js (5619B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      4 *
      5 * Adapted from browser_canvas_fingerprinting_resistance.js
      6 */
      7 "use strict";
      8 
      9 const kUrl = "https://example.com/";
     10 var gPlacedData = false;
     11 
     12 function initTab(performReadbackTest) {
     13  let contentWindow = content.wrappedJSObject;
     14 
     15  let drawCanvas = (fillStyle, id) => {
     16    let contentDocument = contentWindow.document;
     17    let width = 64,
     18      height = 64;
     19    let canvas = contentDocument.createElement("canvas");
     20    if (id) {
     21      canvas.setAttribute("id", id);
     22    }
     23    canvas.setAttribute("width", width);
     24    canvas.setAttribute("height", height);
     25    contentDocument.body.appendChild(canvas);
     26 
     27    let context = canvas.getContext("2d");
     28    context.fillStyle = fillStyle;
     29    context.fillRect(0, 0, width, height);
     30    return canvas;
     31  };
     32 
     33  let canvas = drawCanvas("cyan", "canvas-id-canvas");
     34 
     35  let placedData = canvas.toDataURL();
     36  if (performReadbackTest) {
     37    is(
     38      canvas.toDataURL(),
     39      placedData,
     40      "Reading the placed data twice didn't match"
     41    );
     42    return placedData;
     43  }
     44  return undefined;
     45 }
     46 
     47 function disableResistFingerprinting() {
     48  return SpecialPowers.pushPrefEnv({
     49    set: [
     50      ["privacy.resistFingerprinting", false],
     51      ["privacy.resistFingerprinting.pbmode", false],
     52    ],
     53  });
     54 }
     55 
     56 function enableResistFingerprinting(RfpNonPbmExclusion, RfpDomainExclusion) {
     57  if (RfpNonPbmExclusion && RfpDomainExclusion) {
     58    return SpecialPowers.pushPrefEnv({
     59      set: [
     60        ["privacy.resistFingerprinting.pbmode", true],
     61        ["privacy.resistFingerprinting.exemptedDomains", "example.com"],
     62      ],
     63    });
     64  } else if (RfpNonPbmExclusion) {
     65    return SpecialPowers.pushPrefEnv({
     66      set: [["privacy.resistFingerprinting.pbmode", true]],
     67    });
     68  } else if (RfpDomainExclusion) {
     69    return SpecialPowers.pushPrefEnv({
     70      set: [
     71        ["privacy.resistFingerprinting", true],
     72        ["privacy.resistFingerprinting.exemptedDomains", "example.com"],
     73      ],
     74    });
     75  }
     76  return SpecialPowers.pushPrefEnv({
     77    set: [["privacy.resistFingerprinting", true]],
     78  });
     79 }
     80 
     81 function extractCanvasData(
     82  placedData,
     83  isPbm,
     84  RfpNonPbmExclusion,
     85  RfpDomainExclusion
     86 ) {
     87  let contentWindow = content.wrappedJSObject;
     88  let canvas = contentWindow.document.getElementById("canvas-id-canvas");
     89  let canvasData = canvas.toDataURL();
     90 
     91  if (RfpDomainExclusion) {
     92    is(
     93      canvasData,
     94      placedData,
     95      `A: RFP, domain exempted, canvas data == placed data (isPbm: ${isPbm}, RfpNonPbmExclusion: ${RfpNonPbmExclusion}, RfpDomainExclusion: ${RfpDomainExclusion})`
     96    );
     97  } else if (!isPbm && RfpNonPbmExclusion) {
     98    is(
     99      canvasData,
    100      placedData,
    101      `B: RFP, nonPBM exempted, not in PBM, canvas data == placed data (isPbm: ${isPbm}, RfpNonPbmExclusion: ${RfpNonPbmExclusion}, RfpDomainExclusion: ${RfpDomainExclusion})`
    102    );
    103  } else if (isPbm && RfpNonPbmExclusion) {
    104    isnot(
    105      canvasData,
    106      placedData,
    107      `C: RFP, nonPBM exempted, in PBM, canvas data != placed data (isPbm: ${isPbm}, RfpNonPbmExclusion: ${RfpNonPbmExclusion}, RfpDomainExclusion: ${RfpDomainExclusion})`
    108    );
    109  } else {
    110    isnot(
    111      canvasData,
    112      placedData,
    113      `D: RFP, domain not exempted, nonPBM not exempted, canvas data != placed data (isPbm: ${isPbm}, RfpNonPbmExclusion: ${RfpNonPbmExclusion}, RfpDomainExclusion: ${RfpDomainExclusion})`
    114    );
    115  }
    116 }
    117 
    118 async function populatePlacedData() {
    119  let win = await BrowserTestUtils.openNewBrowserWindow();
    120  await disableResistFingerprinting();
    121  await BrowserTestUtils.withNewTab(
    122    {
    123      gBrowser: win.gBrowser,
    124      url: kUrl,
    125    },
    126    async function () {
    127      let browser = win.gBrowser.selectedBrowser;
    128      gPlacedData = await SpecialPowers.spawn(
    129        browser,
    130        [/* performReadbackTest= */ true],
    131        initTab
    132      );
    133    }
    134  );
    135  await BrowserTestUtils.closeWindow(win);
    136  await SpecialPowers.popPrefEnv();
    137 }
    138 
    139 async function rfpExclusionTestOnCanvas(
    140  win,
    141  placedData,
    142  isPbm,
    143  RfpNonPbmExclusion,
    144  RfpDomainExclusion
    145 ) {
    146  let browser = win.gBrowser.selectedBrowser;
    147  await SpecialPowers.spawn(
    148    browser,
    149    [/* performReadbackTest= */ false],
    150    initTab
    151  );
    152  await SpecialPowers.spawn(
    153    browser,
    154    [placedData, isPbm, RfpNonPbmExclusion, RfpDomainExclusion],
    155    extractCanvasData
    156  );
    157 }
    158 
    159 async function testCanvasRfpExclusion(
    160  isPbm,
    161  RfpNonPbmExclusion,
    162  RfpDomainExclusion
    163 ) {
    164  let win = await BrowserTestUtils.openNewBrowserWindow({
    165    private: isPbm,
    166  });
    167  await enableResistFingerprinting(RfpNonPbmExclusion, RfpDomainExclusion);
    168  await BrowserTestUtils.withNewTab(
    169    {
    170      gBrowser: win.gBrowser,
    171      url: kUrl,
    172    },
    173    rfpExclusionTestOnCanvas.bind(
    174      null,
    175      win,
    176      gPlacedData,
    177      isPbm,
    178      RfpNonPbmExclusion,
    179      RfpDomainExclusion
    180    )
    181  );
    182  await BrowserTestUtils.closeWindow(win);
    183  await SpecialPowers.popPrefEnv();
    184 }
    185 
    186 add_task(populatePlacedData.bind(null));
    187 add_task(testCanvasRfpExclusion.bind(null, false, false, false));
    188 add_task(testCanvasRfpExclusion.bind(null, false, false, true));
    189 add_task(testCanvasRfpExclusion.bind(null, false, true, false));
    190 add_task(testCanvasRfpExclusion.bind(null, false, true, true));
    191 add_task(testCanvasRfpExclusion.bind(null, true, false, false));
    192 add_task(testCanvasRfpExclusion.bind(null, true, false, true));
    193 add_task(testCanvasRfpExclusion.bind(null, true, true, false));
    194 add_task(testCanvasRfpExclusion.bind(null, true, true, true));