Skip to content

Commit

Permalink
Enable sharedStorage.get() in network-restricted fenced frames.
Browse files Browse the repository at this point in the history
If the proper flag (kFencedFramesLocalUnpartitionedDataAccess) is
enabled, sharedStorage.get() can now be called in fenced frames.
The call will only succeed if the entire tree rooted at the fenced
frame has disabled untrusted network access, including nested
fenced frames trees.

Bug: 324440086
Change-Id: Ie6788ba6d299a334800ecf11ba90151eaf40f43d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5279221
Reviewed-by: Cammie Smith Barnes <[email protected]>
Reviewed-by: Ben Kelly <[email protected]>
Commit-Queue: Andrew Verge <[email protected]>
Reviewed-by: Garrett Tanzer <[email protected]>
Reviewed-by: Arthur Sonzogni <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1272982}
  • Loading branch information
VergeA authored and chromium-wpt-export-bot committed Mar 14, 2024
1 parent c9a1cb9 commit b83bbdf
Showing 1 changed file with 141 additions and 0 deletions.
141 changes: 141 additions & 0 deletions fenced-frame/content-shared-storage-get.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<!DOCTYPE html>
<title>Test sharedStorage.get() in a fenced frame with network revocation.</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script src="/common/dispatcher/dispatcher.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/utils.js"></script>

<body>
<script>

promise_setup(async () => {
// Set sharedStorage value for HTTPS_ORIGIN
await sharedStorage.set('test', 'apple');

// Set sharedStorage value for HTTPS_REMOTE_ORIGIN.
let init_iframe = await attachIFrameContext(
{origin: get_host_info().HTTPS_REMOTE_ORIGIN});
await init_iframe.execute(async () => {
await sharedStorage.set('test', 'banana');
});
});

promise_test(async (t) => {
const fencedframe = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

await fencedframe.execute(async () => {
await window.fence.disableUntrustedNetwork();
let get_result = await sharedStorage.get('test');
assert_equals(get_result, 'apple');
});
}, 'Test sharedStorage.get() succeeds in a fenced frame with network revocation.');

promise_test(async (t) => {
const fencedframe = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

await fencedframe.execute(async () => {
try {
await sharedStorage.get('test');
assert_unreached('Calling get() without revoking network should throw.');
} catch (e) {
assert_equals(e.name, 'OperationError');
assert_equals(e.message, 'sharedStorage.get() is not allowed in a ' +
'fenced frame until network access for it and all descendent frames ' +
'has been revoked with window.fence.disableUntrustedNetwork()');
}
});
}, 'Test that sharedStorage.get() in a fenced frame rejects when network is not revoked.');

promise_test(async (t) => {
const fencedframe = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_REMOTE_ORIGIN});

await fencedframe.execute(async () => {
await window.fence.disableUntrustedNetwork();
let get_result = await sharedStorage.get('test');
assert_equals(get_result, 'banana');
});
}, 'Test that sharedStorage.get() can only fetch keys for its own origin when network is revoked.');

promise_test(async (t) => {
// First, try get() in a top-level document.
try {
await sharedStorage.get('test');
assert_unreached('Call to get() in top-level document should throw.');
} catch (e) {
assert_equals(e.name, 'OperationError');
assert_equals(e.message, 'Cannot call get() outside of a fenced frame.')
}

const samesite_iframe = await attachIFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

// Then, try get() in an iframe.
await samesite_iframe.execute(async () => {
try {
await sharedStorage.get('test');
assert_unreached('Call to get() outside a fenced frame should throw.');
} catch (e) {
assert_equals(e.name, 'OperationError');
assert_equals(e.message, 'Cannot call get() outside of a fenced frame.')
}
});
}, 'Test that sharedStorage.get() rejects outside of a fenced frame.');

promise_test(async (t) => {
const fencedframe = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

let get_result = await fencedframe.execute(async () => {
const nested_frame = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

// Note that the parent fenced frame has not disabled network at this point.
return nested_frame.execute(async () => {
await window.fence.disableUntrustedNetwork();
return sharedStorage.get('test');
});
});

assert_equals(get_result, 'apple');
}, 'Test that sharedStorage.get() succeeds in a nested fenced frame with network disabled, ' +
'even if the parent fenced frame has not disabled network yet.');

promise_test(async (t) => {
const fencedframe = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN});

await fencedframe.execute(async () => {
const nested_frame = await attachFencedFrameContext(
{origin: get_host_info().HTTPS_ORIGIN})

// Note that we do *not* await, because we need to operate in the top frame
// while the nested frame still hasn't disabled network access.
// TODO(crbug.com/324440086): disableUntrustedNetwork() should not resolve
// until all child frames also disable untrusted network. However, that
// behavior is yet to be implemented. We should add a timeout check here
// once the async behavior of disableUntrustedNetwork() is correct.
let disable_network_promise = window.fence.disableUntrustedNetwork();

try {
await sharedStorage.get('test');
assert_unreached('sharedStorage.get() is not allowed in a fenced frame ' +
'until network access for it and all descendent frames has been ' +
'revoked with window.fence.disableUntrustedNetwork()');
} catch (e) {
assert_equals(e.name, 'OperationError');
assert_equals(e.message, 'sharedStorage.get() is not allowed in a ' +
'fenced frame until network access for it and all descendent frames ' +
'has been revoked with window.fence.disableUntrustedNetwork()');
}
});
}, 'sharedStorage.get() fails in a top-level fenced frame with network disabled, ' +
'because a nested fenced frame has not disabled network yet.');

</script>
</body>

0 comments on commit b83bbdf

Please sign in to comment.