Passwords are dead? Long live WebAuthn!
Password security is getting out of hand. You only need to watch the latest news stories about large-scale breaches or visit the haveibeenpwned site to see the current state of password security. Expecting end users to invent complex passwords for every web site they visit is untenable. Wouldn’t it be great if there was some new technology that uses public key exchange and biometrics to get rid of passwords altogether?
Well, that technology is here. WebAuthn (Web Authentication) is a web standard published in 2019 by the World Wide Web Consortium (W3C). The goal of the project is to standardize an interface for authenticating users to web-based applications and services using public-key cryptography instead of passwords. Despite being an emerging technology, this standard has already been adopted by leading browsers and platforms.
This post aims to shed light on the technical details of what WebAuthn is and how it works. We will also cover the security pros and cons of this new standard and make predictions about what this may mean for the future of web application security. This is an introductory post. You do not need any prior knowledge of web authentication or cryptography to benefit from this article.
Outline
- What is wrong with passwords?
- What is WebAuthn?
- WebAuthn Pros and Cons
- What does WebAuthn mean for the future of web security?
What is wrong with passwords?
Password must be complicated to be strong.
This has a few implications:
- Your grandma (or whoever in your life is not security minded) can’t remember them
- Time wasted typing complicated passwords
- Time wasted resetting complicated passwords
All this makes passwords an easy target for attackers.
So we should all use pass phrases!
Some suggest passphrases instead of passwords. They are easier to remember, sure. But they still take forever to enter into authentication prompts. Also, in 2020, the average number of accounts per internet user will be roughly 207 (informal Dashline study). That’s a whole lot of random “Correct Horse Battery Staple” phrases to remember!
Additionally, many users will re-use their passwords. A recent Virginia Tech study found that 52% of users reuse their passwords. If you combine that with the fact that there are now more than 8 billion leaked passwords in the haveibeenpwned database, that paints a bleak picture.
So we should all use password managers!
Because of all the reasons outlined above, most security professionals recommend everyone use a password manager. This is the best option we currently have. But it still puts the burden of securing and backing up their password manager on the user. Also, putting all your eggs into one basket makes password managers a high-value target for attackers.
And finally, the biggest reason passwords are a problem, is that we can attack them. Here’s all the tools we use when trying to compromise a corporate network password:
- Phishing
- Password spraying
- Password breaches to check for re-use
- Brute Force
Is phishing really still a thing?
Yes! According to a recent Verizon report, 32% of breaches involved phishing. And speaking from experience, a well-crafted spear phishing message almost never fails. Sorry to say, but phishing training won’t help much either. A recent Vanderbilt study found that user awareness training had almost no impact on phishing click rates. Heck, I’m a security guy, and I believe a well-targeted phish would fool even me.
To make matters worse, we only need one password to win. After we phish or otherwise guess a password for one user in an organization, we normally measure the time to complete domain compromise in HOURS. That means the security of your organization could depend on Fred’s imagination when creating a password and his password hygiene for his other 206 online accounts.
“Well, that’s all well and good, Matt, but we have Multi-factor Authentication (MFA). So we are unhackable”
Great, let’s talk MFA. We have probably all heard about SIM-swapping attacks to break text message-based MFA, but we have never needed to go to such lengths during an engagement. If you are already entering your username and password into a look-alike site, it is not difficult to prompt for you MFA credentials as well.
Ultimately, with passwords and phishing, the onus of account security is put on the end user who is not a security expert. Even security experts are human and can make mistakes.
“So, passwords suck. What does this mean? Is everything broken and we should all go live in caves again?”
Well, lucky for us, for the past few years folks have been trying to fix this problem. And in 2019 WebAuthn was accepted as a standard by the W3C organization.
What is WebAuthn?
WebAuthn uses biometrics coupled with Public Key Authentication to replace passwords on web sites.
For those of us who slept through our cryptography classes, here’s a quick refresher of how Public Key Authentication works:
It may be obvious that the private keys here might be just as troublesome to protect for the average user as passwords are. Users would need to worry about hackers getting their hands on those keys. Here’s where the FIDO alliance steps in. They to try to make standards for universal hardware so a user can carry around private keys to use for authentication. Yubikeys are a popular example of this.
WebAuthn is exciting because, by adding just a few missing pieces to existing FIDO/private key technologies, web sites can do away with password authentication entirely.
The major pieces added were:
- WebAuthn API
- JavaScript functions
- Biometric checks
Here’s a high-level overview of how this all fits together:
In researching WebAuthn, you can get lost in the weeds with acronyms (CTAP2, FIDO, U2F, WTF). Here’s the lowdown on what all these pieces do:
- WebAuthn API: Site has to talk to browsers. This is usually a JSON API as defined in the W3C standard, but may take other forms.
- New JavaScript Functions: All major browsers have added new JavaScript functions that the sites can call during authentication to use these new features.
- Platform API: The major OSes have included what they are calling the “platform API”. This is just a formal way for different browsers to ask the operating system for the signature we talked about earlier.
- CTAP2: This is based heavily on the CTAP standards from the FIDO alliance that already are in use. CTAP2/FIDO2 adds new features including:
- CTAP2 supports “user verification”, such as PIN or Biometric Authentication
- Stores private keys locally so no sensitive data is ever sent to the server
- Extensions that allow manufacturer to add additional security features
- Compatible with existing TPM models such as Microsoft Hello
- Backwards compatible to CTAP1
But really, you only need to know two new overarching terms:
- WebAuthentication (aka WebAuthn) is from W3C (the browser people)
- Client-to-Authenticator (aka CTAP2) is from the FIDO Alliance (the hardware + OS people)
So, now let’s get into some more technical details about how it works. There are really only two actions you can take from the WebAuthN API:
For both of these actions, there will be data coming to your browser from the site you are authenticating to (server) and from your authentication device (client).
Register User
Here’s an example of the kind of data that will come to your browser from the server when you attempt to register a new user named “mattymcfatty” on the site:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// From server { "publicKey": { "challenge": "dcvVgLEwVx+owf0TVHGdCVtnun3gNuQq2P1B98jYj9U=", "rp": { "name": "webauthn.io", "id": "webauthn.io" }, "user": { "name": "mattymcfatty", "displayName": "mattymcfatty", "id": "5fAFAAAAAAAAAA==" }, "pubKeyCredParams": [ { "type": "public-key", "alg": -7 }, … ], "authenticatorSelection": { "authenticatorAttachment": "platform", "requireResidentKey": false, "userVerification": "required" }, "timeout": 60000, "extensions": { "txAuthSimple": "" }, "attestation": "none" } } |
Here’s a brief description of what all these values are:
- challenge: Random string that the user will sign with their private key.
- rp: Relying party; your browser will make sure this matches the domain name of the site you’re on. This is important to prevent phishing attacks with lookalike domains.
- user: The username you specified during registration. The handle here will be stored with the keypair on your authentication device.
- pubKeyCredParams: A list of encryption algorithms the site accepts.
- authenticatorSelection: What types of authenticators the site will accept.
- timeout: How long this request is valid. Usually set to one minute (60000 milliseconds).
- attestation: A way to cryptographically verify the authenticator used. Likely will be used in high-security circumstances. Most sites will not use attestation.
When your browser receives all that information above, your browser will then use a new JavaScript function to request a fingerprint scan from your authentication device.
1 |
navigator.credentials.create() |
The JavaScript function will use some of the details from the response above to make a new keypair using your authentication device (CTAP2). Here’s a look at what your browser will then send back to the server in response:
1 2 3 4 5 6 7 8 9 10 |
// From client { "id": "xi3JkjSCYRHOPPX6txMHDPQjHs1NcN4RWDqFU6DKmn4", "rawId": "xi3JkjSCYRHOPPX6txMHDPQjHs1NcN4RWDqFU6DKmn4", "type": "public-key", "response": { <strong>"</strong>attestationObject<strong>":</strong> "o2NmbXRkbm9uZWdhdHRTdG10oGhhdX…", "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJkY3ZWZ0xFd1Z…" } } |
And here’s a little description of what the values represent:
- id / rawId: Your authenticator creates this random value to identify the key pair.
- type: Currently one credential type is defined, namely “public-key”.
- attestationObject: This bit was confusing. So even though most implementations will NOT use attestation, the public key is always sent in this attestationObject parameter. It’s usually in Compact Binary Object Representation ( CBOR ) and Base64 encoded.
- clientDataJSON: Base64 encoded JSON that describes the authenticator that was used. It includes data such as the challenge value that was used and the hash algorithm used to sign the challenge.
OK, so now the server has a credential ID and public key for the user “mattymcfatty”. Next time the user wants to come back and login, these details will be used for authentication.
Authenticate User
Ok, we’re almost done with the code snippets. Now what happens when “mattymcfatty” comes back to the site after registration? The user will type their name and the server will respond with a challenge and the key id that was sent during registration. The following is an example of a response to a login request:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// From server { "publicKey": { "challenge": "cUZkPcKvkB3s/9m5afln3uTF9+SPiV1zbiO+RWznIpQ=", "timeout": 60000, "rpId": "webauthn.io", "allowCredentials": [ { "type": "public-key", "id": "xi3JkjSCYRHOPPX6txMHDPQjHs1NcN4RWDqFU6DKmn4=" } ], "extensions": { "txAuthSimple": "" } } } |
Here’s a brief description of what all these values are:
- challenge: Random string that the user will sign with their private key.
- timeout: How long this request is valid. Usually set to one minute (60000).
- rpId: Requesting Party ID. Should always be the domain of the site you are registering to. This is important to prevent phishing attacks with lookalike domains.
- id: This should look familiar. It is the random ID generated by your authenticator during registration. This will be used by your authenticator to look up the private key to use for this site.
- extensions: Extensions are optional features of the authenticator that can be used if the authenticator supports it. They are not really widely used right now, but it is intended for additional authentication features such as GPS location.
Again, your browser will use a new JavaScript function to request a fingerprint scan from your authentication device.
1 |
navigator.credentials.get() |
The JavaScript function will use the credential id and challenge from above to create a signature that can be verified by the server. Here’s a look at what your browser will then send back to the server in after you scan your fingerprint:
1 2 3 4 5 6 7 8 9 10 11 12 |
// From client { "id": "xi3JkjSCYRHOPPX6txMHDPQjHs1NcN4RWDqFU6DKmn4", <strong>"</strong>rawId<strong>":</strong> "xi3JkjSCYRHOPPX6txMHDPQjHs1NcN4RWDqFU6DKmn4", "type": "public-key", "response": { "authenticatorData": "dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvAFAAAAAQ", "clientDataJSON": "eyJjaGFsbGVuZ2UiOiJjVVprUGNL…", "signature": "X-pZe7TOEbHWtOW4Vt9qaNm8On2rjDf63OmGmqdNmTtPD-5-kOgFrUcAdEo-uSJ6sEM_icXQiWvXDj34RVib8Ddo9j7DfHkpdZNXmvvmA3R4pJpnOeXRzrR9WBp1UNifDzn91qb3dLddFfn5OdWNE8XZLhBSTyI-4FaT9L0Ab9cxEXCmT2O-tfqEFIM753d_-AOuo2hgiqr5Unu3bKfINP2zLDgOzY1fSPDiT9Xt3EyxJyeWOOuJESoLCl_JvGBNy27rOgHEMPZu9EakCLwArLltRejA7Lhy46k52N5SkwmPMfv572VuyA-DWUPphz0cUHuQcZXDZri9YDNpnYFwfQ", "userHandle": "5fAFAAAAAAAAAA" } } |
And here’s a little description of what the values represent:
- id / rawId: Should be the same as the id received originally.
- type: Currently one credential type is defined, namely “public-key”.
- authenticatorData / clientDataJSON: Base64 encoded JSON that describes the authenticator that was used.
- signature: This is where all the magic happens. This is the challenge signed by the private key. The server will use the public key to verify this signature.
- userHandle: The is the user identifier originally provided by the server during registration.
Whoa, that was a mouthful! You still with me? Ok if you’re like me, it helps to see this in action. Head on over to https://webauthn.io with browser tools enabled, fiddler, or burp suite to see an example of the requests and responses flying around. You will need a computer with a fingerprint scanner for this to be really fun, but Windows 10 Hello still works with a pin or other mechanism if you don’t have a fingerprint scanner.
WebAuthn Pros and Cons
[+] Easy to use
Most of the time when authentication gets stronger, the user has a harder time getting in. Not the case here.
WebAuthn is described as an authentication “Unicorn” that is both easier for users and more secure.
[+] Phishing resistant
This one is huge. Users cannot be relied upon to properly vet every URL that comes their way. WebAuthn eliminates this stumbling block by including the domain in the key exchange. With WebAuthn, the browser verifies the domain and not the user.
[+] Breach resistant
The sever has no private key or password data so there is nothing for hackers to steal from an authentication perspective. This is an advantage over password managers. In fact, the private keys are never transmitted and there is generally no straightforward way retrieve the private keys from the authentication devices.
[+] Based on strong crypto
Public Key cryptography has been used for years to secure the internet and the algorithms available are all vetted to meet industry best practices.
[+] Reverse compatible with FIDO1
Those FIDO1 Yubikeys will still work, but you miss out on the benefit of the “Something you are” factor of authentication with FIDO1 devices.
[+] Supported by all major browsers
[+] Good Platform support
[-] No iOS support at the moment
This could be a major problem for adoption. I imagine Apple will eventually jump aboard, but you can never be sure with Apple.
[-] Devices can be lost/stolen
For now, the best recommendation is to authenticate multiple devices for each account in case one device gets lost or stolen. This would be done in the application itself with a “Register a secondary authentication device” type of function. The second best recommendation is to use email to recover your account if your device is lost. This becomes troublesome, of course, if your email is also protected by said device. Experts unanimously agree DO NOT FALL BACK TO PASSWORD AUTHENTICATION if you lost your device. Any benefit of a WebAuthn mechanism would instantly evaporate if the “lost my device” function just prompts for a password.
[-] Cost of devices could exclude users
Combined with the recommendation to use multiple devices in case one is lost, users could be spending hundreds of dollars to be able to authenticate to your web application. This could be a huge hurdle to most of the world’s internet users.
[-] Legal implications
No one has really been talking about this, but there are some strange legal implications to using biometrics versus using a password.
Do you remember the whole FBI unlocking iPhones thing? A lot of that hinges on the fact that iPhones are generally protected by a pin in addition to a fingerprint.
In the US, under the 5th amendment, a defendant cannot be compelled say something that might incriminate themselves. Strangely enough, that means law enforcement cannot force you to tell them a combination to a safe full of drugs for example. They can, however, force you to provide the physical key to unlock that safe. This holds true in the digital world as well. Police can’t force you to say keys that are in your mind, but they can force you to provide physical keys.
I’m not a lawyer, so please don’t believe anything I am saying right now, but with biometric keys such as those used for WebAuthn, they could be subpoenaed in a way that passwords currently cannot be. Just some food for thought.
What does WebAuthn mean for the future of web security?
Bottom line, this will make it harder for bad guys like us to attack web applications for a number of reasons:
- We would be fighting crypto now instead of Grandma’s creativity
- No more hashed passwords to find when you dump databases 🙁
- No more phishing 🙁
If widespread adoption happens, the phishing protection could mean a sea change for the way hackers hack. Right now, phishing is a common step for any red team engagement. Not surprisingly, password phishing attacks are much more popular than malware and trojans. If phishing dies, then we can expect to see trojans and malware grow in popularity.
I do foresee iOS compatibility as a major barrier to adoption. No one is going to buy a $100 fingerprint scanner to plug into their $1000 iPhone that already has a fingerprint scanner on it. Another barrier could be Remote Desktop or other virtual environments. Some passthrough mechanism from the host to the guest would be necessary for such physical authentication devices to work.
That’s all! You made it!
Thanks for reading. Feel free to comment below or contact us.