12 Sep
2026
12 Sep
'26
9:07 p.m.
> > Note: This gives Chrome your PEM data but allowed me to relogin on
> > webauthn.io on a public computer without a physical key. From
> > exhaustive rubber ducking with google search AI.
> >
> > Registering:
> 0. F12 / ctrl-shift-I / dev tools on the hardware key registration page
> > 1. 3 dots -> More tools -> WebAuthn
> > 2. Check Enable virtual authenticator environment
> > 3. Click Add to create a new authenticator, optionally enable support
> > for resident keys and user verification
> > 3b: If the registration window is a popup and the registration flow
> > may close the window, Sources -> Event listener breakpoints
> > (right-hand pane) -> Load: check beforeunload and unload
> > expand the webauthn credentials columns so they can be quickly copied out!
> > 4. Register a device on the website => a row is added to the Credentials table.
> > 5. Copy all the values from the table and export the PEM file (privat
> > key) and copy the body text from it without the header and footer
> > guards or linebreaks. This is your insecure, not-airgapped paper ID.
> > 5b. if a breakpoint is raised resume execution to not time out,
> > although the registration may stlil succeed if the flow times out
> >
> > Authenticating:
> > 1. F12 / ctrl-shift-I / dev tools -> gear icon / settings ->
> > Experiments -> enable Protocol Monitor
> > 2. Reload dev tools and go to 3 dots -> More tools -> Protocol Monitor
> > At the bottom raw CDP commands can be sent in JSON.
> >
> > 3. In the lower right dropdown next to the CDP command line, set the
> > target to Main.
> >
> > 4. send:
> >
> > {"command":"WebAuthn.enable","parameters":{}}
> >
> > check the log and ensure no error is raised
> >
> > 5. send (removing any e-mail artefacts such as line breaks):
> >
> > {"command":"WebAuthn.addVirtualAuthenticator","parameters":{"options":{"protocol":"ctap2","transport":"usb","hasResidentKey":true,"hasUserVerification":true,"isUserVerified":true}}}
> >
> > check the log and ensure no error is raised
> >
> > 6. The last command produced an authenticator ID in its response. Copy
> > this ID from the log.
> >
> > 7, Replace in the following command all the uppercase snakecase values
> > with the copied values from before, and send it:
> >
> > {"command":"WebAuthn.addCredential","parameters":{"authenticatorId":"AUTHENTICATOR_ID","credential":{"credentialId":"CREDENTIAL_ID","isResidentCredential":true,"rpId":"CREDENTIAL_RP_ID","privateKey":"CREDENTIAL_PEM_FILE_BODY_STRING","userHandle":"CREDENTIAL_USER_HANDLE","signCount":1}}}
> >
> > check the log and ensure no error is raised
If one of these commands raises an error, open the left drawer, select
the target, input the "command" field and hit Enter -- then the
properties expand as editable form fields and can be filled in
individually. Either hit send or close the drawer and chrome will
generate a correct command in the command field.
> >
> > 8. Authenticate on the website. It worked for me.
> >
> > On reuse only the authenticator ID need be changed from the last command.