5.3.5 Preventing cross-site request forgery
Cross-site request forgery (CSRF) is a common security attack. It involves subjecting a user to code on a maliciously designed web page that automatically (and usually secretly) submits a form to another application on behalf of a user who is often the victim of the attack. For example, a user may be presented with a form on an attacker’s website that automatically posts to a URL on the user’s banking website (which is presumably poorly designed and vulnerable to such an attack) to transfer money. The user may not even know that the attack happened until they notice money missing from their account.
To protect against such attacks, applications can generate a CSRF token upon displaying a form, place that token in a hidden field, and then stow it for later use on the server. When the form is submitted, the token is sent back to the server along with the rest of the form data. The request is then intercepted by the server and compared with the token that was originally generated. If the token matches, the request is allowed to proceed. Otherwise, the form must have been rendered by an evil website without knowledge of the token generated by the server.
Fortunately, Spring Security has built-in CSRF protection. Even more fortunate is that it’s enabled by default and you don’t need to explicitly configure it. You only need to make sure that any forms your application submits include a field named _csrf that contains the CSRF token.
Spring Security even makes that easy by placing the CSRF token in a request attribute with the name _csrf. Therefore, you could render the CSRF token in a hidden field with the following in a Thymeleaf template:
<input type="hidden" name="_csrf" th:value="${_csrf.token}"/>If you’re using Spring MVC’s JSP tag library or Thymeleaf with the Spring Security dialect, you needn’t even bother explicitly including a hidden field. The hidden field will be rendered automatically for you.
In Thymeleaf, you just need to make sure that one of the attributes of the <form> element is prefixed as a Thymeleaf attribute. That’s usually not a concern, because it’s quite common to let Thymeleaf render the path as context relative. For example, the th:action attribute shown next is all you need for Thymeleaf to render the hidden field for you:
<form method="POST" th:action="@{/login}" id="loginForm">It’s possible to disable CSRF support, but I’m hesitant to show you how. CSRF protection is important and easily handled in forms, so there’s little reason to disable it. But if you insist on disabling it, you can do so by calling disable() like this:
.and()
.csrf()
.disable()Again, I caution you not to disable CSRF protection, especially for production applications.
All of your web layer security is now configured for Taco Cloud. Among other things, you now have a custom login page and the ability to authenticate users against a JPA user repository. Now let’s see how you can obtain information about the loggedin user.
