Passkey security: what the \"Pass the Passkey\" attack really means
Unit 42 showed malware can use synced Google passkeys without any biometric prompt. The crypto held. The checks around it didn't. Here's the fix if you run a login.

Passkey security just took its first serious public knock, and the interesting part is what did not break. Nobody factored a private key. Nobody beat the TPM. The cryptography did its job perfectly and accounts fell over anyway.
Unit 42 (Palo Alto Networks) published Pass the Passkey on 3 August 2026, written by Arie Olshtein. It documents three attacks against Google's synced-passkey system on Windows machines with a TPM. I want to talk about the part almost every writeup will skip: one of these is a bug on your side of the connection, not Google's.
🔍 Three attacks, one shared assumption
All three techniques start from the same place. Malware is already running on the victim's Windows machine as a normal user. No admin rights, no privilege escalation. From there:
| Attack | What it steals | What the attacker gets |
|---|---|---|
| Pass-ta-key | The wrapped device identity key from Chrome's passkey_enclave_state |
A valid assertion with no user interaction, but the UV flag left at 0 |
| Silver Pass-ta-key | Nothing — it registers an attacker-controlled UV key after forcing re-onboarding | Assertions with the UV flag set to 1, usable from the attacker's own machine |
| Golden Pass-ta-key | The Security Domain Secret (SDS), dumped from Chrome's process memory | Every synced passkey, decrypted, plus persistence over future ones |
The escalation is neat and grim. The first attack gets you in but leaves a tell. The second removes the tell. The third removes the need for the victim's machine at all.
Key takeaway: Passkeys are phishing-resistant, not endpoint-compromise-resistant. Those are different properties and the marketing has been blurring them for two years.
Unit 42 is straight about this limitation, and I'll repeat it because it matters: all of these require malware on the device first. This is not a remote exploit. It is a post-compromise credential-theft technique, which is exactly the category that made Mimikatz famous.
🛠️ The one flag most logins never check
Here is the bit that should ruin an afternoon for anyone who has shipped a WebAuthn login.
Authenticator data carries a User Verified (UV) bit. It tells the relying party whether a human actually did a fingerprint or PIN. In the basic Pass-ta-key attack, the malware signs with the device identity key, so UV stays 0. The assertion is otherwise cryptographically perfect.
Unit 42 tested real relying parties and found that many simply don't look at that bit. eBay was named as one that fixed its UV validation after disclosure. GitHub was also tested.
Two things have to be true, and most tutorials only cover the first:
// 1. Ask for it at the server, on BOTH register and authenticate
const options = await generateAuthenticationOptions({
rpID,
userVerification: "required", // not "preferred" — the default in many libs
});
// 2. Actually enforce it on the verify path
const { verified, authenticationInfo } = await verifyAuthenticationResponse({ /* ... */ });
if (!verified || !authenticationInfo.userVerified) {
throw new Error("UV not performed — reject");
}
userVerification value |
Behaviour | Safe to ship? |
|---|---|---|
"discouraged" |
Authenticator skips the biometric/PIN prompt | No |
"preferred" |
Prompts if it can, silently proceeds if it can't | No — this is the trap |
"required" + server-side flag check |
Prompt enforced and verified in the response | Yes |
"preferred" is the dangerous one because it looks correct in development. You test it on your own laptop, Windows Hello prompts you, everything works. The failure mode only appears when someone deliberately produces an assertion without UV, and your code shrugs and issues a session anyway.
While you're in that code path, check what you mint afterwards too. A perfect WebAuthn handshake followed by a sloppy session token is a wasted effort — you can paste yours into our JWT decoder and confirm the expiry and claims are what you think they are.
💡 Why this lands differently on a small Sri Lankan team
Unit 42's mitigations for the user side are all sensible and all expensive. Their own product suggestions include endpoint privilege management and identity threat detection. That is a fine answer for a bank in Colombo. It is not an answer for a four-person startup or a student running a side project.
What I'd actually do, in order of cost:
- Fix the relying-party side first. It is free, it is roughly ten lines, and it is the only part of this you fully control. If you run a login for anyone, do this today.
- Move the accounts that matter to a hardware key. A physical FIDO2 key is device-bound. It never syncs, so there is no Security Domain Secret to steal from Chrome's memory. Use it on the one account that unlocks the rest: your domain registrar, your GitHub org, your cloud billing.
- Stop treating "the malware got in" as an unthinkable scenario. Cracked software and second-hand Windows laptops with pre-loaded "activators" are normal here. The threat model in this research assumes exactly that starting condition.
- Never sign into a synced passkey account on a machine you don't own. A shared office PC or a lab machine now leaks more than a password would, because the Golden variant grants persistence over future credentials too.
🌐 So should you still use passkeys?
Yes, and I want to be unambiguous about that, because "passkeys hacked" headlines will do real damage this week.
| Method | Phishing-resistant | Survives endpoint malware | Cost |
|---|---|---|---|
| Password + SMS OTP | No | No | Free |
| Password + TOTP app | Weak | No | Free |
| Synced passkey (Google/Apple) | Yes | Not reliably | Free |
| Device-bound hardware key | Yes | Much better | ~$25–60 |
A synced passkey is still far ahead of the password you reused on three sites. The honest framing is that syncing is a convenience feature, and this research is the bill for it. You traded "the key never leaves this device" for "the key follows me to my new phone," and Unit 42 found the seam in that trade.
Bottom line: Convenience-tier passkeys for ordinary accounts. Hardware keys for the accounts that can end your business.
What this means for you
If you build logins, this is a bug report with your name on it. Set userVerification: "required", verify the UV bit server-side on every assertion, and reject anything that arrives without it. Then look at your re-registration and account-recovery flows, because the Silver variant works by abusing exactly that path — a recovery flow that quietly re-establishes device trust is a backdoor with a friendly name.
If you're a user, nothing here means you should crawl back to passwords. It means the phrase "passwords are dead" was always half a sentence. The other half is that authentication only ever proves something about a device, and a device you no longer control cannot prove anything on your behalf.
This is commentary on Unit 42's published research. Read the original writeup for the full technical detail and their disclosure timeline.