Skip to content

Instantly share code, notes, and snippets.

@shimarin
Last active August 29, 2015 13:55
Show Gist options
  • Save shimarin/8731533 to your computer and use it in GitHub Desktop.
Save shimarin/8731533 to your computer and use it in GitHub Desktop.
A servlet filter which provides functionality supports AngularJS's XSRF protection scheme.
package com.walbrix.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class AntiXSRFFilter implements Filter {
private String[] methodsToBeProtected = new String[] {"POST","DELETE","PUT"};
private boolean isMethodToBeProtected(String method)
{
for (String m:this.methodsToBeProtected) {
if (m.equals(method)) return true;
}
return false;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String methodsToBeProtected = filterConfig.getInitParameter("methodsToBeProtected");
if (methodsToBeProtected != null) {
this.methodsToBeProtected = methodsToBeProtected.split("\\s*,\\s*");
}
}
@Override
public void doFilter(ServletRequest _request, ServletResponse _response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) _request;
HttpServletResponse response = (HttpServletResponse) _response;
if (isMethodToBeProtected(request.getMethod())) {
HttpSession session = request.getSession(false);
String header = request.getHeader("X-XSRF-TOKEN");
if (session == null || header == null || !header.equals(session.getId())) {
// It's possibly a cross site request
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Token mismatch");
return;
}
}
response.addHeader("X-Content-Type-Options", "nosniff");
Cookie cookie = new Cookie("XSRF-TOKEN",request.getSession(true).getId());
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<filter>
<filter-name>AntiXSRFFilter</filter-name>
<filter-class>com.walbrix.servlet.AntiXSRFFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AntiXSRFFilter</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
</web-app>
@eliotstock
Copy link

You're simply using the session ID as the token here, right? Shouldn't there be some extra randomness to it at least, or better, it changes on each request?

Also, the token won't be there yet on the first POST, DELETE or PUT, if I'm reading this right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment