browser_webconsole_trackingprotection_errors.js (11717B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 // Load a page with tracking elements that get blocked and make sure that a 5 // 'learn more' link shows up in the webconsole. 6 7 "use strict"; 8 requestLongerTimeout(2); 9 10 const TEST_PATH = "browser/devtools/client/webconsole/test/browser/"; 11 const TEST_FILE = TEST_PATH + "test-trackingprotection-securityerrors.html"; 12 const TEST_FILE_THIRD_PARTY_ONLY = 13 TEST_PATH + "test-trackingprotection-securityerrors-thirdpartyonly.html"; 14 const TEST_URI = "https://example.com/" + TEST_FILE; 15 const TEST_URI_THIRD_PARTY_ONLY = 16 "https://example.com/" + TEST_FILE_THIRD_PARTY_ONLY; 17 const TRACKER_URL = "https://tracking.example.org/"; 18 const THIRD_PARTY_URL = "https://example.org/"; 19 const BLOCKED_URL = `\u201c${ 20 TRACKER_URL + TEST_PATH + "cookieSetter.html" 21 }\u201d`; 22 const PARTITIONED_URL = `\u201c${ 23 THIRD_PARTY_URL + TEST_PATH 24 }cookieSetter.html\u201d`; 25 26 const COOKIE_BEHAVIOR_PREF = "network.cookie.cookieBehavior"; 27 const COOKIE_BEHAVIORS = { 28 // reject all third-party cookies 29 REJECT_FOREIGN: 1, 30 // reject all cookies 31 REJECT: 2, 32 // reject third-party cookies unless the eTLD already has at least one cookie 33 LIMIT_FOREIGN: 3, 34 // reject trackers 35 REJECT_TRACKER: 4, 36 // dFPI - partitioned access to third-party cookies 37 PARTITION_FOREIGN: 5, 38 }; 39 40 const { UrlClassifierTestUtils } = ChromeUtils.importESModule( 41 "resource://testing-common/UrlClassifierTestUtils.sys.mjs" 42 ); 43 44 registerCleanupFunction(async function () { 45 UrlClassifierTestUtils.cleanupTestTrackers(); 46 47 await new Promise(resolve => { 48 Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () => 49 resolve() 50 ); 51 }); 52 }); 53 54 pushPref("devtools.webconsole.groupSimilarMessages", false); 55 56 add_task(async function testEnhancedTrackingProtectionMessage() { 57 await UrlClassifierTestUtils.addTestTrackers(); 58 59 await pushPref("privacy.trackingprotection.enabled", true); 60 const hud = await openNewTabAndConsole(TRACKER_URL + TEST_FILE); 61 62 info("Test tracking protection message"); 63 const message = await waitFor(() => 64 findWarningMessage( 65 hud, 66 `The resource at \u201chttps://tracking.example.com/\u201d was blocked because ` + 67 `Enhanced Tracking Protection is enabled` 68 ) 69 ); 70 71 await testLearnMoreClickOpenNewTab( 72 message, 73 "https://developer.mozilla.org/Web/Privacy/Guides/Firefox_tracking_protection" + 74 DOCS_GA_PARAMS 75 ); 76 }); 77 78 add_task(async function testForeignCookieBlockedMessage() { 79 info("Test foreign cookie blocked message"); 80 // Bug 1518138: GC heuristics are broken for this test, so that the test 81 // ends up running out of memory. Try to work-around the problem by GCing 82 // before the test begins. 83 Cu.forceShrinkingGC(); 84 // We change the pref and open a new window to ensure it will be taken into account. 85 await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_FOREIGN); 86 const { hud, win } = await openNewWindowAndConsole(TEST_URI); 87 const message = await waitFor(() => 88 findWarningMessage( 89 hud, 90 `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` + 91 `blocking all third-party storage access requests and Enhanced Tracking Protection is enabled` 92 ) 93 ); 94 await testLearnMoreClickOpenNewTab( 95 message, 96 getStorageErrorUrl("CookieBlockedForeign") 97 ); 98 // We explicitly destroy the toolbox in order to ensure waiting for its full destruction 99 // and avoid leak / pending requests 100 await hud.toolbox.destroy(); 101 win.close(); 102 }); 103 104 add_task(async function testLimitForeignCookieBlockedMessage() { 105 info("Test unvisited eTLD foreign cookies blocked message"); 106 // Bug 1518138: GC heuristics are broken for this test, so that the test 107 // ends up running out of memory. Try to work-around the problem by GCing 108 // before the test begins. 109 Cu.forceShrinkingGC(); 110 // We change the pref and open a new window to ensure it will be taken into account. 111 await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.LIMIT_FOREIGN); 112 const { hud, win } = await openNewWindowAndConsole(TEST_URI); 113 114 const message = await waitFor( 115 () => 116 findWarningMessage( 117 hud, 118 `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` + 119 `blocking all third-party storage access requests and Enhanced Tracking Protection is enabled` 120 ), 121 "Wait for 'blocking all third-party storage access' message", 122 100 123 ); 124 ok(true, "Third-party storage access blocked message was displayed"); 125 126 info("Check that clicking on the Learn More link works as expected"); 127 await testLearnMoreClickOpenNewTab( 128 message, 129 getStorageErrorUrl("CookieBlockedForeign") 130 ); 131 // We explicitely destroy the toolbox in order to ensure waiting for its full destruction 132 // and avoid leak / pending requests 133 await hud.toolbox.destroy(); 134 win.close(); 135 }); 136 137 add_task(async function testAllCookieBlockedMessage() { 138 info("Test all cookies blocked message"); 139 // We change the pref and open a new window to ensure it will be taken into account. 140 await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT); 141 const { hud, win } = await openNewWindowAndConsole(TEST_URI); 142 143 const message = await waitFor(() => 144 findWarningMessage( 145 hud, 146 `Request to access cookie or storage on ${BLOCKED_URL} was blocked because we are ` + 147 `blocking all storage access requests` 148 ) 149 ); 150 await testLearnMoreClickOpenNewTab( 151 message, 152 getStorageErrorUrl("CookieBlockedAll") 153 ); 154 // We explicitely destroy the toolbox in order to ensure waiting for its full destruction 155 // and avoid leak / pending requests 156 await hud.toolbox.destroy(); 157 win.close(); 158 }); 159 160 add_task(async function testTrackerCookieBlockedMessage() { 161 info("Test tracker cookie blocked message"); 162 // We change the pref and open a new window to ensure it will be taken into account. 163 await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.REJECT_TRACKER); 164 const { hud, win } = await openNewWindowAndConsole(TEST_URI); 165 166 const message = await waitFor(() => 167 findWarningMessage( 168 hud, 169 `Request to access cookie or storage on ${BLOCKED_URL} was blocked because it came ` + 170 `from a tracker and Enhanced Tracking Protection is enabled` 171 ) 172 ); 173 await testLearnMoreClickOpenNewTab( 174 message, 175 getStorageErrorUrl("CookieBlockedTracker") 176 ); 177 // We explicitely destroy the toolbox in order to ensure waiting for its full destruction 178 // and avoid leak / pending requests 179 await hud.toolbox.destroy(); 180 win.close(); 181 }); 182 183 add_task(async function testForeignCookiePartitionedMessage() { 184 info("Test tracker cookie blocked message"); 185 // We change the pref and open a new window to ensure it will be taken into account. 186 await pushPref(COOKIE_BEHAVIOR_PREF, COOKIE_BEHAVIORS.PARTITION_FOREIGN); 187 const { hud, win } = await openNewWindowAndConsole(TEST_URI_THIRD_PARTY_ONLY); 188 189 const message = await waitFor(() => 190 findWarningMessage( 191 hud, 192 `Partitioned cookie or storage access was provided to ${PARTITIONED_URL} because it is ` + 193 `loaded in the third-party context and dynamic state partitioning is enabled.` 194 ) 195 ); 196 await testLearnMoreClickOpenNewTab( 197 message, 198 getStorageErrorUrl("CookiePartitionedForeign") 199 ); 200 // We explicitely destroy the toolbox in order to ensure waiting for its full destruction 201 // and avoid leak / pending requests 202 await hud.toolbox.destroy(); 203 win.close(); 204 }); 205 206 add_task(async function testCookieBlockedByPermissionMessage() { 207 info("Test cookie blocked by permission message"); 208 // Turn off tracking protection and add a block permission on the URL. 209 await pushPref("privacy.trackingprotection.enabled", false); 210 const p = 211 Services.scriptSecurityManager.createContentPrincipalFromOrigin( 212 TRACKER_URL 213 ); 214 Services.perms.addFromPrincipal( 215 p, 216 "cookie", 217 Ci.nsIPermissionManager.DENY_ACTION 218 ); 219 220 const { hud, win } = await openNewWindowAndConsole(TEST_URI); 221 const message = await waitFor(() => 222 findWarningMessage( 223 hud, 224 `Request to access cookies or ` + 225 `storage on ${BLOCKED_URL} was blocked because of custom cookie permission` 226 ) 227 ); 228 await testLearnMoreClickOpenNewTab( 229 message, 230 getStorageErrorUrl("CookieBlockedByPermission") 231 ); 232 // We explicitely destroy the toolbox in order to ensure waiting for its full destruction 233 // and avoid leak / pending requests 234 await hud.toolbox.destroy(); 235 win.close(); 236 237 // Remove the custom permission. 238 Services.perms.removeFromPrincipal(p, "cookie"); 239 }); 240 241 add_task(async function testCookieBlockedForUserContentResourceMessage() { 242 info("Test usercontent resource cookie blocking"); 243 // Bug 1518138: GC heuristics are broken for this test, so that the test 244 // ends up running out of memory. Try to work-around the problem by GCing 245 // before the test begins. 246 Cu.forceShrinkingGC(); 247 await pushPref("privacy.antitracking.isolateContentScriptResources", true); 248 249 const extension = ExtensionTestUtils.loadExtension({ 250 manifest: { 251 content_scripts: [ 252 { 253 matches: [`*://example.com/*/test-blank.html`], 254 js: ["content_scripts.js"], 255 all_frames: true, 256 }, 257 ], 258 }, 259 files: { 260 "content_scripts.js": ` 261 // An image 262 const img = document.createElement("img"); 263 img.src = "https://example.com/${TEST_PATH}test-image.png"; 264 document.body.appendChild(img); 265 266 // A script 267 const script = document.createElement("script"); 268 script.src = "https://example.com/${TEST_PATH}empty-with-cookie.js"; 269 document.body.appendChild(script); 270 `, 271 }, 272 }); 273 274 await extension.startup(); 275 276 const { hud, win } = await openNewWindowAndConsole( 277 "https://example.com/" + TEST_PATH + "test-blank.html" 278 ); 279 280 await waitFor( 281 () => 282 findWarningMessage( 283 hud, 284 "Request to access cookie or storage on “https://example.com/" + 285 `${TEST_PATH}test-image.png” was blocked because we are blocking all ` + 286 "storage access requests." 287 ) && 288 findWarningMessage( 289 hud, 290 "Request to access cookie or storage on “https://example.com/" + 291 `${TEST_PATH}empty-with-cookie.js” was blocked because we are ` + 292 "blocking all storage access requests." 293 ) 294 ); 295 ok(true, "Third-party storage access blocked message was displayed"); 296 297 // We explicitly destroy the toolbox in order to ensure waiting for its full destruction 298 // and avoid leak / pending requests 299 await hud.toolbox.destroy(); 300 win.close(); 301 302 await extension.unload(); 303 }); 304 305 function getStorageErrorUrl(category) { 306 const BASE_STORAGE_ERROR_URL = 307 "https://developer.mozilla.org/docs/Web/Privacy/Guides/Storage_Access_Policy/Errors/"; 308 const STORAGE_ERROR_URL_PARAMS = new URLSearchParams({ 309 utm_source: "devtools", 310 utm_medium: "firefox-cookie-errors", 311 utm_campaign: "default", 312 }).toString(); 313 return `${BASE_STORAGE_ERROR_URL}${category}?${STORAGE_ERROR_URL_PARAMS}`; 314 } 315 316 async function testLearnMoreClickOpenNewTab(message, expectedUrl) { 317 info("Clicking on the Learn More link"); 318 319 const learnMoreLink = message.querySelector(".learn-more-link"); 320 const linkSimulation = await simulateLinkClick(learnMoreLink); 321 checkLink({ 322 ...linkSimulation, 323 expectedLink: expectedUrl, 324 expectedTab: "tab", 325 }); 326 } 327 328 function checkLink({ link, where, expectedLink, expectedTab }) { 329 is(link, expectedLink, `Clicking the provided link opens ${link}`); 330 is(where, expectedTab, `Clicking the provided link opens in expected tab`); 331 }