CSRF Protection in Spring

In this tutorial you will learn how to protect your application against CSRF.

java-featured-image

What is CSRF?

If you already know what CSRF, feel free to continue without reading this sub-point. But if you don’t, CSRF stands for cross-site request forgery and simply put, it is when attackers make authenticated users to perform an action on the website. The consequence – unauthorized users perform actions that are trusted by the web application. 

A classical example of that is when a user logs in, the website sends token information that is assigned to a cookie as part of the response. Now that the user has logged in, the attacker tries to make the user visit the attacker’s website from where the CSRF attack would start. To make the user visit his website, the attacker usually sends an email over email. If the user has clicked on that link, there is 1 or even more APIs on the website. A request is sent along with the cookie information which was sent earlier as a result of the user’s visit. Now the attacker is able to make unauthorized changes to the user’s data/account like transferring money for example.



How to prevent from CSRF?

There are a couple of ways that can prevent CSRF.

One of them is by enforcing the same origin policy. Under this policy, a web browser permits scripts that are contained in one web page to access data in another web page but only if both web pages have the same origin. This method depends on HTTP Cookies.

Another one is by applying per-session/per-request token that filters requests that are coming as a CSRF attack.

How to prevent from CSRF in Spring implementation

public class TokenFilter extends OncePerRequestFilter {
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
		CsrfToken csrfToken = (CsrfToken).request.getAttribute(CsrfToken.class.getName());
		
		if (csrfToken != null) {
			Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");
			String token = csrf.getToken();
			
			if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
				cookie = new Cookie("XSRF-TOKEN", token);
				cookie.setPath("/");
				response.addCookie(cookie);
			}
		}
		
		filterChain.doFilter(request, response);
	}
}

Breakdown

We create a class called TokenFilter that looks for a specific cookie which, in this case, is called XSRF-TOKEN. 

Cookie cookie = WebUtils.getCoookie(request, "XSRF-TOKEN");

If there isn’t one, we are creating one and assign the token value and then we add the cookie to the server response.

if (cookie == null || !(token.equals(cookie.getValue())) && token != null) {
	cookie = new Cookie("XSRF-TOKEN", token);
	cookie.setPath("/");
	response.addCookie(cookie);
}

So we managed to prevent CSRF by writing our own Filter class which looks for a specific cookie and if it exists, it adds it to the server response and if it doesn’t, create a new one with the name given.

Leave a Reply

avatar