-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Shared Storage: Allow writes from headers in all sandboxed frames
Previously, writing to shared storage via response headers by way of a fetch or image request would work inside a sandboxed iframe only if the iframe had sandbox flag "allow-same-origin". We remove this restriction. See WICG/shared-storage#155 for the related specification fix. Bug: 339172115 Change-Id: Ia3d048c8441bb99ea48d3943c55fe83c943bcadf
- Loading branch information
1 parent
d213c42
commit 888cc2b
Showing
7 changed files
with
226 additions
and
43 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
shared-storage/shared-storage-writable-fetch-request-for-data-url.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<!doctype html> | ||
<body> | ||
<script src=/resources/testharness.js></script> | ||
<script src=/resources/testharnessreport.js></script> | ||
<script> | ||
'use strict'; | ||
|
||
promise_test(async t => { | ||
const innerCode = | ||
`window.parent.postMessage({fetchStatus: "success"}, '*');`; | ||
const dataURL = 'data:text/javascript;base64,' | ||
+ btoa(unescape(encodeURIComponent(innerCode))); | ||
try { | ||
const response = await fetch(dataURL, {sharedStorageWritable: true}); | ||
} catch (error) { | ||
assert_equals(error.message, | ||
"Failed to execute 'fetch' on 'Window': " | ||
+ "sharedStorageWritable: sharedStorage operations are " | ||
+ "not available for opaque origins."); | ||
return; | ||
} | ||
assert_unreached('sharedStorageWritable fetch for data URL did not throw'); | ||
|
||
}, 'shared storage fetch request disallowed for data URL'); | ||
</script> | ||
</body> |
72 changes: 72 additions & 0 deletions
72
shared-storage/shared-storage-writable-fetch-request-in-data-url.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<!doctype html> | ||
<body> | ||
<script src=/resources/testharness.js></script> | ||
<script src=/resources/testharnessreport.js></script> | ||
<script src=/common/utils.js></script> | ||
<script src=/fenced-frame/resources/utils.js></script> | ||
<script src=/shared-storage/resources/util.js></script> | ||
<script> | ||
'use strict'; | ||
const origin = window.location.origin; | ||
const rawSetHeader = 'set;key=hello;value=world'; | ||
const setHeader = encodeURIComponent(rawSetHeader); | ||
|
||
promise_test(async t => { | ||
let frame = document.createElement('iframe'); | ||
const promise = new Promise((resolve, reject) => { | ||
window.addEventListener('message', async function handler(evt) { | ||
if (evt.source === frame.contentWindow && | ||
evt.data.sharedStorageFetchStatus) { | ||
document.body.removeChild(frame); | ||
window.removeEventListener('message', handler); | ||
resolve(evt.data.sharedStorageFetchStatus); | ||
} | ||
}); | ||
window.addEventListener('error', (error) => { | ||
reject(error); | ||
}); | ||
}); | ||
|
||
const fetchUrl = | ||
`${origin}\\/shared-storage\\/resources\\/shared-storage-write.py` | ||
+ `?write=${setHeader}`; | ||
const fetchCode = ` | ||
let parentOrOpener = window.opener || window.parent; | ||
let innerFrame = document.createElement('iframe'); | ||
window.addEventListener('message', async (evt) => { | ||
if (evt.source === innerFrame.contentWindow) { | ||
parentOrOpener.postMessage({sharedStorageFetchStatus: "success"}, '*'); | ||
} | ||
}); | ||
window.addEventListener('error', (error) => { | ||
parentOrOpener.postMessage({sharedStorageFetchStatus: error.message}, '*'); | ||
}); | ||
fetch('${fetchUrl}', {sharedStorageWritable: true}) | ||
.then(response => response.text()) | ||
.then(htmlContent => { | ||
innerFrame.srcdoc = htmlContent; | ||
document.body.appendChild(innerFrame); | ||
}) | ||
.catch(error => { | ||
parentOrOpener.postMessage({sharedStorageFetchStatus: error.message}, | ||
"*"); | ||
}); | ||
`; | ||
|
||
const dataURL = 'data:text/html;base64,' | ||
+ btoa(unescape('%3Chtml%3E%3Cbody%3E%3Cscript%3E' | ||
+ encodeURIComponent(fetchCode) + | ||
'%3C%2Fscript%3E%3C%2Fbody%3E%3C%2Fhtml%3E')); | ||
frame.src = dataURL; | ||
document.body.appendChild(frame); | ||
|
||
const result = await promise; | ||
assert_equals(result, | ||
"Failed to execute 'fetch' on 'Window': " | ||
+ "sharedStorageWritable: sharedStorage operations are " | ||
+ "only available in secure contexts."); | ||
await verifyKeyNotFoundForOrigin('hello', origin); | ||
|
||
}, 'shared storage fetch request disallowed in opaque origin from data URL'); | ||
</script> | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
shared-storage/shared-storage-writable-iframe-request-in-data-url.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<!doctype html> | ||
<body> | ||
<script src=/resources/testharness.js></script> | ||
<script src=/resources/testharnessreport.js></script> | ||
<script src=/common/utils.js></script> | ||
<script src=/fenced-frame/resources/utils.js></script> | ||
<script src=/shared-storage/resources/util.js></script> | ||
<script> | ||
'use strict'; | ||
const origin = window.location.origin; | ||
const rawSetHeader = 'set;key=hello;value=world'; | ||
const setHeader = encodeURIComponent(rawSetHeader); | ||
|
||
promise_test(async t => { | ||
let frame = document.createElement('iframe'); | ||
const promise = new Promise((resolve, reject) => { | ||
window.addEventListener('message', async function handler(evt) { | ||
if (evt.source === frame.contentWindow && | ||
evt.data.sharedStorageWritableHeader) { | ||
document.body.removeChild(frame); | ||
window.removeEventListener('message', handler); | ||
resolve(evt.data.sharedStorageWritableHeader); | ||
} | ||
}); | ||
window.addEventListener('error', (error) => { | ||
reject(error); | ||
}); | ||
}); | ||
|
||
const innerUrl = | ||
`${origin}\\/shared-storage\\/resources\\/shared-storage-write-` | ||
+ `notify-parent.py?write=${setHeader}`; | ||
const innerCode = ` | ||
let parentOrOpener = window.opener || window.parent; | ||
let innerFrame = document.createElement('iframe'); | ||
window.addEventListener('message', async (evt) => { | ||
if (evt.source === innerFrame.contentWindow && | ||
evt.data.sharedStorageWritableHeader) { | ||
parentOrOpener.postMessage({sharedStorageWritableHeader: | ||
evt.data.sharedStorageWritableHeader}, '*'); | ||
} | ||
}); | ||
window.addEventListener('error', (error) => { | ||
parentOrOpener.postMessage({sharedStorageWritableHeader: error.message}, '*'); | ||
}); | ||
innerFrame.src = '${innerUrl}'; | ||
innerFrame.sharedStorageWritable = true; | ||
document.body.appendChild(innerFrame); | ||
`; | ||
|
||
const dataURL = 'data:text/html;base64,' | ||
+ btoa(unescape('%3Chtml%3E%3Cbody%3E%3Cscript%3E' | ||
+ encodeURIComponent(innerCode) + | ||
'%3C%2Fscript%3E%3C%2Fbody%3E%3C%2Fhtml%3E')); | ||
frame.src = dataURL; | ||
document.body.appendChild(frame); | ||
|
||
const result = await promise; | ||
assert_equals(result, "NO_SHARED_STORAGE_WRITABLE_HEADER"); | ||
await verifyKeyNotFoundForOrigin('hello', origin); | ||
|
||
}, 'shared storage iframe request disallowed in opaque origin from data URL'); | ||
</script> | ||
</body> |
62 changes: 62 additions & 0 deletions
62
shared-storage/shared-storage-writable-img-request-in-data-url.tentative.https.sub.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
<!doctype html> | ||
<body> | ||
<script src=/resources/testharness.js></script> | ||
<script src=/resources/testharnessreport.js></script> | ||
<script src=/common/utils.js></script> | ||
<script src=/fenced-frame/resources/utils.js></script> | ||
<script src=/shared-storage/resources/util.js></script> | ||
<script> | ||
'use strict'; | ||
const origin = window.location.origin; | ||
const rawSetHeader = 'set;key=hello;value=world'; | ||
const setHeader = encodeURIComponent(rawSetHeader); | ||
|
||
promise_test(async t => { | ||
let frame = document.createElement('iframe'); | ||
const promise = new Promise((resolve, reject) => { | ||
window.addEventListener('message', async function handler(evt) { | ||
if (evt.source === frame.contentWindow && | ||
evt.data.sharedStorageWritableLoadStatus) { | ||
document.body.removeChild(frame); | ||
window.removeEventListener('message', handler); | ||
resolve(evt.data.sharedStorageWritableLoadStatus); | ||
} | ||
}); | ||
window.addEventListener('error', (error) => { | ||
reject(error); | ||
}); | ||
}); | ||
|
||
const imageUrl = | ||
`${origin}\\/shared-storage\\/resources\\/shared-storage-writable-` | ||
+ `pixel-write.png?write=${setHeader}`; | ||
const innerCode = ` | ||
let parentOrOpener = window.opener || window.parent; | ||
let image = document.createElement('img'); | ||
window.addEventListener('load', async (evt) => { | ||
parentOrOpener.postMessage({sharedStorageWritableLoadStatus: | ||
'loaded'}, '*'); | ||
}); | ||
window.addEventListener('error', (error) => { | ||
parentOrOpener.postMessage({sharedStorageWritableLoadStatus: error.message}, | ||
'*'); | ||
}); | ||
image.src = '${imageUrl}'; | ||
image.sharedStorageWritable = true; | ||
document.body.appendChild(image); | ||
`; | ||
|
||
const dataURL = 'data:text/html;base64,' | ||
+ btoa(unescape('%3Chtml%3E%3Cbody%3E%3Cscript%3E' | ||
+ encodeURIComponent(innerCode) + | ||
'%3C%2Fscript%3E%3C%2Fbody%3E%3C%2Fhtml%3E')); | ||
frame.src = dataURL; | ||
document.body.appendChild(frame); | ||
|
||
const result = await promise; | ||
assert_equals(result, "loaded"); | ||
await verifyKeyNotFoundForOrigin('hello', origin); | ||
|
||
}, 'shared storage iframe request disallowed in opaque origin from data URL'); | ||
</script> | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 0 additions & 41 deletions
41
shared-storage/shared-storage-writable-opaque-origin.tentative.https.sub.html
This file was deleted.
Oops, something went wrong.