In our dialogues with customers, we often come across CSRF findings being marked as False Positives because a CAPTCHA is implemented. There is a widespread misconception that having a CAPTCHA in place protects against CSRF. In most cases, this is incorrect at best and dangerous at worst. CAPTCHA does not prevent CSRF – here’s why.
To understand why CAPTCHA does not protect against CSRF, we need a basic grasp of how it works.
On the client side
- The browser requests a challenge from the captcha provider.
- The browser retrieves the challenge/image and the ID of that image.
- The user solves the challenge/image by transcribing it into an input field.
- When the user clicks submit, the browser sends the challenge ID and the transcribed data to the server.
On the server side
- The server receives the challenge ID and the transcribed data from the user.
- The server forwards these two parameters to the CAPTCHA provider that in turn confirms if it was correctly solved or not.
As such, the server never knows who solved the captcha, just that it has in fact been solved. This is the core principle of all CAPTCHA systems.
An attack scenario would look like this:
- The attacker requests a challenge from the captcha provider.
- The attacker saves the challenge ID and solves it.
- The attacker compiles the CSRF request and includes both the solution and challenge ID in the request.
- The server retrieves the request from the user, confirms it is a valid solution, and accepts the action.
(Google uses a slight variation on this. The user sends a request to Google as soon they have solved the CAPTCHA and the received token is then sent to the website for validation, but the result stays the same.)
This is nothing new. Egor Homakov described this exact attack scenario back in 2013 and he was not the first to have done so. It should also be mentioned that it is possible to buy challenge:solution pairs online from people that have already solved them, making this attack even more practical.
Even the official OWASP page has recommended implementing a CAPTCHA for a long time, so it is not surprising that CAPTCHA is believed to be a solution. OWASP vaguely mentions that CAPTCHA needs to be implemented correctly, but this is easily misinterpreted.
While challenge-response is a very strong defense against CSRF (assuming proper implementation),
We always explain this attack scenario to customers that report CSRF findings as false positives to show that implementing CAPTCHA is not enough. We have recently received several questions about the next version of Google reCAPTCHA and whether it protects against CSRF.
Neither CSRF or Cross Site Request Forgery yield any results in the documentation for Google reCAPTCHA. This is important, because even if it turned out to actually protect against CSRF right now, relying on it would not be a good idea. The way reCAPTCHA works could be changed anytime and because the documentation does not mention CSRF protection, Google are not obligated to ensure reCAPTCHA works as a CSRF defense.
Even though reCAPTCHA is not intended to protect against CSRF, we decided to take a closer look. Debunking the myth of reCAPTCHA as CSRF protection was as easy as looking at the official documentation.
The secret is static for all solved captchas on your website and therefore also not relevant for this question. The only thing that matters is the response, and possibly the optional remoteip. (It should be noted that the same verification process is used for both reCAPTCHA V2 and Invisible reCAPTCHA, so this ‘problem’ is universal.)
We can hereby conclude that reCAPTCHA does not prevent CSRF by default.Please note that this is not a criticism of Google reCAPTCHA as their goal has never been to prevent CSRF attacks in the first place.
It would be possible to use the remoteip which would make a CSRF attack much more difficult as the attacker and the user would have to use the same IP address. However, this is not something we would recommend as it also prevents legitimate scenarios where a user for example receives the CAPTCHA over a mobile connection, automatically connects to home wifi and thereafter submits the actual request over that connection.
Check if you’re vulnerable to CSRF by running a free Detectify security scan >>