Regarding Cross site Scripting Forgery - spring

I am working on csrf and using spring 5. Spring 5 automatically provide supports for csrf and on enabling csrf protection on the server side I am getting
403: Invalid X-CSRF token
So this means a token needs to come from frontend?
My understanding is that backend generates csrf token and sends as a response to frontend browser and then it uses this token and send it as cookies to the backend server and then backend will validate it. is my understanding is correct?
when manually generating the hidden token for csrf, How backend will know it is a valid csrf token?
Second Scenario: Suppose two users are logged in to my website and frontend is sending this token to backend then how the application will differentiate which token is for which user?
Also please explain how it works internally means we enabled csrf protection in the backend and manually generated a token on the front end then what it does behind the scenes?
consider my frontend is JS pages
Is there is any specialty of Spring 5 which take care's of sessions for each user and validate tokens automagically for each user?. I tried finding it on the official website but didn't get it anywhere

Hi Zaib the csrf token is generated from back-end as you stated, once it is generated is automatically sent to the front-end which must take care to retrieve from the model and re-post for each "POST" requests.
You can share the csrf token via different way mostly i used header or html parameter.
A token is related to a specific session so is not really important if you have a logged user or not , even not authenticated users must send the csrf token for "POST".
The csrf token is validated via a filter placed in the front of the filter chain defined by Spring security itself, if you search in the documentation there is a table showing you the position of each "default" filter enabled by Spring security. Moreover if you enable debug on Spring ( </debug> is enough in your xml configuration) you will have printed all the filters used while processing an http request.
So each time a request with "POST" method pass through that filter , it will check if in the parameters there is the csrf token or header.
I never used as cookie so it may a different case for you if specifically need that but it does not differ on how it works.
Here is the details of csrf implementation on Spring:
https://docs.spring.io/spring-security/site/docs/5.0.7.RELEASE/reference/htmlsingle/#csrf-configure
I said "POST" method but actually the token is checked for any method that is related to a change of state , you can refer to doc here:
https://docs.spring.io/spring-security/site/docs/4.2.5.RELEASE/apidocs/org/springframework/security/web/csrf/CsrfFilter.html
Hope this help clarifying a bit the usage of the csrf token.

Related

CSRF token in rest api

Using CSRF token in rest API is helpful or not ? as far as I know we don't have a session so we should send the token to client for next request or for submitting the form.
Is it helpful to use it again in ajax(xhr) calls. are there any alternatives ?
I've been reading the spring documents for this, and it also has some examples. but I was curious that is it really helpful or not ?
By the way My server is spring 2.2 and my client is Angular 9.
Thanks
CSRF tokens are essential for preventing XSS attacks, for instance you are logged into your bank, in one tab, and visiting my malicious site that will send a hidden form to your bank stealing your credicard number.
If you want to build a more secure site, every request that manipulates the state in the backend (POST, PUT, DELETE etc) should have a CSRF token included, to ensure that the request came from forms on your site and only your site.
You can read more about CSRF tokens on Owasps webpage.

Why should we call sanctum/csrf-cookie on Laravel Sanctum

I was reading document, and one question occurred. Why would we need to call this endpoint /sanctum/csrf-cookie to get CSRF protection when login?
I understand what CSRF is, and per my understanding, the practice that Laravel uses to prevent CSRF is to set a cookie xsrf-token on browser and then Angular or some framework would automatically attach the cookie to header as x-xsrf-token, and it's also called server side double submit as one of the practices to prevent CSRF
However, I just don't get why on Laravel Sanctum we have to manually call /sanctum/csrf-cookie before login. With Web guard, this protection is automatic after login without any manual work before login.
My question is what is the benefit or logic for calling /sanctum/csrf-cookie before login rather than automatically sending x-csrf-cookie to browser via response after login?
Anyone could help to further explain will be so much appreciated.

How are CSRF tokens stored on the server side ( by spring security or tomcat)

