Commit a14d168b authored by Luna Lu's avatar Luna Lu Committed by Commit Bot

Reland "Add WPT tests for feature policy"

This is a reland of 6252427a.

Original change's description:
> Add WPT tests for feature policy
> 
> 1. Added tests for header policy.
>     a. document.policy shows correctly parsed policy
>     b. local / remote iframes without allow attribute correctly inherit
>        document.policy
>     c. dynamically update allow attribute updates the policy correctly.
> 
> 2. Added tests for nested policies.
> 
> Bug: 732003
> Change-Id: I869449f6bba89fc58997355df27249f403d76808
> Reviewed-on: https://chromium-review.googlesource.com/796952
> Commit-Queue: Luna Lu <loonybear@chromium.org>
> Reviewed-by: Ian Clelland <iclelland@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#531698}

Bug: 732003
Change-Id: I46065efff8c5af2d5279721f3c759580b0807e05
Reviewed-on: https://chromium-review.googlesource.com/887324Reviewed-by: default avatarIan Clelland <iclelland@chromium.org>
Commit-Queue: Luna Lu <loonybear@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538904}
parent cc1712d6
...@@ -99,6 +99,11 @@ crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-none ...@@ -99,6 +99,11 @@ crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-none
crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js [ Timeout ] crbug.com/623268 http/tests/inspector-protocol/request-mixed-content-status-optionally-blockable.js [ Timeout ]
crbug.com/623268 http/tests/devtools/console-cross-origin-iframe-logging.js [ Timeout ] crbug.com/623268 http/tests/devtools/console-cross-origin-iframe-logging.js [ Timeout ]
# https://crbug.com/814887 - Feature policy is not replicated correctly.
crbug.com/814887 external/wpt/feature-policy/feature-policy-header-policy-allowed-for-all.https.sub.html [ Failure ]
crbug.com/814887 external/wpt/feature-policy/feature-policy-nested-header-policy-allowed-for-all.https.sub.html [ Failure ]
crbug.com/814887 virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-nested-header-policy-allowed-for-all.https.sub.html [ Failure ]
# https://crbug.com/645641 - test_runner.cc(1863) Check failed: # https://crbug.com/645641 - test_runner.cc(1863) Check failed:
# layout_test_runtime_flags_.have_top_loading_frame() # layout_test_runtime_flags_.have_top_loading_frame()
crbug.com/645641 external/wpt/html/syntax/parsing/html5lib_tests19.html [ Crash Failure ] crbug.com/645641 external/wpt/html/syntax/parsing/html5lib_tests19.html [ Crash Failure ]
......
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<!-- Feature-Policy: fullscreen *; -->
<script>
'use strict';
var same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
var cross_origin_src = cross_origin + same_origin_src;
var header_policy = 'Feature-Policy: fullscreen *';
// Test that fullscreen's allowlist is ['*']
test(function() {
assert_array_equals(
document.policy.getAllowlistForFeature('fullscreen'),
['*']);
}, header_policy + ' -- test allowlist is ['*']');
// Test that fullscreen is allowed on all subframes.
test_allowed_feature_for_subframe(
header_policy + ' -- test fullscreen is allowed on same-origin subframe',
'fullscreen',
same_origin_src);
test_allowed_feature_for_subframe(
header_policy + ' -- test fullscreen is allowed on cross-origin subframe',
'fullscreen',
cross_origin_src);
// Dynamically update sub frame's container policy
var allow = "fullscreen 'self';"
test_allowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is allowed on same-origin subframe',
'fullscreen',
same_origin_src,
allow);
test_disallowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is disallowed on cross-origin subframe',
'fullscreen',
cross_origin_src,
allow);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<!-- Feature-Policy: fullscreen 'self'; -->
<script>
'use strict';
var same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
var cross_origin_src = cross_origin + same_origin_src;
var header_policy = 'Feature-Policy: fullscreen \'self\'';
// Test that fullscreen's allowlist is ['same_origin']
test(function() {
assert_array_equals(
document.policy.getAllowlistForFeature('fullscreen'),
[same_origin]);
}, header_policy + ' -- test allowlist is [same_origin]');
// Test that fullscreen is only allowed on same-origin subframe.
test_allowed_feature_for_subframe(
header_policy + ' -- test fullscreen is allowed on same-origin subframe',
'fullscreen',
same_origin_src);
test_disallowed_feature_for_subframe(
header_policy + ' -- test fullscreen is disallowed on cross-origin subframe',
'fullscreen',
cross_origin_src);
// Dynamically update sub frame's container policy
var allow = "fullscreen 'src';"
test_allowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is allowed on same-origin subframe',
'fullscreen',
same_origin_src,
allow);
test_allowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is allowed on cross-origin subframe',
'fullscreen',
same_origin_src,
allow);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<!-- Feature-Policy: fullscreen 'self' cross_origin https://www.example.com; -->
<script>
'use strict';
var same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
var cross_origin_src = cross_origin + same_origin_src;
var header_policy = 'Feature-Policy: fullscreen \'self\' ' + cross_origin +
' https://www.example.com;';
// Test that fullscreen's allowlist is [same_origin, cross_origin, 'https://www.example.com']
test(function() {
assert_array_equals(
document.policy.getAllowlistForFeature('fullscreen'),
[same_origin, cross_origin, 'https://www.example.com']);
}, header_policy + ' -- test allowlist is [same_origin, cross_origin, https://www.example.com]');
// Test that fullscreen is allowed on same_origin, some cross_origin subframes.
test_allowed_feature_for_subframe(
header_policy + ' -- test fullscreen is allowed on same-origin subframe',
'fullscreen',
same_origin_src);
test_allowed_feature_for_subframe(
header_policy + ' -- test fullscreen is allowed on cross-origin ' + cross_origin_src + ' subframe',
'fullscreen',
cross_origin_src);
var cross_origin_src1 = 'https://{{domains[www1]}}:{{ports[https][0]}}' + same_origin_src;
test_disallowed_feature_for_subframe(
header_policy + ' -- test fullscreen is disallowed on cross-origin ' + cross_origin_src1 + ' subframe',
'fullscreen',
cross_origin_src1);
// dynamically update sub frame's container policy
var allow = "fullscreen 'none';"
test_disallowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is disallowed on same-origin subframe',
'fullscreen',
same_origin_src,
allow);
test_disallowed_feature_for_subframe(
header_policy + 'iframe.allow = ' + allow + ' -- test fullscreen is disallowed on cross-origin subframe',
'fullscreen',
cross_origin_src,
allow);
</script>
</body>
Feature-Policy: fullscreen 'self' https://{{domains[www]}}:{{ports[https][0]}} https://www.example.com;
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<!-- Feature-Policy: fullscreen 'none'; -->
<script>
'use strict';
var same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
var cross_origin_src = cross_origin + same_origin_src;
var header_policy = 'Feature-Policy: fullscreen \'none\'';
// Test that fullscreen's allowlist is []
test(function() {
assert_array_equals(
document.policy.getAllowlistForFeature('fullscreen'),
[]);
}, header_policy + ' -- test allowlist is []');
// Test that fullscreen is disallowed on all subframes.
test_disallowed_feature_for_subframe(
header_policy + ' -- test fullscreen is disallowed on same-origin subframe',
'fullscreen',
same_origin_src);
test_disallowed_feature_for_subframe(
header_policy + ' -- test fullscreen is disallowed on cross-origin subframe',
'fullscreen',
cross_origin_src);
// Dynamically update sub frame's container policy
var allow = "fullscreen 'src';"
test_disallowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is disallowed on same-origin subframe',
'fullscreen',
same_origin_src,
allow);
test_disallowed_feature_for_subframe(
header_policy + ', iframe.allow = ' + allow + ' -- test fullscreen is disallowed on cross-origin subframe',
'fullscreen',
cross_origin_src,
allow);
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
/*
fullscreen is allowed for all at the top-level document. It can be disabled by
subframes.
*/
'use strict';
const same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
const cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const same_origin_src = '/feature-policy/resources/feature-policy-nested-subframe-policy.https.sub.html';
const cross_origin_src = cross_origin + same_origin_src;
/* ------------------------------------------
| top-level document |
| ------------------------------------ |
| | same-origin iframe | |
| | ------------------------------ | |
| | | local and remote iframes | | |
| | ------------------------------ | |
| ------------------------------------ |
------------------------------------------ */
test_subframe_header_policy('fullscreen', '*', same_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: true, remote_self: true, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen *"');
test_subframe_header_policy('fullscreen', '\'self\'', same_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen \'self\'"');
test_subframe_header_policy('fullscreen', '\'none\'', same_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen \'none\'"');
/* -------------------------------------------
| top-level document |
| ------------------------------------- |
| | cross-origin iframe | |
| | ------------------------------- | |
| | | local and remote iframes | | |
| | ------------------------------- | |
| ------------------------------------- |
------------------------------------------- */
test_subframe_header_policy('fullscreen', '*', cross_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: true, remote_self: true, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen *"');
test_subframe_header_policy('fullscreen', '\'self\'', cross_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen \'self\'"');
test_subframe_header_policy('fullscreen', '\'none\'', cross_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen \'none\'"');
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
/*
fullscreen is allowed for 'self' at the top-level document and through the
chain of same-origin iframes. It can be enabled by subframes, but otherwise
is disallowed everywhere else.
*/
'use strict';
const same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
const cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const same_origin_src = '/feature-policy/resources/feature-policy-nested-subframe-policy.https.sub.html';
const cross_origin_src = cross_origin + same_origin_src;
/* ------------------------------------------
| top-level document |
| ------------------------------------ |
| | same-origin iframe | |
| | ------------------------------ | |
| | | local and remote iframes | | |
| | ------------------------------ | |
| ------------------------------------ |
------------------------------------------ */
test_subframe_header_policy('fullscreen', '*', same_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: true, remote_self: true, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen *"');
test_subframe_header_policy('fullscreen', '\'self\'', same_origin_src,
{local_all: true, local_self: true, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen \'self\'"');
test_subframe_header_policy('fullscreen', '\'none\'', same_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen \'none\'"');
/* -------------------------------------------
| top-level document |
| ------------------------------------- |
| | cross-origin iframe | |
| | ------------------------------- | |
| | | local and remote iframes | | |
| | ------------------------------- | |
| ------------------------------------- |
------------------------------------------- */
test_subframe_header_policy('fullscreen', '*', cross_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen *"');
test_subframe_header_policy('fullscreen', '\'self\'', cross_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen \'self\'"');
test_subframe_header_policy('fullscreen', '\'none\'', cross_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen \'none\'"');
</script>
</body>
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
/*
fullscreen is disabled at the top-level document, therefore disabled
everywhere throughout inheritance.
*/
'use strict';
const same_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
const cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
const same_origin_src = '/feature-policy/resources/feature-policy-nested-subframe-policy.https.sub.html';
const cross_origin_src = cross_origin + same_origin_src;
const policies = ['*', '\'self\'', '\'none\''];
for (var i = 0; i < policies.length; i++) {
/* ------------------------------------------
| top-level document |
| ------------------------------------ |
| | same-origin iframe | |
| | ------------------------------ | |
| | | local and remote iframes | | |
| | ------------------------------ | |
| ------------------------------------ |
------------------------------------------ */
test_subframe_header_policy('fullscreen', policies[i], same_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with local iframe on policy "fullscreen '
+ policies[i] + '".');
/* -------------------------------------------
| top-level document |
| ------------------------------------- |
| | cross-origin iframe | |
| | ------------------------------- | |
| | | local and remote iframes | | |
| | ------------------------------- | |
| ------------------------------------- |
------------------------------------------- */
test_subframe_header_policy('fullscreen', policies[i], cross_origin_src,
{local_all: false, local_self: false, local_none: false,
remote_all: false, remote_self: false, remote_none: false},
'Test nested header policy with remote iframe on policy "fullscreen '
+ policies[i] + '".');
}
</script>
</body>
<script>
'use strict';
window.onload = function() {
parent.postMessage(document.policy.allowedFeatures(), '*');
}
</script>
<!DOCTYPE html>
<body>
<script>
'use strict';
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
var cross_origin_src = 'https://{{domains[www1]}}:{{ports[https][0]}}' + same_origin_src;
var subframe_header_policy = '?pipe=header(Feature-Policy, fullscreen ';
var policy_all = '*';
var policy_self = '\'self\'';
var policy_none = '\'none\'';
let local_frame_all = document.createElement('iframe');
let local_frame_self = document.createElement('iframe');
let local_frame_none = document.createElement('iframe');
local_frame_all.src = same_origin_src + subframe_header_policy + policy_all + ';)';
local_frame_self.src = same_origin_src + subframe_header_policy + policy_self + ';)';
local_frame_none.src = same_origin_src + subframe_header_policy + policy_none + ';)';
let remote_frame_all = document.createElement('iframe');
let remote_frame_self = document.createElement('iframe');
let remote_frame_none = document.createElement('iframe');
remote_frame_all.src = cross_origin_src + subframe_header_policy + policy_all + ';)';
remote_frame_self.src = cross_origin_src + subframe_header_policy + policy_self + ';)';
remote_frame_none.src = cross_origin_src + subframe_header_policy + policy_none + ';)';
window.addEventListener('message', function(evt) {
if (evt.source === local_frame_all.contentWindow) {
parent.postMessage({frame: 'local', policy: policy_all, allowedfeatures: evt.data}, '*');
} else if (evt.source === local_frame_self.contentWindow) {
parent.postMessage({frame: 'local', policy: policy_self, allowedfeatures: evt.data}, '*');
} else if (evt.source === local_frame_none.contentWindow) {
parent.postMessage({frame: 'local', policy: policy_none, allowedfeatures: evt.data}, '*');
} else if (evt.source === remote_frame_all.contentWindow) {
parent.postMessage({frame: 'remote', policy: policy_all, allowedfeatures: evt.data}, '*');
} else if (evt.source === remote_frame_self.contentWindow) {
parent.postMessage({frame: 'remote', policy: policy_self, allowedfeatures: evt.data}, '*');
} else if (evt.source === remote_frame_none.contentWindow) {
parent.postMessage({frame: 'remote', policy: policy_none, allowedfeatures: evt.data}, '*');
}
});
document.body.appendChild(local_frame_all);
document.body.appendChild(local_frame_self);
document.body.appendChild(local_frame_none);
document.body.appendChild(remote_frame_all);
document.body.appendChild(remote_frame_self);
document.body.appendChild(remote_frame_none);
</script>
</body>
...@@ -247,3 +247,139 @@ function run_all_fp_tests_allow_all( ...@@ -247,3 +247,139 @@ function run_all_fp_tests_allow_all(
'Feature policy "' + feature_name + 'Feature policy "' + feature_name +
'" can be disabled in cross-origin iframes using "allow" attribute.'); '" can be disabled in cross-origin iframes using "allow" attribute.');
} }
// This function tests that a given policy allows each feature for the correct
// list of origins specified by the |expected_policy|.
// Arguments:
// expected_policy: A list of {feature, allowlist} pairs where the feature is
// enabled for every origin in the allowlist, in the |policy|.
// policy: Either a document.policy or a iframe.policy to be tested.
// message: A short description of what policy is being tested.
function test_allowlists(expected_policy, policy, message) {
for (var allowlist of allowlists) {
test(function() {
assert_array_equals(
policy.getAllowlistForFeature(allowlist.feature),
allowlist.allowlist);
}, message + ' for feature ' + allowlist.feature);
}
}
// This function tests that a subframe's document policy allows a given feature.
// A feature is allowed in a frame either through inherited policy or specified
// by iframe allow attribute.
// Arguments:
// test: test created by testharness. Examples: async_test, promise_test.
// feature: feature name that should be allowed in the frame.
// src: the URL to load in the frame.
// allow: the allow attribute (container policy) of the iframe
function test_allowed_feature_for_subframe(message, feature, src, allow) {
let frame = document.createElement('iframe');
if (typeof allow !== 'undefined') {
frame.allow = allow;
}
promise_test(function() {
frame.src = src;
return new Promise(function(resolve, reject) {
window.addEventListener('message', function handler(evt) {
resolve(evt.data);
}, { once: true });
document.body.appendChild(frame);
}).then(function(data) {
assert_true(data.includes(feature), feature);
});
}, message);
}
// This function tests that a subframe's document policy disallows a given
// feature. A feature is allowed in a frame either through inherited policy or
// specified by iframe allow attribute.
// Arguments:
// test: test created by testharness. Examples: async_test, promise_test.
// feature: feature name that should not be allowed in the frame.
// src: the URL to load in the frame.
// allow: the allow attribute (container policy) of the iframe
function test_disallowed_feature_for_subframe(message, feature, src, allow) {
let frame = document.createElement('iframe');
if (typeof allow !== 'undefined') {
frame.allow = allow;
}
promise_test(function() {
frame.src = src;
return new Promise(function(resolve, reject) {
window.addEventListener('message', function handler(evt) {
resolve(evt.data);
}, { once: true });
document.body.appendChild(frame);
}).then(function(data) {
assert_false(data.includes(feature), feature);
});
}, message);
}
// This function tests that a subframe with header policy defined on a given
// feature allows and disallows the feature as expected.
// Arguments:
// feature: feature name.
// frame_header_policy: either *, 'self' or 'none', defines the frame
// document's header policy on |feature|.
// src: the URL to load in the frame.
// test_expects: contains 6 expected results of either |feature| is allowed
// or not inside of a local or remote iframe nested inside
// the subframe given the header policy to be either *,
// 'slef', or 'none'.
// test_name: name of the test.
function test_subframe_header_policy(
feature, frame_header_policy, src, test_expects, test_name) {
let frame = document.createElement('iframe');
promise_test(function() {
frame.src = src + '?pipe=sub|header(Feature-Policy,' + feature + ' '
+ frame_header_policy + ';)';
return new Promise(function(resolve, reject) {
let results = [];
window.addEventListener('message', function handler(evt) {
results.push(evt.data);
if (results.length >= 6) {
resolve(results);
}
});
document.body.appendChild(frame);
}).then(function(results) {
for (var j = 0; j < results.length; j++) {
var data = results[j];
function test_result(message, test_expect) {
if (test_expect) {
assert_true(data.allowedfeatures.includes(feature), message);
} else {
assert_false(data.allowedfeatures.includes(feature), message);
}
}
if (data.frame === 'local') {
if (data.policy === '*') {
test_result('local_all:', test_expects.local_all);
}
if (data.policy === '\'self\'') {
test_result('local_self:', test_expects.local_self);
}
if (data.policy === '\'none\'') {
test_result('local_none:', test_expects.local_none);
}
}
if (data.frame === 'remote') {
if (data.policy === '*') {
test_result('remote_all:', test_expects.remote_all);
}
if (data.policy === '\'self\'') {
test_result('remote_self:', test_expects.remote_self);
}
if (data.policy === '\'none\'') {
test_result('remote_none:', test_expects.remote_none);
}
}
}
});
}, test_name);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment