tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

createcredential-cross-origin-iframe.https.sub.html (4684B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>WebAuthn credential.create() in a cross-origin iframe tests</title>
      4 <meta name="timeout" content="long">
      5 <link rel="help" href="https://w3c.github.io/webauthn/#publickey-credentials-create-feature">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="/resources/testdriver.js"></script>
      9 <script src="/resources/testdriver-vendor.js"></script>
     10 <script src=helpers.js></script>
     11 <body></body>
     12 <script>
     13 standardSetup(function() {
     14    "use strict";
     15 
     16    const targetOrigin = "https://{{hosts[alt][www]}}:{{ports[https][0]}}";
     17 
     18    // Returns a |Promise| that gets resolved with |event.data| when |window|
     19    // receives a "message" event whose |event.data.type| matches the string
     20    // |message_data_type|.
     21    function getMessageData(message_data_type) {
     22        return new Promise(resolve => {
     23            function waitAndRemove(e) {
     24                if (!e.data || e.data.type != message_data_type)
     25                    return;
     26                window.removeEventListener("message", waitAndRemove);
     27                resolve(e.data);
     28            }
     29            window.addEventListener("message", waitAndRemove);
     30        });
     31    }
     32 
     33    // Creates an iframe with the given `src` and (optional) allow attribute.
     34    // Waits for the iframe to load, based on receiving a "subframe-loaded"
     35    // message from the iframe.
     36    async function createIframe(test, src, allow) {
     37        const iframeElement = document.createElement("iframe");
     38        document.body.appendChild(iframeElement);
     39        test.add_cleanup(() => {
     40            iframeElement.remove();
     41        });
     42 
     43        if (allow !== undefined) {
     44          iframeElement.allow = allow;
     45        }
     46 
     47        const loadedPromise = getMessageData("subframe-loaded");
     48        iframeElement.src = src;
     49        await loadedPromise;
     50 
     51        return iframeElement;
     52    }
     53 
     54    promise_test(async (test) => {
     55        const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`;
     56        const iframe = await createIframe(test, src);
     57 
     58        const resultPromise = getMessageData("result");
     59        iframe.contentWindow.postMessage({type: "create-credential"}, {targetOrigin: targetOrigin});
     60        const data = await resultPromise;
     61 
     62        assert_equals(data.result, "failure");
     63        assert_equals(data.error.name, "NotAllowedError");
     64    }, "create() in cross-origin iframe fails without permissions policy");
     65 
     66    promise_test(async (test) => {
     67        const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`;
     68        const iframe = await createIframe(test, src, "publickey-credentials-create");
     69 
     70        const resultPromise = getMessageData("result");
     71        iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: false}, {targetOrigin: targetOrigin});
     72        const data = await resultPromise;
     73 
     74        assert_equals(data.result, "failure");
     75        assert_equals(data.error.name, "NotAllowedError");
     76    }, "create() in cross-origin iframe fails with permissions policy but no user activation");
     77 
     78    promise_test(async (test) => {
     79        const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`;
     80        const iframe = await createIframe(test, src, "publickey-credentials-create");
     81 
     82        const resultPromise = getMessageData("result");
     83        iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: true}, {targetOrigin: targetOrigin});
     84        const data = await resultPromise;
     85 
     86        assert_equals(data.result, "success", `Expected success but got error: "${data.errorMessage}"`);
     87    }, "create() in cross-origin iframe succeeds with permissions policy and user activation");
     88 
     89    promise_test(async (test) => {
     90        const src = `${targetOrigin}/webauthn/resources/webauthn-subframe.sub.html`;
     91        const iframe = await createIframe(test, src, "publickey-credentials-create");
     92 
     93        // For this call, we have a user activation in this main frame, but not
     94        // in the iframe. That shouldn't be sufficient - the user activation has
     95        // to be on the iframe itself.
     96        await test_driver.bless("create credential, main frame activation");
     97        const resultPromise = getMessageData("result");
     98        iframe.contentWindow.postMessage({type: "create-credential", addUserActivation: false}, {targetOrigin: targetOrigin});
     99        const data = await resultPromise;
    100 
    101        assert_equals(data.result, "failure");
    102        assert_equals(data.error.name, "NotAllowedError");
    103    }, "create() in cross-origin iframe requires user activation on the iframe, not the main frame");
    104 });
    105 </script>