| <!DOCTYPE html> | |
| <meta name=timeout content=long> | |
| <title>Test of sandbox mandatory flags</title> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="resources/utils.js"></script> | |
| <script src="/common/utils.js"></script> | |
| <script src="/common/dispatcher/dispatcher.js"></script> | |
| <body> | |
| <script> | |
| const mandatory_flags = [ | |
| 'allow-same-origin', | |
| 'allow-forms', | |
| 'allow-scripts', | |
| 'allow-popups', | |
| 'allow-popups-to-escape-sandbox', | |
| 'allow-top-navigation-by-user-activation']; | |
| promise_test(async t => { | |
| const key = token(); | |
| const value = 'fenced frame loaded'; | |
| const iframe = document.createElement('iframe'); | |
| iframe.src = | |
| 'resources/sandbox-mandatory-flags-iframe.sub.html?key=' + key + | |
| '&value=' + value; | |
| mandatory_flags.forEach(flag => { | |
| iframe.sandbox.add(flag); | |
| }); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => { | |
| iframe.remove(); | |
| }); | |
| const result = await nextValueFromServer(key); | |
| assert_equals(result, value, 'The fenced frame must be loaded.'); | |
| }, 'Sandboxed Iframe with mandatory flags can load a fenced frame.'); | |
| promise_test(async t => { | |
| const key = token(); | |
| // Try to load a fenced frame in a sandboxed iframe like this: | |
| // <iframe sandbox="|mandatory_flags| without |missing_flag|" | |
| // src="sandbox-mandatory-flags-iframe.sub.html"> | |
| // <fencedframe src="sandbox-mandatory-flags-inner.sub.html"> | |
| // <img src="key-value-store.py?key=|key|&value=|value|"> | |
| // <fencedframe> | |
| // </iframe> | |
| // But this should fail because the sandboxed iframe is loaded without | |
| // |missing_flag|. | |
| for (let missing_flag of mandatory_flags) { | |
| const value = | |
| 'a fenced frame was loaded in a sandboxed iframe without ' + | |
| missing_flag + '.'; | |
| const iframe = document.createElement('iframe'); | |
| iframe.src = | |
| 'resources/sandbox-mandatory-flags-iframe.sub.html?key=' + key + | |
| '&value=' + value; | |
| mandatory_flags.forEach(flag => { | |
| if (flag != missing_flag) { | |
| iframe.sandbox.add(flag); | |
| } | |
| }); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => { | |
| iframe.remove(); | |
| }); | |
| } | |
| t.step_timeout(() => t.done(), 3000); | |
| let server_value = await nextValueFromServer(key); | |
| assert_unreached('fenced frame should not be loaded, but ' + server_value); | |
| }, 'Sandboxed Iframe without one of mandatory flag must fail to load a fenced' + | |
| ' frame.'); | |
| promise_test(async t => { | |
| const key = token(); | |
| // Try to load a fenced frame in a nested sandboxed iframe like this: | |
| // <iframe sandbox="|mandatory_flags| without |missing_flag|" | |
| // src="sandbox-mandatory-flags-looser-restriction.sub.html"> | |
| // <iframe sandbox="|mandatory_flags|" | |
| // src="sandbox-mandatory-flags-iframe.sub.html"> | |
| // <fencedframe src="resources/sandbox-mandatory-flags-inner.sub.html"> | |
| // <img src="key-value-store.py?key=|key|&value=|value|"> | |
| // <fencedframe> | |
| // </iframe> | |
| // </iframe> | |
| // But this should fail because the nested iframe is loaded sandboxed | |
| // without |missing_flag|. | |
| for (let missing_flag of mandatory_flags) { | |
| const value = | |
| 'a fenced frame was loaded in a nested sandboxed iframe without ' + | |
| missing_flag + '.'; | |
| const iframe = document.createElement('iframe'); | |
| iframe.src = | |
| 'resources/sandbox-mandatory-flags-looser-restriction.sub.html?key=' + | |
| key + '&value=' + value; | |
| mandatory_flags.forEach(flag => { | |
| if (flag != missing_flag) { | |
| iframe.sandbox.add(flag); | |
| } | |
| }); | |
| document.body.appendChild(iframe); | |
| t.add_cleanup(() => { | |
| iframe.remove(); | |
| }); | |
| } | |
| t.step_timeout(() => t.done(), 3000); | |
| let server_value = await nextValueFromServer(key); | |
| assert_unreached('fenced frame should not be loaded, but ' + server_value); | |
| }, 'Nested sandboxed iframe without one of mandatory flag must fail to load a' + | |
| 'fenced frame even when the inner nested sandboxed iframe has all ' + | |
| 'mandatory allow- flags.'); | |
| promise_test(async t => { | |
| const key = token(); | |
| // allow-scripts is needed to run iframe.execute, so we will test every other | |
| // sandbox flag | |
| for (let missing_flag of | |
| mandatory_flags.filter(word => word != "allow-scripts")) { | |
| const value = | |
| 'canLoadOpaqueURL returned true even with flag ' + | |
| missing_flag + ' not set.'; | |
| const flags_to_add = mandatory_flags | |
| .filter(word => word != missing_flag) | |
| .join(" "); | |
| const iframe = attachIFrameContext( | |
| {attributes: [["sandbox", flags_to_add]]}); | |
| await iframe.execute(async (t) => { | |
| assert_false(navigator.canLoadAdAuctionFencedFrame()); | |
| }); | |
| } | |
| }, 'navigator.canLoadAdAuctionFencedFrame considers mandatory sandbox flags'); | |
| </script> | |
| </body> |