| <!DOCTYPE html> |
| <!-- This test should be upstreamed to WPT but it was difficult to do so, see |
| https://codereview.chromium.org/2869093002/ --> |
| <meta charset="utf-8"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/resources/get-host-info.js?pipe=sub"></script> |
| <script src="resources/test-helpers.js"></script> |
| <title>Insecure parent frame test</title> |
| <body></body> |
| <script> |
| // Asks |worker| to call clients.claim. Returns a promise that resolves when |
| // the worker acks that claim finished. |
| function wait_for_claim(worker) { |
| var saw_message = new Promise(resolve => { |
| var channel = new MessageChannel(); |
| channel.port1.onmessage = (e => resolve(e.data)); |
| worker.postMessage({port: channel.port2}, [channel.port2]); |
| }); |
| |
| return saw_message.then(data => { |
| assert_equals(data, 'PASS', 'claim should finish'); |
| }); |
| } |
| |
| // Asks |frame| whether it has a controller. Returns a promise that resolves |
| // if controller was null. |
| function assert_no_controller(frame, description) { |
| var saw_message = new Promise(resolve => { |
| window.onmessage = (e => resolve(e.data)); |
| frame.contentWindow.postMessage('', '*'); |
| }); |
| |
| return saw_message.then(data => assert_equals(data, 'PASS', description)); |
| } |
| |
| // This test creates https iframes inside insecure http iframes. It registers a |
| // service worker that should not control the in-scope iframes. The iframes |
| // communicate whether they have a controller to the top-level frame. |
| promise_test(t => { |
| var script = 'resources/claim-worker.js'; |
| var scope = 'resources/insecure-inscope'; |
| var registration; |
| var insecure_url = get_host_info().UNAUTHENTICATED_ORIGIN + |
| '/serviceworker/resources/insecure-parent.html'; |
| var pre_registration_frame; |
| var post_registration_frame; |
| |
| return navigator.serviceWorker.getRegistration(scope) |
| // Unregister. |
| .then(reg => { |
| if (reg) |
| return reg.unregister(); |
| }) |
| |
| // Create an iframe prior to registration. |
| .then(() => with_iframe(insecure_url)) |
| |
| // Register. |
| .then(frame => { |
| pre_registration_frame = frame; |
| add_result_callback(() => pre_registration_frame.remove()); |
| return navigator.serviceWorker.register(script, {scope:scope}); |
| }) |
| .then(reg => { |
| registration = reg; |
| return wait_for_state(t, registration.installing, 'activated'); |
| }) |
| |
| // Create an iframe after registration. |
| .then(() => with_iframe(insecure_url)) |
| .then(frame => post_registration_frame = frame) |
| |
| // Check that no frame is controlled. |
| .then(() => assert_no_controller(pre_registration_frame, |
| 'pre_registration_frame should not be controlled')) |
| .then(() => assert_no_controller(post_registration_frame, |
| 'post_registration_frame should not be controlled')) |
| |
| // Attempt to claim. The iframes should still have no controllers. |
| .then(() => wait_for_claim(registration.active)) |
| .then(() => assert_no_controller(pre_registration_frame, |
| 'pre_registration_frame should not be claimed')) |
| .then(() => assert_no_controller(post_registration_frame, |
| 'post_registration_frame should not be claimed')); |
| }, 'Service worker does not control a subframe of an insecure frame'); |
| </script> |