This question is not about how CSRF tokens works, but is rather about they are stored on the server side.
In short, CSRF tokens are generated by server and injected in to the web page/form. When the form is submitted the csrf token is extracted by the server and compared to the one saved on the server. So far so good.
From this earlier posting - CSRF token value when same page is opened in two tabs on same machine?
Here's the excellent answer which explains that -
The server will create a CSRF token (token1) and store that token in
the HttpSession. The CSRF token (token1) is also be embedded in the
form on the client side. The client is also given a Session ID
(session-id1) which is stored in a cookie.
When the client submits the form, it sends token1 and session-id1. The
server will then use session-id1 to look up the HttpSession and get
the expected CSRF token for that session. It will compare the expected
CSRF token to token1 and if the values do not match, the HTTP request
will be rejected.
and
If you open the same form in another tab, the browser will still have
access to the Session ID (session-id1). That form will get the same
token (token1) that was associated with session-id1.
In the end, there is only one CSRF token (token1) that is used in both
tabs.
Bit more info can be found in the quoted reference, but it fails to explain the server side part.
The above leads to more questions -
If another form (form2) is opened by user in a different tab - then what CSRF token will it get, will it be same as that for the first form(form1) ?
To explore and unsderstand better, I want to know where and how the CSRF tokens are stored in the backend when using spring security (unlike Session Cookies which are generated by Servlet Container, I am assuming that CSRF tokens are generated by Spring Security module). Is there just one CSRF token per session, which is used accross every form and every tab or there are several CSRF tokens.
Please clarify as much as you can... every drop counts

CSRF token value when same page is opened in two tabs on same machine?

From my understanding, when CSRF is enabled on server side, the server creates a token (say token1) and injects it in to the form and saves the same in the cookie of the client browser.
When the client sends the form request to the server, it sends the csrf token (token1) from browser cookie and also send the same token as in the form. The server validates the request by checking that the token in cookie and the token in form match and then processes the request.
Now, if i open the same form in another tab, will the server generate another token (token2) and inject it in to the form and cookie. Then, in the cookie, token1 will be overwritten by token2. So the submission of the form in first tab will not work in this case? But from experience i see that the submission of form in tab 1 still succeeds.
So can some one explain how it's succeeding in the above scenario??
Since you have added the Spring Security tag, I will describe how Spring Security uses the Synchronizer Token Pattern to protect against CSRF attacks.
the server creates a token (say token1) and injects it in to the form and saves the same in the cookie of the client browser.
That's not exactly what happens. The server will create a CSRF token (token1) and store that token in the HttpSession. The CSRF token (token1) is also be embedded in the form on the client side. The client is also given a Session ID (session-id1) which is stored in a cookie.
When the client submits the form, it sends token1 and session-id1. The server will then use session-id1 to look up the HttpSession and get the expected CSRF token for that session. It will compare the expected CSRF token to token1 and if the values do not match, the HTTP request will be rejected.
If you open the same form in another tab, the browser will still have access to the Session ID (session-id1). That form will get the same token (token1) that was associated with session-id1.
In the end, there is only one CSRF token (token1) that is used in both tabs.
You can find more information about protection against CSRF attacks in the Spring Security reference documentation.

Spring Security - REST API - token vs. cookie

I have written a REST- API in Java and I have secured this API with Spring Security. The procedure is like this:
Frontend invokes /login RestService in Backend
Backend gives back token to frontend
at each REST- API Backend invokation the token has to be placed in header
This works fine, but I have read that it is also possible (with Node.JS/Passport.js/Express.js) that the session object with the cookie inside can be transfered out of the box without any custom code.
My question now would be if there is a better approach so that the frontend/client do not need to set the token into the header all the time for any request.
Usually token based authentication has advantages over cookie based.
You can achieve this using middle-ware layer
Here is a good Post - https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
Server side, I usually first check in the headers if there is an auth token. If not, I then check in the cookies as a fallback.
If you want to use cookies, then at your step 2, you need to add a Set-Cookie header to the response, so that browsers know they must store a cookie. Once done, no need to add a header client-side, since browsers will send cookies each request. You'll need to add a CSRF protection though (here is a good example).

Resources