Just wanted to add since I didn't see this covered in other comments yet --
TOTP and any sort of one time code authentication are just as phishable as passwords. Perhaps the biggest benefit for most people using U2F or FIDO2, is the large resistance to phishing.
This is because of how the whole ecosystem has adopted FIDO2. When a FIDO2 key signs an assertion for a website, it includes the domain in the signature base, e.g. "example.com". The browser enforces that the request to the FIDO2 key always uses the correct name of the domain you're on.
If you accidentally go to a fake website, "exaample.com", then the key will make a signature for "exaample.com", which is invalid for "example.com". Nothing can be phished to get around that, unlike OTP codes.
Even if you have other 2FA options linked to your account, as long as you're using your FIDO2 key, you gain this benefit. Very strong benefit for both individuals and enterprises.
> If you accidentally go to a fake website, "exaample.com", then the key will make a signature for "exaample.com", which is invalid for "example.com".
This actually isn't true - the result is even better.
When you visit fake.example instead of real.example there are two scenarios: For FIDO2 (like this product) with usernameless mode, just as with a modern iPhone or fancy Android with fingerprint reader, the authenticator knows perfectly well that you've never registered at fake.example so, you can't very well authenticate to it, you get an error.
With FIDO1 (or on sites that don't use the usernameless feature anyway) the authenticator has no idea you've never visited fake.example... but the site has to hand over an opaque ID, a large binary blob. This is (either directly or in effect) actually your private key, encrypted in AEAD mode using a symmetric key known only to your authenticator. Another ingredient to this encryption is the domain name. So either fake.example hands over a random blob, which is gibberish, or they hand over a genuine real.example blob... but they're fake.example so the decryption fails. You get an error.
The way I found this out was by trying it, I built a toy site with WebAuthn authentication. If I run the same code, on another site I own, it gets an error in the Javascript telling it that apparently I don't yet have a Security Key enrolled for this site, maybe it should enroll me first. If I tell it to pretend it's a different site, it gets an error saying no it isn't.
[ The bad guys could enroll you, but now you're really signing into their web site. Which is cool, but, doesn't actually help them phish credentials for the other site ]
I look at it like nothing < SMS 2fac, app OTP, fido2.
Every layer buys you a little bit (or a lot) more, raising the skill level and/or cost. Fido2 is much harder to phish but of course weaknesses may be found in the future.
I wrote pass-otp because I want to use a hardware token everywhere, not a TOTP secret that can be duplicated. The number 1 complaint I get is that I'm defeating the purpose of 2FA.
TOTP and any sort of one time code authentication are just as phishable as passwords. Perhaps the biggest benefit for most people using U2F or FIDO2, is the large resistance to phishing.
This is because of how the whole ecosystem has adopted FIDO2. When a FIDO2 key signs an assertion for a website, it includes the domain in the signature base, e.g. "example.com". The browser enforces that the request to the FIDO2 key always uses the correct name of the domain you're on.
If you accidentally go to a fake website, "exaample.com", then the key will make a signature for "exaample.com", which is invalid for "example.com". Nothing can be phished to get around that, unlike OTP codes.
Even if you have other 2FA options linked to your account, as long as you're using your FIDO2 key, you gain this benefit. Very strong benefit for both individuals and enterprises.