Google recaptcha v3 issues - recaptcha

Why does recaptcha v3 throw an error ?
... when I check the humanity of a visitor a second time on the same page?
Token is clearly NOT a duplicate.
... so what is a duplicate?
First token:
03AEMEkEl76Kn0nMhKlgY8dMOAD2g3zGIHoGOqz95jEFKl8A24gADw-2gBipDYcU7G_TWSqpuWyNa62CIk-tYdreevde0p1lJg_3wwZlmD9giDSdPb_He-mTsIqv0tMuEroJLLArCI4vfbZjcCZ6BYokYEhYbCU-Qqdx9YbqgRG1JJDxE8LRagR0cPY8mfQZ5bZ7KGK8Dfqe8avqOy18RvIcYk-H6s9Bhq28s5YRIkHid163c-yqpeY8U5j9U70aveSuEcLz-UMlgsQ8MaYhHIIv7cJpag2RJFAgGxOZnWONEk2Z9-IK_Ea_4
recaptcha v3 Response:
{
"score":0.1,
"hostname":"localhost",
"success":true,
"challenge_ts":"2018-07-17T21:24:03Z",
"action":"AW___________LGOZCKiH_oQBEJnwwYcD"
}
Second token on same page with same label:
03AEMEkEk-CVItfMmzYErG97inmxzf7mIeWuAgEXmwncu8AvMGP0ofXnwCMFNdBpa7CY8MCkVZ_skiF1HwmGhKBgayFm-fM3VM_QfM5LRNDbxLLyCF8lGclmBBlihmkeT1PsvW9LrVfp2VdikuHxeqvviGnI2NKQHbclvaDnuu5rwy3HS_EiPrn7eJb3z892f8oIOMkVg6tTsCNPCTnH5QuvAIw2DlI3EiRFDSqIjXp4vJdzJIGn10K6Noi1JIPOCzJ8OUshn_yFROWvNNpYNFn3E7tSHk3j0LU9-KDy1RiSoEf2I1VcVEKTE
recaptcha v3 Response:
{"error-codes":["timeout-or-duplicate"],"success":false}

Yes, This is the error code we get in two case.
1) When we send same token for two requests
2) The token gets expired in every 3 minutes. So if the user do not submit the form in 3 minutes then the token gets expired and we get this error message.

The token might have timed out. It happened to me also. On page rendering, a token was generated but I performed an action after a long time. Then it gave me this error. But if the token is generated on action performing then it works fine.

I had a similar problem, but I realized it was not a good understanding.
This error message happens when:
1. The token was already verified, so it becomes "duplicate".
The token was executed 3 minutes or more before it was verified, so it becomes "timeout".
Regarding the second scenario, the idea is to verify the action when the action is executed. Meaning, if you want to verify a submit operation, then you may need to generate the token to verify when submitting, not right after the grecaptcha Object is ready.
Online documentation has an example where the execute methods is invoked right after the grecaptcha is ready, but that's the case when you want to verify that execution right away. In the case of formularies, the execute method should be placed in the same routine of the form submission, makes sense? Probably I am mistaken, but I have been able to verify click actions, form submit actions, close popups actions, you name them. 😉

The monstor captcha token generation at the time of page load is definitely is not a good idea as it expires after 2 mins. If still you bound to do so, you have to renew the token after some time intervals using 'setinterval' in JavaScript.
So to generate the token on button submit 'execute' will do your work better. You can call ajax or java script to call the execute method. Please refer google reCAPTCHA v3 documentation for more information.

Related

Trying to understand how recaptcha works step by step

This is my current understanding of recaptcha (using v2 invisible)
We load the api.js script onto our site
We add data attributes to the button
User clicks button
A listener somewhere in the api.js script fires because it's listening for an event on a tag with those data attributes
This is where it gets fuzzy and I start guessing:
api.js gathers browsing info from the user's cookies and information about how they interacted with the site. Based on this it determines how likely you are are to be a bot and if you are below a certain threshold it gives you a test. Whether you pass the test then gets further factored into your score and all of that gets encoded into a token, which we receive in our callback that we specified on the button's data attribute.
We pass this token to the back end with the rest of our form
From the backend, we make an API request to Google to convert the token into usable information about whether the user passed or failed.
At this point I get confused about why this wasn't just what the api.js script returned in the first place. Does this step only exist in order to give Recaptcha information to further improve it? I just don't understand why this step is here, unless I'm misunderstanding what is going on earlier in the process. Am I getting these we steps wrong? Thanks.
The whole point for captchas is that your server (instead of client in the browser) can verify that the (HTTP) request it received was generated from a real person's actions, when interacting with your application.
This is why your client sends a recaptcha token to your server and your backend consults with the captcha provider about this token and receives trusted information about the original client. In this scenario, your server does not trust the client, so it receives only a token from it. Then it communicates with the trusted captcha provider server-to-server and validates that the token it received from the client is valid and the user behind it is legitimate.
If your client sent the original response from the captcha provider to your backend server, there would be no way for your server to know whether this was a legitimate response from the captcha provider, or a fake one from the client.

I want to use Google API refresh tokens forever

