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));