reCaptcha v3: should I post to Google's verification API even if I have no token? - recaptcha

I'm currently implementing Google's reCAPTCHA v3 to guard a form. Normally, the way this works is that when a user submits the form, a user response token is generated and conveyed to the back end, which then forwards the token to Google's verification API to get an assessment.
I've found that, for certain attacks, the user response token is missing because the attacker is submitting their POST request to my site directly, rather than using the form. This is good because it makes it obvious that they should be rejected. But I'm wondering if I should go ahead and submit a token-less verification request to Google anyway, knowing that it will fail.
I ask because my understanding is that reCAPTCHA gathers information about my site activity over time, using it to fine tune their assessments. I don't know how this is done, so I don't know if it would be useful to exercise the verification API even when I already know what should be the outcome.

Related

How to detect Captcha farms and block Captcha bots

Brief Summary
Let's start with a brief introduction of what a Google reCaptcha farm is - a service that bot developers can query via an API to automate solving Google reCaptcha:
The bot is blocked by a Captcha challenge.
It makes an API call to the Captcha farm with the website’s Captcha public key & its domain name as parameters.
The Captcha farm asks one of its workers to solve the Captcha.
After ~30-45 seconds, the Captcha is solved and you obtain its response token.
The bot solves the Captcha by submitting the response token.
In short, solving a Captcha is as simple as calling a function in the bot's code. The attacker doesn't even need to interact directly with the Google reCaptcha by clicking on it. If the attackers know the structure and the URL of the Google reCaptcha callback, i.e. the request where the website sends the Google reCaptcha response token after a successful response has been submitted (which is straightforward by looking at the devtools), they can prove that they've solved a Captcha without even using a real browser.
Problem
My website is fully integrated with Google reCaptcha V2 (Invisible reCaptcha). The implementation follows all steps listed in the documentation. It worked like a charm till now. As time passed by, we experienced different kind of attacks that tried to infiltrate our login. The one the caused the biggest problem was a Dictionary attack combined with automated Google reCaptcha solving mechanism. The attackers are using farms (or may be scripts) that solve the Google reCaptcha and generate unique response codes, which are used by a bot network (different IP addresses around the world, User-Agents, Browser Fingerprints, etc.). Using these codes, the Google reCaptcha is taken out of the picture and we MUST use different mechanisms to block the attackers.
Question
I reviewed the Google reCaptcha documentation multiple times along with different topics related to this problem, but couldn't find a way to prevent such attack in an easy way. I have a few questions and will be very grateful if somebody succeeded to answer them:
Is it possible to bind the Google reCaptcha response code to a code challenge, cookie or something similar in order to ensure that the code is generated by the exact client?
Is there any way to distinguish the Google reCaptcha codes, taken from a farm/script and the ones generated by the exact client?
I found that there are some solutions as DataDome, which are very expensive. Is there something similar but on lower price or an algorithm that can be implemented on my own?
Big thanks in advance!
Script
Below is a simplification of the script that acts like a Google reCaptcha farm:
bypassReCaptcha();
function bypassReCaptcha() {
grecaptcha.render(createPlaceholder(), buildConfiguration());
grecaptcha.execute();
}
function createPlaceholder() {
document.body.innerHTML += '<div class="g-recaptcha-hacker"></div>';
return document.getElementsByClassName('g-recaptcha-hacker')[0];
}
function buildConfiguration() {
return {
size: 'invisible',
badge: 'bottomleft',
sitekey: '<your site-key>',
callback: (reCaptchaResponse) => localStorage.setItem('reCaptchaResponse', reCaptchaResponse)
};
}
I am using a server-side validation - something like this:
curl -X POST 'https://www.google.com/recaptcha/api/siteverify?secret=<your secret>&response=<generated code from above>&remoteip=<client IP address>'
It seems that the remoteip parameter is not working as expected - the validation is successful no matter of the client IP. I checked some topics and seems that this is a common problem:
Google reCAPTCHA's remoteip parameter is ignored
Is there any reason to include the remote ip when using reCaptcha?

Single Sign On(-ish) behavior from MS Teams with BotFramework Composer

