The thing is, if you fall victim to a phishing attack, the attacker may steal your credentials; but he/she will not be able to login to your accounts because even though the username and password works, they still need to have the 2FA code which only you have in your physical possesion (wheter it be a Yubi Key or a OTP in your phone). So the attack will be unsuccessful.
On the other hand, you could still get infected with malware via a phishing attack if you don't have a secure system. In this case, 2FA won't help much.
I mean: 2fa-code, login, password instead of: login, password, 2fa-code. Maybe login could be automatically filled based on 2fa-code public key? That should prevent leaking password to fake page.
A cheap Security Key has no idea what public key it told you to use when registering.
There's a cute trick here. When you tell a key "Hi, authenticate please" you must send it a "cookie" it gave you during registration. Now this could in theory be some pointer it uses or whatever. But in fact it's actually the private key it will use to authenticate, encrypted with its own baked in secret key. It decrypts that, then authenticates. But if you don't know which user you're authenticating you can't send their cookies, you'd have to try every cookie for every user. Not fast.
If every user uses WebAuthn then just a login (username or email address or something) is enough. But if some just have passwords then doing anything before the password step gives away what's up.
But more importantly, phishing sites will always tell you 'your key succeeded. Enter your password next' regardless, so this doesn't protect against password disclosure at all.
Real page: Give me login You: Login Real page: Good login, press your 2fa to authenticate You: Press Real page: Good 2fa, enter your password You: Password
Versus:
Fake page: Give me your login You: Login Fake page: Good login, press your 2fa to authenticate You: Press Real page: Good 2fa (wink wink), enter your password You: Password
The fake page wouldn't have a working login to the real page because the 2fa would be wrong, but it would still have your password.
So mybank.phishing can ask your Security Key to please authenticate, and convince you to press the button, but the output is useless for getting into the real site at my bank.com
Not only is a valid authentication to PornHub useless for GitHub, even if they both collaborate and share all their data they can't prove you've used the same token for both sites, so this is even a privacy win.
Secret Key USB or NFC devices also more resemble other physical keys for which users already have some useful intuitions we can leverage.
Almost all practical attacks are against a key stored on a server somewhere, a key in flight on the network, or a lack of security in the client. If we properly secure these aspects of access, we don't need a whole lot of extra layers, which are only workarounds for the actual root problems.
In the cheap mass-produced FIDO tokens we mostly care about the only keys anybody is storing are 1. a single secret symmetric key inside the token. It has no reason to give this up to anybody, and no API for doing so; 2. _public_ keys used to check credentials
If you're thinking "Wait, that can't be right, where do the corresponding _private_ keys live?" then Bzzzt, time to go read the FIDO/U2F specification before writing anything else on Hacker News.
The whole point of this type of design is that even if the attacker has local code execution you haven't lost. An attacker with local code execution _plus a button press_ gets not a key which can be stolen but a single proof of control of their choice. It's like stealing a single OTP code, it's not _nothing_ but it's very far from everything.