Google Recaptcha is one of the industry-standard methods that solve the email spamming problem.
What is Email Spamming?
Email spam a.k.a junk emails refers to uninvited emails, usually sent to a large list of recipient email users. This recipient’s email addresses are stolen or purchased by attackers for money theft or commercial purpose depending on what attackers want.
These emails most of the time have hidden malware that was not supposed to open and if someone opens their mail and clicks the links will become a victim of these attackers.
e.g the places which is the source of the email spam –
Login, signup and reset password forms on the site
the comment and contact us section in a blog
There are 4 types of Google ReCaptcha –
In this article, we are going to integrate the google ReCaptcha v3 which is the latest.
If you’re already using Google Recaptcha v2 and you want to move to Google Recaptcha v3, you can read the Google documentation for the same, it is pretty straightforward.
After registering the website on the admin console, note down the reCAPTCHA keys.
e.g. In the above image, you must be seeing the reCaptcha Keys.
ReCaptcha gives 2 keys – 1. Site Key – this is the public key and is used in client-side integration. 2. Secret Key – this is the private key and can’t be exposed to anyone. This should be safely stored in your backend server.
Let’s start with the client-side integration –
1. Load the JavaScript API with your site key
in the above, you will pass the actual Recaptcha Site Key in the place of <site_key>
e.g if the Recaptcha Site Key is sdfjhjk124jkhk
you will pass it as ?render=sdfjhjk124jkhk
2. Call `grecaptcha.execute` on each action you wish to protect
Whichever input box you wish to protect, it could be your signup, login or some other field, you need to update the click handler for that, similar to above.
You can see the above code, we pass the actual Recaptcha site key and one callback function to the grecaptcha.execute function.
When the callback is executed, we get the token in it. And this token immediately needs to be passed to the backend server for fetching the user score.
3. Send the token immediately to your backend with the request to verify
This will trigger the server-side flow.
Step 2. Server-Side Integration
With the token passed by the client and with the Recaptcha Secret Key that was already stored at the server-side, the backend will make the call to google site-verify api.
The google site-verify API returns a score that is between 0.0 to 1.0. We also set one threshold score default of 0.5 up to which score we will allow users to make requests.
If the score is less than the threshold score we can say that the user is not human and it’s a bot. If the score is >threshold score then the user is human and the actual functionality of click is allowed.
Request end point
Site Verify Response
The response is a JSON object.
Challenge
On StackOverflow, I was searching for something and found out most of the people are implementing it incorrectly.
They are getting the score from server-side and comparing the score and threshold on the client-side which is completely wrong.
e.g. Below implementation is wrong
The above is incorrect due to –
the client never does the validation
Attackers can easily manipulate the score and see the comment API endpoint and flood it with unsolicited emails.
Here is the correct implementation –
// At server side
function callCommentAPI(token){
var score = fetchScoreFromAPI(token);
if (score > THRESHOLD_SCORE) {
// execute logic for comment API
}
}
So, we have just passed the token to the existing API and the validation is done at the server-side which is the more secure and correct way of doing it.
Also, you can notice that even if the comment API URL is exposed to the public but it won’t get spammed as it first checks the score.
Summary
I hope you have learned something new. Let me know if you think you can solve it differently or if something is wrong with the article.