The CSRF Protection with Spring Security | Spring Boot Backend #3.5
Ғылым және технология
In this video I will explain the CSRF attack, the Cross-Site Request Forgery attack. I will show how Spring Security can protect against this attack, in both a server side rendering server and with a separated frontend and the Cookie repository.
This is the fifth part of the third video of a playlist where I show how to create a Spring Boot Backend, how to create a website step by step: • Spring Boot
Content:
* What is the CSRF attack, the Cross-Site Request Forgery attack;
* What are the typical mistakes made with this attack;
* How to allow multiple origins to request my backend;
* How to enable the CSRF protection in Spring Security correctly.
Repository: github.com/serlesen/backend-s...
My NEW eBook: sergiolema.dev/git-book/
Blog: bit.ly/47ornJL
LinkedIn: bit.ly/41Nn61q
Facebook: bit.ly/47rc9nh
My Desktop:
• Laptop: Macbook Pro 16' 2019
• Gaming Chair: amzn.to/47Vu6ed
• Mouse: amzn.to/3HoBwM1
• Desk: amzn.to/48Tc5Oi
• Screen: amzn.to/48VZkCL
Icons:
* Cookie by Satawat Anukul from NounProject.com
* Server by Paulus Agus Setiawan from NounProject.com
* Webpage by Bucky Clarke from NounProject.com
Пікірлер: 71
Thank you so much for this! You explained in 8 minutes what people couldn't explain in a 1 hour video.
@TheDevWorldbySergioLema
Жыл бұрын
So glad it helped you Venera!
Thanks you for the video, you are the best
@TheDevWorldbySergioLema
Жыл бұрын
Thanks to you for those kind words!
Great explanation
@TheDevWorldbySergioLema
2 жыл бұрын
Thank you!
Great job, very helpful! Youre the 'Macho'
@TheDevWorldbySergioLema
2 жыл бұрын
Gracias!
Great one, thanks!
@TheDevWorldbySergioLema
2 жыл бұрын
Thanks to you for watching and following!!
Great video!
@TheDevWorldbySergioLema
2 жыл бұрын
Thank you!
Great video
@TheDevWorldbySergioLema
2 жыл бұрын
Thank you!
Hi Sergio. This is a great video. Thanks. I also want to know at what point you call the CsrfController endpoint from React. Do you have a video that shows this?
@TheDevWorldbySergioLema
Жыл бұрын
Thanks! I call it at the beginning, when the React application is loaded. Sorry, I don't have neither a video about the React part neither the Github repository of the React project. Maybe I should update this video with a more complete part on the frontend.
Thanks you for the amazing video. Can we have the repo with the frontend because I am interested in how you handle the csrf/cors there too? Much love from Bulgaria!
@TheDevWorldbySergioLema
Жыл бұрын
I'm sorry, but i didn't save the frontend project. In the frontend project, I first call the CSRF endpoint and store the token for further requests, nothing more.
Can you show me where in your react frontend you have implemented sending "X-XSRF-TOKEN" header ?
@TheDevWorldbySergioLema
2 жыл бұрын
I've just enabled axios.defaults.withCredentials, and the header and cookies are sent automatically when received from the backend.
great but one thing that is not clear:your front end in React should call the CSRF controller when it start up ? Or when the user login ?
@TheDevWorldbySergioLema
2 жыл бұрын
It should call the backend at the start up. This way, the frontend get an initial token to start the communication with the backend at any endpoint (POST, PATCH, PUT or DELETE).
Hola, tengo una duda, el cookie y el header están devolviendo tokens diferentes, tienes alguna idea de por qué? Gracias
@TheDevWorldbySergioLema
2 жыл бұрын
En una misma llamada, el cookie y el header tienen que devolver el mismo token (acabo de revisar el video, y en el minuto 7:00 veo que el cookie y el header son identicos). En las siguientes llamadas, después del login, el token será modificado para asegurar una continuidad en las llamadas.
Podrias mostrar el codigo del login page. Lo que entiendo es que utilizas useEffect para llamar el servicio de generacion del token _csrf. Eso actualizar el _csrf del header. Y tienes un campo en tu forma con el _csrf. Si el _csrf header es diferente al capturado ... hubo modificacion por parte del usuario.
@TheDevWorldbySergioLema
2 жыл бұрын
Podría haber utilizado useEffect, pero tan solo llamo al endpoint "/v1/csrf" al cargar la página. Además he activado la opción de axios "axios.defaults.withCredentials = true" para almacenar en todas las llamadas el token CSRF. No tengo el cógido del login almacenado en ninguna parte, había hecho algo rápido para el vídeo y nada mas, lo siento.
if my spring boot application, accept request from frontend web application and mobile application, is this configuration affect the mobile side ?
@TheDevWorldbySergioLema
3 ай бұрын
Yes, the CSRF impacts all the endpoints. You have to handle the cookies session when using the requests from the mobile application. An alternative is to use different endpoints for the frontend and for the mobile. Then apply the CSRF only for the frontend endpoints.
Hi, Should this work in Postman? I'm getting 403 for very request, even tho I hit the /csrf endpoint before each request. (Using SpringBoot 3.2.1)
@TheDevWorldbySergioLema
6 ай бұрын
It should work from Postman. But you need to link your Postman to a browser to store the cookies. First you need to query the CSRF endpoint, then the rest of the endpoints using the CSRF token and the cookie.
@rauliciii
6 ай бұрын
@@TheDevWorldbySergioLema Thank you for your response
Hi, I see a fall in this approach. If the Bad Site uses (lets say) a JavaScript Block and calls the /csrf API before calling the /deleeteAllData API (making 2 requests one after the another). The first request would ensure you have a Token ready (or overriding your existing token from cookie). That would ensure the success of the second request. Am I missing something?
@TheDevWorldbySergioLema
6 ай бұрын
Yes, you're right. Nevertheless, in the backend side, you can check which action was made with which CSRF token. Knowing that some behavior was not intentioned, you can trace it very easily.
@rauliciii
6 ай бұрын
@@TheDevWorldbySergioLema Thank you so much for responding. I don't understand how would tracing help.
@TheDevWorldbySergioLema
6 ай бұрын
You can log the details of each action. If you know about an action that shouldn't be done, you can revert it. Let's say the operation was withdrawing money from a bank account. If you know that the CSRF token wasn't the one used by the user, you can revert the withdraw easily.
how to check whether the csrf token is valid if our code is running on multiple servers
@TheDevWorldbySergioLema
Жыл бұрын
You can also save the CSRF token in another repository, the HTTP Session repository (docs.spring.io/spring-security/site/docs/3.2.x/apidocs/org/springframework/security/web/csrf/HttpSessionCsrfTokenRepository.html). Then, you can serialize the HTTP Session somewhere (like Redis) and share it across many instances (as done in this video kzread.info/dash/bejne/i4uKzNCDo624d5M.html)
Thank you so much for the video. I tried the same without controller csrf itself , spring is validating the csrf token from header& cookie for login and same is not working for logout , even if I change to post method and I am not sending the csrf token to frontend..
@TheDevWorldbySergioLema
Жыл бұрын
Thank for watching. I'm not sure to understand the problem with the logout. Do you mean that the CSRF token isn't validated with the logout request? I think Spring Security has a default behavior for the logout request, it already removes all the CSRF, and clears the session. Which means that after a logout, you must start again with a new CSRF token.
@sharrmilaadevi9261
Жыл бұрын
@@TheDevWorldbySergioLema Thanks for your time..Yes ..logout is giving forbidden request Error even if we give correct token
@TheDevWorldbySergioLema
Жыл бұрын
If you disable the CSRF in Spring Security, you still get the same error? (just to discard other problems)
Can you let me know how to enable csrf token in spring cloud gateway application?? Thanks in advance
@TheDevWorldbySergioLema
2 жыл бұрын
Sorry, I've never tested this configuration. Maybe this question in StackOverflow can guide you (stackoverflow.com/questions/70363882/spring-cloud-gateway-post-forbidden-with-csrf-enable) If that's the case, let me know, I'm interested.
With your config I'm always getting the same csrf token back! Edit: It does not refresh when I use that token to authorize / get an jwt token, but it refreshes on all other post requests.
@TheDevWorldbySergioLema
Жыл бұрын
I'm not sure about what first endpoint you're talking about. The token should refresh at each POST request in fact.
@TechFrame-kr1fv
Жыл бұрын
@@TheDevWorldbySergioLema It actually does not refresh when I call my /auth endpoint and it is a POST endpoint that I use to login.
@TheDevWorldbySergioLema
Жыл бұрын
You should have a different CSRF token at each POST/PUT/PATCH endpoint. The first one is the one generated by the csrf endpoint. The fact that you get a different token at all the requests, is ok. The fact that you get the same token when calling the auth endpoint it's not ok. Maybe you're returning (or Spring) the initial token with the auth endpoint (when starting a new Spring session). You can read more about this here: docs.spring.io/spring-security/reference/features/exploits/csrf.html#csrf-protection-stp and here cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern
@TechFrame-kr1fv
Жыл бұрын
@@TheDevWorldbySergioLema Thanks a lot for the support. You just earned yourself a new subscriber :D
@TheDevWorldbySergioLema
Жыл бұрын
I'm happy with that 😅
es normal que el valor del token y el valor de la cookie sea distinto?
@TheDevWorldbySergioLema
Жыл бұрын
No estoy seguro, pero creo que deberían tener el mismo valor. Por lo menos después de la primera llamada.
is the /v1/csrf controller needs to be called on launch of the UI?
@TheDevWorldbySergioLema
Жыл бұрын
Yes, it's the first endpoint to call. This returns you a token to be used in the following requests.
@ProjectAryawarta
Жыл бұрын
@@TheDevWorldbySergioLema I am already using JWT bearer token, will these configuration still valid?
@TheDevWorldbySergioLema
Жыл бұрын
Yes, those are two different tokens, totally independent and compatible
Any good way to write JUnit test for it?
@TheDevWorldbySergioLema
Жыл бұрын
You can do it with the dependency spring-security-test as described here, stackoverflow.com/questions/25605373/unit-testing-controllers-with-csrf-protection-enabled-in-spring-security
@Tengil
Жыл бұрын
@@TheDevWorldbySergioLema ah good stuff. What about if i want the test for the controllers to check if the token is valid.
@TheDevWorldbySergioLema
Жыл бұрын
You mean testing the CSRF protocol? I think this is internal to Spring Security, I'm not sure you can test it (I would say: trust Spring Security 😅)
@Tengil
Жыл бұрын
@@TheDevWorldbySergioLema Yeah. Maybe thats for the best.
So I have a problem, the header value is wildly different than the one stored in the cookie. For example, my original was 8531a7ca-8cec-4f9a-b4b2-50dfd1623e69 but the token i got was 24Pt9bnLMGDtiB1OqVYManBJ8euDfLhDRfyxp8KBr_QUAglB47bexNj8UwHAsH4ryns4DEko3Im3HopucMzVwaawmcYnZz94. Why is that???
@TheDevWorldbySergioLema
Жыл бұрын
There is the cookie session and the CSRF token. They have different usage. You must manually store the CSRF token in the frontend and use it for each request. The cookie session is automatically handled by the browser.
It looks like you had mixed spring security 6 and 5-. Do I right? I try to found solution for spring security 6 a lot of time and can't
@TheDevWorldbySergioLema
Жыл бұрын
Yes, in this video not all the features of Spring Security 6 were released. I had to use Spring Security 5.
@vh3104
Жыл бұрын
@@TheDevWorldbySergioLema Thanks for the answer. So I'll follow your solution - if more experienced developers use SS5, so why do I can't? :)
Getting error while calling GET /v1/csrf from angular: No primary or single unique constructor found for interface org.springframework.security.web.csrf.CsrfToken
@TheDevWorldbySergioLema
Жыл бұрын
In my case, I use lombok to generate the constructors. If you don't use Lombok, you have to write the constructors manually.