Spring Boot: POST and CSRF
If you get 403 forbidden messages when using POST
If you are trying to do a @PostMapping
in your Spring Boot application and you are getting
the error
403 - Forbidden
The problem is likely that you didn’t include this magic line in your form:
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
The solution is to include that magic line in your form.
The reason has to do with preventing cross site request forgery.
The explanation
Suppose I was running a virtual online bank, and it had the following endpoint:
badbank.com/transfer?from=you&to=me&amount=1000000
The transfer
endpoint allows for the transfer of an amount of money from one account to another: in the above case, you’d be giving me $1,000,000.
Obviously, you’d rather not navigate to that link on accident or else you’d find yourself in financial ruin.
So I’ll just not navigate to it then
You’d think so, but consider the scenario where you encounter the following link on your favorite website:
If you hover the above link, you’ll notice that it actually navigates you to the malicious endpoint previously discussed. This method of attack is known in security as Cross Site Scripting (XSS).
This seems bad. How do we deal with it?
With CSRF tokens! Imagine now that along with amount
, from
, and to
variables, the /transfer
endpoint also required a token
value that would be generated randomly and unpredictably on the bank’s server when the client navigates to the bank’s website.
That way every request could be validated as coming from a form that their server gave to a client, and not some shady link on another website. Now the attacker can’t embed a malicious link in their website anymore, as they won’t be able to predict/fake the tokens being generated by the server.
If you want to read more about the specifics on CSRF and XSS, you can check out the following articles on PortSwigger:
- https://portswigger.net/web-security/csrf/tokens
- https://portswigger.net/web-security/csrf/xss-vs-csrf
Related topics:
- Spring Boot: —A Java web application framework
- Spring Boot: Actuator—Checking the endpoint mappings, health or other info about your Spring Boot app
- Spring Boot: Application Properties—Defining the application.properties
- Spring Boot: ControllerAdvice—A place to factor out common ExceptionHandler, ModelAttribute and InitBinder code across multiple controllers
- Spring Boot: CSV—Downloading and Uploading CSV files with Spring Boot
- Spring Boot: Database Migrations—When you need to make a change to your database schema for an app in progress
- Spring Boot: Heroku—Tips for running with Spring Boot applications on Heroku
- Spring Boot: Logging—How to write information to the log in Spring Boot
- Spring Boot: OAuth—How to implement OAuth for authentication in Spring Boot
- Spring Boot: POST and CSRF—If you get 403 forbidden messages when using POST
- Spring Boot: Postgres—Using Spring Boot with Postgres
- Spring Boot: RestTemplate—When you need to access other APIs from the backend of your Spring Boot Application
- Spring Boot: Secrets—Ways of keepings database credentials and OAuth client secrets out of Github
- Spring Boot: Security—Authentication, Authorization and other Security issues
- Spring Boot: Sessions—How to make the stateless HTTP protocol stateful
- Spring Boot: SQL—Working with SQL and Databases in Spring Boot
- Spring Boot: VS Code—Suggested VS Code extensions for working with Spring Boot