Skip to content

Commit

Permalink
Add WPT tests for feature policy frame policy
Browse files Browse the repository at this point in the history
1. Without specifying allow attribute, frame policy inherits correctly.
2. With allow attribute, frame policy inherits from and overrides header policy
   correctly. Updating allowfullscreen and allowpaymentrequest correctly updates
   frame policy.
3. Frame policy is not affected by the frame's document policy.

Bug: 732003
Change-Id: Ib41f883a779f11c564c91cfc03ff1224330108f5
  • Loading branch information
loonybear authored and chromium-wpt-export-bot committed Jan 4, 2018
1 parent be5419e commit 09214c7
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 0 deletions.
68 changes: 68 additions & 0 deletions feature-policy/feature-policy-frame-policy.https.sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
var local_origin = 'https://{{domains[]}}:{{ports[https][0]}}';
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
var src = '/feature-policy/resources/feature-policy-frame-policy.html';
var src1 = '/feature-policy/resources/feature-policy-frame-policy-with-headers.https.sub.html';

// Withouth iframe allow attribute, frame.policy will inherit from header policy.
test(function() {
test_frame_policy(
['usb', 'speaker', 'camera', 'geolocation', 'fullscreen', 'payment'],
['midi'],
local_origin + src);
}, 'Test frame.policy on local iframe without allow attribute');
test(function() {
test_frame_policy(
['usb', 'camera'],
// speaker, geolocation, fullscreen and payment are allowed for self.
['midi', 'speaker', 'geolocation', 'fullscreen', 'payment'],
cross_origin + src);
}, 'Test frame.policy on remote iframe without allow attribute');

// With allow attribute:
// - midi is disabled by parents, cannot be enabled in subframes.
// - geolocation is not disabled by parents, can be enabled for subframes.
// - usb is enabled by parents, but disabled by subframes.
// - allowfullscreen overrides parent policy, fullscreen is allowed for subframes.
// - allowpaymentrequest overrides parent policy, but is overriden by allow attribute.
var allow = "midi *; geolocation 'src'; usb 'none'; payment 'self';";
test(function() {
test_frame_policy(
['speaker', 'camera', 'geolocation', 'fullscreen', 'payment'],
['usb', 'midi'],
local_origin + src,
allow, true, true);
}, 'Test frame.policy on local iframe with allow attribute');
test(function() {
test_frame_policy(
['camera', 'geolocation', 'fullscreen'],
['speaker', 'usb', 'midi', 'payment'],
cross_origin + src,
allow, true, true);
}, 'Test frame.policy on remote iframe with allow attribute');

// However, if header policy is set for the subframe documents, frame.policy does not get affected.
// Subframe header policy:
// Feature-Policy: camera 'none'; fullscreen 'none'; payment 'none';
test(function() {
test_frame_policy(
['speaker', 'camera', 'geolocation', 'fullscreen', 'payment'],
['usb', 'midi'],
local_origin + src1,
allow, true, true);
}, 'Test frame.policy on local iframe with allow attribute and header policy');
test(function() {
test_frame_policy(
['camera', 'geolocation', 'fullscreen'],
['speaker', 'usb', 'midi', 'payment'],
cross_origin + src1,
allow, true, true);
}, 'Test frame.policy on remote iframe with allow attribute and header policy');
</script>
</body>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Feature-Policy: usb *; speaker 'self'; midi 'none'; camera 'self' https://{{domains[www]}}:{{ports[https][0]}} https://www.example.com; geolocation 'self'; fullscreen 'self'; payment 'self';
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<p>Test frame policy</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Feature-Policy: camera 'none'; fullscreen 'none'; payment 'none';
2 changes: 2 additions & 0 deletions feature-policy/resources/feature-policy-frame-policy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<p>Test frame policy</p>
98 changes: 98 additions & 0 deletions feature-policy/resources/featurepolicy.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,101 @@ function run_all_fp_tests_allow_all(
'Feature policy "' + feature_name +
'" 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 |allowlists|.
// Arguments:
// allowlists: 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(allowlists, policy, message) {
for (var allowlist of allowlists) {
test(function() {
assert_array_equals(
policy.getAllowlistForFeature(allowlist.feature),
allowlist.whitelist);
}, message + ' for feature ' + allowlist.feature);
}
}

// This function tests that a frame's policy allows and disallows features
// correctly. 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.
// allowed_features: A list of features that should be allowed in the frame.
// disallowed_features: A list of features that should be disallowed in the
// frame.
// src: the URL to load in the frame.
// allow: the allow attribute (container policy) of the iframe.
function test_allowed_features_for_subframe(
test, allowed_features, disallowed_features, src, allow) {
let frame = document.createElement('iframe');
if (typeof allow !== 'undefined') {
frame.allow = allow;
}
frame.src = src;

window.addEventListener('message', test.step_func(function handler(evt) {
if (evt.source === frame.contentWindow) {
for (var feature of allowed_features) {
assert_true(evt.data.includes(feature), feature, feature + " is allowed");
}
for (var feature of disallowed_features) {
assert_false(evt.data.includes(feature), feature, feature + " is not allowed");
}
window.removeEventListener('message', handler);
test.done();
}
}));

document.body.appendChild(frame);
}

// This function tests that a frame.policy allows and disallows features
// correctly. A feature is allowed in a frame either through inherited policy or
// specified by iframe allow attribute.
// Arguments:
// allowed_features: A list of features that should be allowed by
// frame.policy
// disallowed_features: A list of features that should be disallowed by
// frame.policy
// src: the URL to load in the frame.
// allow: the allow attribute (container policy) of the iframe.
// allowfullscreen: boolean value of allowfullscreen attribute.
// allowpayment: boolean value of allowpaymentrequest attribute.

function test_frame_policy(
allowed_features, disallowed_features, src, allow, allowfullscreen, allowpayment) {
let frame = document.createElement('iframe');
document.body.appendChild(frame);
var frame_policy_features = frame.policy.allowedFeatures();
var frame_policy = frame.policy;
if (typeof allow !== 'undefined') {
frame.allow = allow;
// Dynamically update allow attribute update frame.policy
assert_not_equals(frame_policy_features, frame_policy.allowedFeatures(),
'Updating allow updates frame.policy');
}
if (typeof allowfullscreen !== 'undefined') {
frame.setAttribute('allowfullscreen', allowfullscreen);
// Dynamically update allow attribute update frame.policy
assert_not_equals(frame_policy_features, frame_policy.allowedFeatures(),
'Updating allowfullscreen updates frame.policy');
}
if (typeof allowpaymentrequestned !== 'undefined') {
frame.setAttribute('allowpaymentrequest', allowpayment);
// Dynamically update allow attribute update frame.policy
assert_not_equals(frame_policy_features, frame_policy.allowedFeatures(),
'Updating allowfullscreen updates frame.policy');
}
frame.src = src;

for (var feature of allowed_features) {
assert_true(frame_policy.allowsFeature(feature), feature + " is allowed");
}
for (var feature of disallowed_features) {
assert_false(frame_policy.allowsFeature(feature), feature + " is not allowed");
}
}

0 comments on commit 09214c7

Please sign in to comment.