There is a process to obtain a refresh token via OAuth authentication for Google API, and then obtain an access token from the refresh token to validate the receipt.
The other day the refresh token suddenly expired and the receipt validation failed. Our service stopped processing billing.
Below is the error when it failed.
{
"error": "invalid_grant",
"error_description": "Token has been expired or revoked."
}
I thought refresh tokens reset their expiration date each time they are used, so why did they expire?
I don't think the following rules apply.
You must write your code to anticipate the possibility that a granted refresh token might no longer work. these reasons:
The user has revoked your app's access.
The refresh token has not been used for six months.
The user changed passwords and the refresh token contains Gmail scopes.
The user account has exceeded a maximum number of granted (live) refresh tokens.
The user belongs to a Google Cloud Platform organization that has session control policies in effect.
(https://developers.google.com/identity/protocols/oauth2)
I want to use the refresh token forever.
Thank you in advance.
Refresh tokens do not expire by design there are a few things that can cause them to expire as you have listed. However there is one you have not listed.
If you check the docs for Experation you will find it also says.
If your app is in testing set it to production and your refresh token will stop expiring.
So as long as your app is in production, the user does not revoke your access, and they have less then 50 outstanding refresh tokens for that user, and you have used it at least once in the last six months. (gmail scope the user does not change their password). The refresh token should not be expiring.
That being said your system should be designed to handle a refresh token expiring and request access of the user again. or notifying the admin if this is a backend system.
Thank you for this interesting conversation. It looks like in my case, after having got an access_token and a refresh_token, which I use regulary to invoke the Gmail API, it no longer works after 6 months.
Could someone point me to a code example in Node, showing how to update the tokens on a regular basis? (I store them in a database, and wonder how to update the record appropriately via the google.auth.OAuth2 API).
I have made hundreds of searches but could not find anything else than "you should refresh your tokens" :)
It looks like
oauth2Client.on('tokens', (tokens) => {
logger.info("tokens=%o", tokens)
})
is only invoked once when establishing the connection, so it will not help.
I have also tried:
let x = await oauth2Client.refreshToken(database_refresh_token)
let refreshedToken = x.tokens.access_token
To store the new refreshed token in the database, but this does not help after 6 months. FYI, thanks to oauth2Client.getTokenInfo(refreshedToken) I can see that refreshedToken expires in 1 hour.
Finally, is there a way to test, without having to wait for 6 months?
Many thanks!
By last answer...
It means we can used one refresh token for 6 month. right ?
And after 6 month we have to update refresh token. right ?

Recaptcha v3 protection for Get request

Came from recaptcha v2 background with my own bot detection logic. I want to try out the new bot detection score feature of v3.
I want to protect my search page from being abused by bots trying to query the DB every 0.5 second.
Search result page accepts url query parameter to allow users to book mark the page. For example mydomain.com/findallcities?country=xxx&province=yyy&populationmin=5000
Based on my understanding v3 flow works like this
Client calls recaptcha JS function and get a token
Client append the token some where in the form so that server can validate the token later
Form submit and server receives the token
If server gets no token then reject. otherwise validate the token to get user score and act accordingly
So the question comes. How can I tell if its a bot that is hitting mydomain.com/findallcities?country=xxx&province=yyy&populationmin=5000 with a Get request or if its a legitimate user clicking on a bookmark? There is no token to verify and even if there is its probably an expired (used) one from before.

CSRF Token mismatch error on clicking links from email

App was developed in Web API. We are using AntiForgery Token validation for all the POST calls in xyz.com. Registered xyz.com users get email alerts for the contents they are signed up for. Users click item from email to view the content details. On click of item first click event is being saved in SilverPop and silverpop redirects to actual content in xyz.com. Details page is being loaded with out any issues after authenticating the user based on few query string parameters. Issue is when user make a post call(to saving for later, book mark etc) App is throwing Antiforgery token mismatch error. Sorry for bad English and long question. Strange part of this issue is We are unable to replicate this error and its not occurring consistently. We have two server and 1 load balance hosted in AWS not using sticky session enabled. Using Forms cookie authentication. finally, this issue kept occurring though we run with 1 server. Thanks for reading and appreciate if any one could help.
*User must be Authenticated to validate CSRF token ? This xyz.com makes few api get and post calls.

Proposing an alternative way of securing ajax calls with a stored token

Now I think securing ajax calls, sometimes normal forms with a token is pretty common. It works like this. 1) The user requests a page 2) a token is put into the html, and into the session 3) on submit these values are checked.
Now one major obstacle I am facing with this is caching. I do not have a lot of changing content, so I want to be able to cache for at least 24 hours. On the other hand, I do some ajax calls on the front-end, and good practice is to have them a little secured.
Now I was thinking of this, but I do not know if it will work. Maybe you can help.
user requests a site, and the cached site is given.
On the site, the first ajax call is made, which only asks a token
In the backend, a token is generated, stored in the session and sent to the front-end
The token is stored in a var in the frontend, and now sent with every call
On every call we check the session and the given token
If they match we do our DB stuff, if not we make a call to the FBI
The FBI takes over the case
Just kidding about the last part. But will this work, because you are not sending a piece of the actual website.
Maybe you can make it a little smarter by storing an identifier of the form the user requests.
Actually, I have no idea if this will work, I actually doubt it. Maybe someone can explain to me why this will not work.
In order to prevent csrf with a token, each user must have a unique token that an attacker cannot guess. If you serve the same cached page to everyone, then the token isn't a secret and an attacker can forge requests.
That being said. You could have some JavaScript use an XHR to pull that users token from the user's session data store and populate a form or in ajax calls.

Resources