We are using BotFramework Composer to create bots. These bots are supposed to get information from a backend REST service, where we need to know, which user is submitting the request for data. We are currently using {turn.activity.from.id} to get the Teams user's id, and sending it in a special http header in the "Send an HTTP request" action. We then perform a mapping of this id to our internal users.
We are, of course, aware, that this is not secure at all, since anyone who knows this, could get the user's id and send it to our service. We are currently thinking along the lines of generating a short-lived jwt token in the Bot to send to our application. However, we see no direct way of implementing this token generation in the Bot Framework Composer itself.
Also, we don't want to use OAuth, because we don't want the user to have to log in via the bot.
Is there a way to implement custom token generation using C# or js and assigning it to a dialog variable to be used in a "Send an HTTP request" action?
This document discusses how to implement an HTTP request in Composer. The first half is focused on creating a login for OAuth, which I know is not your focus, so look at the second half. If you set up a simple server that can generate a token for you, then you can make a request to it from Composer using the method described.
As links can break and docs can change (and Composer is still in Preview), I would recommend saving the doc somewhere and checking back every so often for any updates.
I've used HTTP requests from within Composer, myself, so I know this will work for you.
Hope of help!
You can create a custom Action or a package component and create any c# methods there for JWT generation. This will keep it all local to the bot.
https://learn.microsoft.com/en-us/composer/how-to-create-custom-actions

reCAPTCHA V3 : Do we need to verify token for each page?

Placement on your website
reCAPTCHA v3 will never interrupt your users, so you can run it whenever you like without affecting
conversion. reCAPTCHA works best when it has the most context about
interactions with your site, which comes from seeing both legitimate
and abusive behavior. For this reason, we recommend including
reCAPTCHA verification on forms or actions as well as in the
background of pages for analytics.
Source: https://developers.google.com/recaptcha/docs/v3
The above document says we need to integrate ReCAPTCHA V3 on multiple pages. So question is, do we really need to generate and verify token for each page or just generating token is enough?
like
grecaptcha.execute(reCaptchaPublicKey, {action: 'cartpage'}).then(function(token) {
//skip verification
});
Note:
On the form for which I want to block the bot, I am generating a token and passing it to the server with the user's form data. Now on the server-side, I am validating token using API and getting a score in response to take further action. like, block the user action if the score is low.
No, Calling grecaptcha.execute with the appropriate action (use 'homepage' for traffic on your homepage) is enough to make the reCAPTCHA service count and process the visit.
The token that is provided to your callback is requested from the reCAPTCHA service by the reCAPCHA client script. Sending it to your server to then send it back to the reCAPTCHA service to get the score makes no sense if you don't use the score.

LinkedIn API + WebKit

I'm trying to use the OAuthConsumer library for Cocoa to connect to users' LinkedIn accounts.
Following the steps provided by the original author of OAuthConsumer, I set up the request token, and point a WebView at the resulting URL.
Now, with other services that I've used OAuthConsumer for (Twitter, Facebook, etc.), this part works fine. The user logs in, authenticates the app, and then my code kills off the WebView and trades in the newly authorized request token for an access token.
However, with LinkedIn, I'm getting the error "We were unable to find the authorization token". No more information; no error codes. Just a neatly rendered webpage full of useless.
So, I ultimately have no idea where to even beging debugging this issue, or whether or not it's a problem with my code at all. The few minor leads I've been able to find on LinkedIn's forums state that my "timestamp may be off" (though, not according to Epoch Converter), and I should check the "timestamp in the response". Seems like a red herring to me.
Edit:
Charles Session
So, it turns out the parameter for returning the request token is "oauth_token", not "token", as I was using.
Now, this would ordinarily just be a commentary on the inconsistencies of OAuth implementation, and my oversight. However, I'm a bit concerned because there were several instances (mostly using a browser) where using the wrong parameter in the return query would work: a serious inconsistency, and potentially severe oversight on LinkedIn's part.
At any rate, it works now.

How can I log into gmail in a script/program using HTTPS?

My teacher has given me as an assignment to log into gmail and then send one e-mail or read the list of unread e-mails, but I can't use IMAP/POP3/SMTP or anything that isn't HTTP or HTTPS. I've tried looking for libraries in Ruby/Java to do it but nothing really worked for me.
I tried looking at the gmail source code page but I couldn't really understand what was going on. The page seems to call a post method on a link, but sniffing the packets what I saw was a GET apparently using a session generated using the info I send. So sending it "raw" didn't work either.
I've no idea what to do now.
After you authenticate with OAuth, you can get unread emails via an atom feed.
URL to hit: https://mail.google.com/mail/feed/atom/[<label>]
You can toy around with this at the Google oauth playground. Get an access token by continually clicking buttons and authenticating, and then hit discover feeds.
If you want a Java OAuth library, signpost is really good. You'll need to read the google documentation on its open authentication scheme. Specifically, you need to pass a scope query parameter when you attempt to authenticate. This is nonstandard, and it will trick you up if you're not looking for it.
If you're confused about OAuth or why its necessary, you may want to check out this resource.
Check out httplib2—it has (among other things) Google Account Authentication.

Resources