Skip to content

Commit

Permalink
[shared storage] implement permissions policy
Browse files Browse the repository at this point in the history
Add the "shared-storage" permissions policy that disallows all
Shared Storage methods.
https://github.com/WICG/shared-storage/blob/main/README.md#permissions-policy

Due to this change, Shared Storage won't be allowed in Fenced Frames
as Fenced Frames disallow all permissions policies. This decision may
change in the future: WICG/fenced-frame#44

Bug: 1337454
Change-Id: I856d31933032355409585bc376f2b6826f667270
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3710841
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Ian Clelland <iclelland@chromium.org>
Commit-Queue: Yao Xiao <yaoxia@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1023892}
  • Loading branch information
yaoxiachromium authored and chromium-wpt-export-bot committed Jul 13, 2022
1 parent f9c8075 commit af5e7ca
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 0 deletions.
29 changes: 29 additions & 0 deletions shared-storage/permissions-policy-default.tentative.https.sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/permissions-policy/resources/permissions-policy.js></script>
<script src="/shared-storage/resources/util.js"></script>
<script>
'use strict';
const same_origin_src = '/shared-storage/resources/permissions-policy-helper.html';
const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
const header = 'Default permissions policy';

promise_test(async t => {
const allowed = await AreSharedStorageMethodsAllowedByPermissionsPolicy();
assert_true(allowed);
}, header + ' allows sharedStorage in the current page.');

async_test(t => {
test_feature_availability('shared-storage', t, same_origin_src,
expect_feature_available_default);
}, header + ' allows sharedStorage in same-origin iframes.');

async_test(t => {
test_feature_availability('shared-storage', t, cross_origin_src,
expect_feature_available_default);
}, header + ' allows sharedStorage in cross-origin iframes.');
</script>
</body>
29 changes: 29 additions & 0 deletions shared-storage/permissions-policy-none.tentative.https.sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/permissions-policy/resources/permissions-policy.js></script>
<script src="/shared-storage/resources/util.js"></script>
<script>
'use strict';
const same_origin_src = '/shared-storage/resources/permissions-policy-helper.html';
const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
const header = 'permissions policy header shared-storage=()';

promise_test(async t => {
const allowed = await AreSharedStorageMethodsAllowedByPermissionsPolicy();
assert_false(allowed);
}, header + ' disallows sharedStorage in the current page.');

async_test(t => {
test_feature_availability('shared-storage', t, same_origin_src,
expect_feature_unavailable_default);
}, header + ' disallows sharedStorage in same-origin iframes.');

async_test(t => {
test_feature_availability('shared-storage', t, cross_origin_src,
expect_feature_unavailable_default);
}, header + ' disallows sharedStorage in cross-origin iframes.');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Permissions-Policy: shared-storage=()
29 changes: 29 additions & 0 deletions shared-storage/permissions-policy-self.tentative.https.sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/permissions-policy/resources/permissions-policy.js></script>
<script src="/shared-storage/resources/util.js"></script>
<script>
'use strict';
const same_origin_src = '/shared-storage/resources/permissions-policy-helper.html';
const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
same_origin_src;
const header = 'permissions policy header shared-storage=(self)';

promise_test(async t => {
const allowed = await AreSharedStorageMethodsAllowedByPermissionsPolicy();
assert_true(allowed);
}, header + ' allows sharedStorage in the current page.');

async_test(t => {
test_feature_availability('shared-storage', t, same_origin_src,
expect_feature_available_default);
}, header + ' allows sharedStorage in same-origin iframes.');

async_test(t => {
test_feature_availability('shared-storage', t, cross_origin_src,
expect_feature_unavailable_default);
}, header + ' disallows sharedStorage in cross-origin iframes.');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Permissions-Policy: shared-storage=(self)
18 changes: 18 additions & 0 deletions shared-storage/resources/permissions-policy-helper.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!doctype html>
<body>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/shared-storage/resources/util.js"></script>
<script>
'use strict';

window.onload = async function() {
if (await AreSharedStorageMethodsAllowedByPermissionsPolicy()) {
parent.postMessage({ type: 'availability-result', enabled: true }, '*');
return;
}

parent.postMessage({ type: 'availability-result', enabled: false }, '*');
}
</script>
</body>
1 change: 1 addition & 0 deletions shared-storage/resources/simple-module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
'use strict';
69 changes: 69 additions & 0 deletions shared-storage/resources/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

// Execute all shared storage methods and capture their errors. Return true if
// the permissions policy allows all of them; return false if the permissions
// policy disallows all of them. Precondition: only these two outcomes are
// possible.
async function AreSharedStorageMethodsAllowedByPermissionsPolicy() {
let permissionsPolicyDeniedCount = 0;
const errorMessage = 'The \"shared-storage\" Permissions Policy denied the method on window.sharedStorage.';

try {
await window.sharedStorage.worklet.addModule('/shared-storage/resources/simple-module.js');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

try {
await window.sharedStorage.run('operation');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

try {
// Run selectURL() with without addModule() and this should always fail.
// Check the error message to distinguish between the permissions policy
// error and the missing addModule() error.
await sharedStorage.selectURL("operation", [{url: "1.html"}]);
assert_unreached("did not fail");
} catch (e) {
if (e.message === errorMessage) {
++permissionsPolicyDeniedCount;
}
}

try {
await window.sharedStorage.set('a', 'b');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

try {
await window.sharedStorage.append('a', 'b');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

try {
await window.sharedStorage.clear();
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

try {
await window.sharedStorage.delete('a');
} catch (e) {
assert_equals(e.message, errorMessage);
++permissionsPolicyDeniedCount;
}

if (permissionsPolicyDeniedCount === 0)
return true;

return false;
}

0 comments on commit af5e7ca

Please sign in to comment.