sandboxed-iframe.https.window.js (2907B)
1 // META: script=/common/get-host-info.sub.js 2 // META: script=/common/utils.js 3 // META: script=/fetch/fetch-later/resources/fetch-later-helper.js 4 // META: script=/fetch/fetch-later/quota/resources/helper.js 5 'use strict'; 6 7 const {HTTPS_ORIGIN, HTTPS_NOTSAMESITE_ORIGIN} = get_host_info(); 8 9 // Skips FormData & URLSearchParams, as browser adds extra bytes to them 10 // in addition to the user-provided content. It is difficult to test a 11 // request right at the quota limit. 12 // Skips File & Blob as it's difficult to estimate what additional data are 13 // added into them. 14 const dataType = BeaconDataType.String; 15 16 // Request headers are counted into total request size. 17 const headers = new Headers({'Content-Type': 'text/plain;charset=UTF-8'}); 18 19 const requestUrl = `${HTTPS_ORIGIN}/`; 20 const quota = getRemainingQuota(QUOTA_PER_ORIGIN, requestUrl, headers); 21 const SMALL_REQUEST_BODY_SIZE = 4 * 1024; // 4KB, well within minimal quota. 22 23 // This test validates the correct behavior for a sandboxed iframe without the 24 // 'allow-same-origin' token. 25 // 26 // Such an iframe should be treated as cross-origin, even if its `src` attribute 27 // points to a same-origin URL. Therefore, it should be allocated its own 28 // separate "minimal quota" (8KB) for fetchLater() requests and should NOT share 29 // the parent document's primary quota pool. 30 // 31 // The test works by first completely exhausting the parent document's quota. 32 // Then, it creates the sandboxed iframe and attempts to send a small request 33 // from it. 34 // 35 // The expected result is that the iframe's request SUCCEEDS, because it should 36 // have its own independent 8KB quota to use. 37 // 38 // NOTE: This test will FAIL until the underlying bug is fixed. The bug causes 39 // the sandboxed iframe to be incorrectly treated as same-origin, making it try 40 // to use the parent's already-exhausted quota, which leads to a premature 41 // QuotaExceededError. 42 promise_test(async test => { 43 const controller = new AbortController(); 44 test.add_cleanup(() => controller.abort()); 45 46 // Step 1: Exhaust the parent frame's entire fetchLater() quota. 47 fetchLater(requestUrl, { 48 method: 'POST', 49 signal: controller.signal, 50 body: makeBeaconData(generatePayload(quota), dataType), 51 referrer: '', // Referrer is part of the quota, so we control it. 52 }); 53 54 // Step 2: Create a sandboxed iframe and attempt a small fetchLater() 55 // call from it. This should succeed as it should have its own 8KB quota. 56 await loadFetchLaterIframe( 57 HTTPS_ORIGIN, // The iframe's src is same-origin. 58 { 59 targetUrl: requestUrl, 60 activateAfter: 0, 61 method: 'POST', 62 bodyType: dataType, 63 bodySize: SMALL_REQUEST_BODY_SIZE, 64 referrer: '', 65 sandbox: 'allow-scripts', // Sandboxed, but NOT allow-same-origin. 66 }); 67 }, `A sandboxed iframe (without allow-same-origin) should be treated as cross-origin and have its own minimal quota.`);