CSRF Token unexpectedly expires - spring-boot

I have an app built with Spring Boot, it's using Apache Tomcat 8.5.53.
It all works fine, but sometimes my users get the following message:
HTTP Status 403 - ForbiddenType Status ReportMessage Invalid CSRF Token '1423gi43-3452-65t3-cg8d-21a75cd7gc3x' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'
Then they refresh the page, login and it all works fine.
This doesn't always happen, and it doesn't happen for the same request. My users perform normally other operations before they see this message. However, it happens most of the time on post or patch requests.
I have seen issues on stackoverflow where token is null, but in my case it randomly expires.
I don't want to remove the token.
Has anyone experienced (and hopefully solved) this issue before?

Related

Postman request receiving cookies but Postman not detecting them

I've recently started using Postman and I am testing an API where I get a CSRF token and then login but I always get a CSRF token mismatch. I am including X-XSRF-TOKEN header but I think the issue is around the cookies not being stored correctly.
I am calling a Laravel Sanctum endpoint to get a CSRF token and when I look in the in the console I can see Set-Cookie response headers
However, when I look in the cookies tab it says no cookies were received from the server
However, when I look at the cookies store they are listed for my test domain (home.local)
Due to this issue, when I send a request to the login, the session cookies are not sent in the request as shown in the console on the request to the login endpoint
I can do this fine using Insomnia.Rest client so I know the API is working as expected - I am however trying to replace Insomnia with Postman.
I've tried Google, but I've only found some bugs that were introduced that seemed to cause something similar back in 2016
Update
I managed to Postman working with production fine using a pre-request script to get the CSRF token and set the environment variable using the below:
const url = pm.environment.get('base_url');
const referer = pm.environment.get('Referer');
pm.sendRequest({
url: `${url}/sanctum/csrf-cookie`,
method: 'GET',
}, function (err, response, {cookies}) {
if (!err) {
console.log("cookies", cookies);
pm.environment.set('xsrf_token', cookies.get('XSRF-TOKEN'))
}
});
Although this worked on production and successfully did the POST request, on my local dev PC, I was still getting the CSRF mismatch.
Although the request/response looked the same between dev/and prod I for some reason had the idea to change my dev URL from my-app.home.local to my-app.home.com and now the cookies are received and send in the next request to login without getting a CSRF token mismatch.
There's clearly an issue with postman here but not sure if it's something I'm doing or a bug in Postman. Does .local mean something different?

Why am I getting a 403 error in a post request in JMeter?

I'm trying to record a script in JMeter for a website. I'm supposed to login, click on submissions, click on one of the submitted documents then logout. I've correlated everything but I'm getting a 403 forbidden error on one of the requests. During the penultimate step of clicking on one of the submitted documents, it sends a post request to the server which looks like this :
Request
I'm getting a 403 error on this request. I've tried correlating every single variable in that request but I still get a 403 error. Any suggestions?
As per HTTP Status 403 description:
The HTTP 403 Forbidden client error status response code indicates that the server understood the request but refuses to authorize it.
This status is similar to 401, but in this case, re-authenticating will make no difference. The access is permanently forbidden and tied to the application logic, such as insufficient rights to a resource.
So unless there is a bug in the application the status means that the logged in user doesn't have enough permissions to execute the request (submit the documents), try checking the username/password (or whatever is the authentication approach) using Debug Sampler and View Results Tree listener combination and ensure that the user is allowed to perform this action.

403 error response from IIS on almost alternate request while load testing api

I have a web api which is deployed on IIS.
Api's are going through load test using load runner and almost on all alternative api call, getting 403 error response code, struggling to identify the issue, call is not going to the API, its returned back from IIS
I am doing bearer token authorization, somehow token which were incoming with each request were not valid, that is why the issue was occurring, to overcome this we have increased the lifetime of token to 1 hour and request load test team to generate the token once and send that token only with each request so that we can now see the proper execution time for each end point.
403 error indicates that access to the requested URL by the client is Forbidden for some reason. you need to provide detailed error message snapshot and what is the sub status code. and check that you assign this permission to the site folder:1) IIS_IUSRS,2)NETWORK SERVICE,3)IUSR

Sails JS CSRF Token is different every call

I want to enable CSRF in my SailsJS and Angular 2 application but I have been having endless problems.
The Angular app is on a page that is only accessible after a user has logged in, controlled by Sails policies.
Then I http.get the CSRF token from the /csrfToken route and store it, adding it to HTTP headers when doing a POST.
I was continually getting CSRF mismatch errors and I finally realised that the /csrfToken route was returning a different value every time, both from a http.get and also when accessing the URL from the browser.
It wasn't clear that this was happening when I went through this tutorial (see 00:30) for a multi-page application where the CSRF value is submitted as a hidden field in a form, and there doesn't seem to be any mention of how to change this behaviour in the Sails documentation.
How can I configure Sails so that it will maintain a single CSRF value for a session?
UPDATE: It’s working now
I have made my update an answer as advised.
It turns out that there were different issues that were causing my problems.
My code had become so fragmented that I didn’t realise I was referencing an older function that was putting the CSRF into the header wrong.
I rolled back a bunch of client-side code and then magically the CSRF value remained consistent between Ajax calls and also worked correctly in the POST request.
So I guess there was something in my fragmented code that had caused the CSRF token to change between API calls but I don’t know what it was.
Visiting /csrfToken in the browser still produces a different result every time but it does not seem to affect the API calls.
EDIT
I discovered that the CSRF changes with each request to /csrfToken. One of my mistakes was that after I stored the CSRF value the first time I then (accidentally) requested a new /csrfToken again later, which then invalidated the stored value. Using the stored value would then result in a CSRF mismatch error as a new value had been issued.

Drupal services/cors api not accepting CSRF token

I am using polymer to send ajax requests to my Drupal services api.
I send a POST to login and then a POST to create a node. When I login I am given a token which I store and pass to the next request.
I am monitoring the the requests and responses with Charles, the token is being sent, the cookie is being set and passed on the 2nd POST but I get an "Unauthorized : CSRF validation failed" response.
When I send the request with Postman It works like a dream but for some reason it doesn't validate when sent with my app.
I have checked the token being set matches the one being sent and the only difference I've noticed is that when it's being sent again there is a prefix of ga_; something to do with google analytics?
The expiry of the token is a month away the token matches what is returned at login and is being sent correctly. The header accepts X-CSRF-Token in the Access-Control-Allow-Headers.
My CORS module code is:
api/*|<mirror>|GET, POST, PUT, OPTIONS|Authorization, Origin, Content-Type, X-CSRF-Token|true
If any body has a similar issue, mine was caused by a couple of things, running Drupal and my app in the same browser causing all kinds or cookie conflicts and when passing parameters to my function that computes my request, if there were any parameters that were not used it breaks.
Hope this helps someone.

Resources