tor-browser

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

getcredential-nested-frame.https.html (4336B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>WebAuthn credential.get() in a nested frame</title>
      4 <link rel="help" href="https://w3c.github.io/webauthn/#publickey-credentials-create-feature">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="/resources/testdriver.js"></script>
      8 <script src="/resources/testdriver-vendor.js"></script>
      9 <script src="/resources/common-inputs.js"></script>
     10 <script src=helpers.js></script>
     11 
     12 <body></body>
     13 <script>
     14 
     15  standardSetup(async function () {
     16    "use strict";
     17 
     18    let credential;
     19    function getCredentialScript() {
     20      // Convert the credential ID into a string that can be safely embedded
     21      // into our get assertion script.
     22      // First, turn the buffer into a byte string.
     23      const idBytes = String.fromCharCode(...new Uint8Array(credential.rawId));
     24      // Then, encode it into base64 so it can be safely embedded as a string.
     25      const id = btoa(idBytes);
     26      return `
     27      try {
     28        // Reverse the process: decode the embedded string into a byte string.
     29        const decoded = atob("${id}");
     30        // Then, copy each byte into a Uint8Array that we can pass to WebAuthn.
     31        const id = Uint8Array.from([...decoded].map(c => c.charCodeAt()));
     32        navigator.credentials.get({
     33          publicKey: {
     34            challenge: Uint8Array.from([]),
     35            allowCredentials: [{type: "public-key", id}],
     36            userVerification: "discouraged",
     37          }
     38        }).then(c => window.parent.postMessage("OK", "*"))
     39          .catch(e => window.parent.postMessage("Error: " + e.toString(), "*"));
     40      } catch(e) {
     41        window.parent.postMessage("Error: " + e.toString(), "*");
     42      }
     43      `;
     44    }
     45    promise_test(async t => {
     46      credential = await createCredential();
     47    }, "Setup: create a credential to test with");
     48 
     49    promise_test(async t => {
     50      let frame = document.createElement("iframe");
     51      const loadPromise = new EventWatcher(t, frame, "load").wait_for("load");
     52      document.body.append(frame);
     53      await loadPromise;
     54      frame.contentWindow.location = "javascript:" + encodeURI(getCredentialScript());
     55 
     56      const messageWatcher = new EventWatcher(t, window, "message");
     57      const { data } = await messageWatcher.wait_for("message");
     58      assert_equals(data, "OK");
     59    }, "navigator.credentials.get({publicKey}) in a javascript url should should succeed.");
     60 
     61    promise_test(async t => {
     62      let frame = document.createElement("iframe");
     63      const loadPromise = new EventWatcher(t, frame, "load").wait_for("load");
     64      frame.srcdoc = "";
     65      document.body.append(frame);
     66      await loadPromise;
     67      frame.contentWindow.eval(getCredentialScript());
     68 
     69      const eventWatcher = new EventWatcher(t, window, "message");
     70      const { data } = await eventWatcher.wait_for("message");
     71      assert_equals(data, "OK");
     72    }, "navigator.credentials.get({publicKey}) in srcdoc should succeed.");
     73 
     74    promise_test(async t => {
     75      let frame = document.createElement("iframe");
     76      const loadPromise = new EventWatcher(t, frame, "load").wait_for("load");
     77      frame.src = "about:blank";
     78      document.body.append(frame);
     79      await loadPromise;
     80      frame.contentDocument.write("<script>" + getCredentialScript() + "<\/script>");
     81 
     82      const eventWatcher = new EventWatcher(t, window, "message");
     83      const { data } = await eventWatcher.wait_for("message");
     84      assert_equals(data, "OK");
     85    }, "navigator.credentials.get({publicKey}) in about:blank embedded in a secure context should succeed.");
     86 
     87    promise_test(async t => {
     88      let frame = document.createElement("iframe");
     89      const eventWatcher = new EventWatcher(t, window, "message");
     90      frame.src = "resources/webauthn-subframe.sub.html";
     91      document.body.append(frame);
     92      assert_equals((await eventWatcher.wait_for("message")).data.type, "subframe-loaded");
     93 
     94      frame.contentWindow.postMessage({ type: "get-credential", addUserActivation: false });
     95      const { data } = await eventWatcher.wait_for("message");
     96      assert_equals(data.result, "success", "Error: " + data.error);
     97    }, "navigator.credentials.get({publicKey}) in a same-origin frame should succeed without requiring user activation.");
     98 
     99  }, {
    100    protocol: "ctap2_1",
    101  });
    102 </script>