Why Cloudflare’s CAPTCHA replacement with FIDO2/WebAuthn is a really bad idea
Disclaimer: Thoughts expressed here are my own, and not of my employers.
Recently Cloudflare released their FIDO based CAPTCHA replacement. You can read more about it https://blog.cloudflare.com/introducing-cryptographic-attestation-of-personhood/, and try it here https://cloudflarechallenge.com/. In the nutshell the way it works:
- User gets FIDO CAPTCHA page.
2. User clicks “I am human”.
3. User’s security key lights up. User taps the security key.
4. Browser asks if user allows Cloudflare to receive device attestation.
5. Cloudflare receives device attestation, and using metadata from the device, that contains root certificate for the batch certificate located in the attestation, it is able to validate device attestation.
6. Success, user passed all the checks.
So why is it actually bad?
What is attestation?
Attestation is a FIDO protocol builtin mechanism that allows relying parties(websites) to obtain information about authenticator model and manufacturer.
The way this is done, is that device has baked into it Batch Certificate and Batch Private key. During the registration authenticator response is signed with the Batch Private key, and websites can validate it with Public Key located in the Batch Certificate.
The response would contain some sort of model identifier, like GUID/UUID for FIDO2 and Subject Key Identifier for U2F. The website, Cloudflare, then has a Trust Root Certificate that is identified by the ModelID(GUID or SKID), and by having that Root Certificate it is able to validate response Batch Certificate, and using the Batch Certificate, validate signature over attestation response. Just a normal PKI, no magic.
What is CAPTCHA?
A CAPTCHA test is designed to determine if an online user is really a human and not a bot. CAPTCHA is an acronym that stands for “Completely Automated Public Turing test to tell Computers and Humans Apart.”
The idea is that a computer program such as a bot will be unable to interpret the distorted letters, while a human being, who is used to seeing and interpreting letters in all kinds of contexts — different fonts, different handwritings, etc. — will usually be able to identify them.
So the idea is: There are tasks that hard for computers, like image recognition, logical tasks, etc, but easy for humans(mostly).
So why FIDO Attestation is a bad idea as replacement for CAPTCHA?
1. Automation of FIDO security keys is really easy.
The idea of CAPTCHA is that you can not easily automate task. Well meet 5$ Arduino and, oh God, WIRES!
And I am not gonna tell how easy it would be to implement automated ClientPIN injection.
2. Popups are optional for attackers.
If you think it will be hard because user need to approve Popup, a bit of JS to modify browser request to be “none”, and a small browser modification to disable EraseAttestationStatement https://source.chromium.org/chromium/chromium/src/+/main:device/fido/attestation_object.cc;bpv=1;bpt=1?q=NoneAttestation&ss=chromium%2Fchromium%2Fsrc and you get popup bypass.
UPD: As Eric Lawrence pointed, you can setup enterprise policies which will disable webauthn popups https://chromeenterprise.google/policies/#SecurityKeyPermitAttestation
3. Security Keys are quiet fast
Security keys, on low level take about 700ms to 1700ms to do all exchanges from my experience. That’s approximately 30 potential requests a minute. And you make it super effectively with HID Click Farm!
The idea is that you have VMs with Virtual HID device. VHID pretends to be security key, but what it actually does is proxies requests over the network, to the farm controller that has hundreds of keys plugged in to it. Couple of good quality USB controllers, and twelve core Ryzen with enough PCI lanes will easily handle few hundred HID devices at a time.
Regarding devices you can get Feitian U2F devices for 18$ or Yubikey Security Keys for 20$ each.
The browser will send request to the VHID device, that will proxy it to the farm controller. The farm will select any random free security key, and call Arduino to perform physical click. The device will return response and send it back to the VM’s Virtual HID, that will return to the browser.
25k$ will get you about 1000 security keys, and couple of good machines to manage them. The software development for that is trivial and can be done in Python in a very short period, which would generate 20,000–40,000 attestations per minute.
Lastly you can simply buy a lot of NFC readers, like ACS122U, and using PCSC, you don’t even need an Arduino, you can just tell the reader magic SCARD_UNPOWER_CARD command to power cycle the device.
4. Attestation is not a good mechanism for CAPTCHA
Attestation is not a perfect mechanism, and I would deeply discourage people from using it. The reasons for it are such:
- Attestation does not prove anything but the device model — There is no magic in attestation. It does not proves user liveliness, because Cloudflare is simply does attestation check. That’s it. FIDO is really good against phishing and bots, because we know that user owns the device, and that it using FIDO moves attack from being remote bruteforce, to direct, personal attack on real human. Cloudflare CAPTCHA does not achieves that, because it does not authenticate user. It is simple verifies device model. That’s it.
- Privacy — FIDO mandates that attestation Batch Certificate usage is at least ONE batch certificate per 100,000 devices. So if you know that Alice has Security Key with this certificate, and you see this certificate on another site, there is 1/100,000 chance that this is Alice. This does not sound like a lot, but when you combine together with all other tracking info that sites may keep on you, this becomes another piece of info that can be used against you, and as we all know, everything is run by Cloudflare today.
Now this does not mean that attestation is completely useless. It is a very important mechanism in high compliancy environments. Banks, governments do need it, and recently Czech government announced that FIDO certified FIDO2 authenticators can be used for their national ID with eIDAS, and L2 certified devices can be used as high assurance proof. This is what you need attestation for. The 1% of situations when you need attestation.
- User experience — Popups are pain, and a lot of people just disable them in them because there are just simple too many popups. Attestation is bad for UX, you should avoid it.
- Attestation is very hard to manage — You need to collect metadata for the devices(Somewhat solved by MDS). You need to know what fields do you need. You need to trust metadata. It’s a very hard problem, that requires good understanding of what you are doing.
I personally think that in a, very short term Cloudflare’s solution will help with some bot. But understanding FIDO market, and knowing that security keys are first and foremost enterprise and backup authentication solution, and that the future of FIDO lying in wide deployment of the platform authenticators, leads me to believe that current solution will be widely abused with wider deployment, as it is explicitly targeted those who need and can afford security keys, enterprise.
I am not here to just crap on someones solution. I objectively believe that Cloudflare team, who do really cool things, have really cool and useful projects, did try to do something good. But in this specific case they are creating potentially even bigger problem while not solving what CAPTCHA was solving, making bad AI better day by day, until Skynet kills us all.
FIDO are authentication standards.
Thoughts expressed here are my own and often are silly.
- Couldn’t Cloudflare just ban malicious security keys?
When manufacturer produces devices, they generate attestation batch certificate and attestation batch private key every 100,000 devices. That means that getting individual attestation can not be used for tracking and therefor, you can not ban individual key without banning the entire 100,000 key batch, so no.