CSRF with Spring and AngularJS

Probably all but the most basic web applications need to protect themselves against Cross Site Request Forgery (CSRF) attacks.

A CSRF attacker abuses the fact that the browser will automatically sent all cookies to a web-server, regardless of the page the request is originating from. This includes any session or authentication cookies that were set after logging in. So while you are doing your online-banking, a page on another tab could easily sent a request to the banking server as well. Since the request will contain the same cookies, the banking server will believe that it is you requesting all your savings to be transferred…

Most web frameworks have built in support for handling CSRF attacks. The most common way of preventing CSRF attacks is to implement the Synchronizer Token Pattern.

This pattern involves a token being generated on the server and sent to the browser in such a way that only the javascript from current page can access this token. The javascript code will then sent this token back to the server with each request. The server only accepts the request if the token it has received matches the token it has sent before.

Of course, server and client will need to know how to receive the token and how the token needs to be sent back. At this time there is no standard defined on how the client should receive the token and how it should be sent back. So when using two different frameworks, e.g. Spring MVC and Angular JS, the two need to be aligned.

As always, spring-source provides detailed documentation on their CSRF protection measurements and how it can be applied.  Angular JS also has built in support for handling CSRF, see the documentation for $http service

Angular expects the token to be sent as a cookie called XSRFTOKEN and will sent the value of that cookie back in a http header called XXSRFTOKEN.

Spring will set the CRF token as an attribute of the request. As such it is not automatically sent back to the client unless it is included in the template used for rendering the HTML response.  Spring expects the csrf token to be sent back in a http header called X-CSRF-TOKEN.

In short, Angular needs a cookie and Spring needs to look for a header called ‘XXSRFTOKEN’ instead of ‘X-CSRF-TOKEN’.

First, we need to implement a filter that will check the request for the CSRF token and create a cookie when needed:

@Component
public class CsrfTokenAsCookieFilter extends OncePerRequestFilter {
 
  public static final String ANGULAR_COOKIE_NAME = "XSRF-TOKEN";
  public static final String ANGULAR_HEADER_NAME = "X-XSRF-TOKEN";
 
  public static final String SPRING_COOKIE_NAME = "CSRF-TOKEN";
  public static final String SPRING_HEADER_NAME = "X-CSRF-TOKEN";

  private String cookieName = ANGULAR_COOKIE_NAME;

  public String getCookieName() {
    return cookieName;
  }

  public void setCookieName(String cookieName) {
    this.cookieName = cookieName;
  }

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
    javax.servlet.FilterChain filterChain) throws ServletException, IOException {

    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
    if (csrf != null) {
      Cookie cookie = WebUtils.getCookie(request, cookieName);
      String token = csrf.getToken();
      if (cookie == null || token != null && !token.equals(cookie.getValue())) {
        cookie = new Cookie(cookieName, token);
        cookie.setPath(request.getServletContext().getContextPath());
        response.addCookie(cookie);
      }
    }
    filterChain.doFilter(request, response);
  }
}

Next we add this component in our spring.xml:

<bean name="csrfTokenAsCookieFilter" class="com.vxcompany.pnh.bms.web.security.CsrfTokenAsCookieFilter">
  <property name="cookieName" value="XSRF-TOKEN"/>
</bean>

And we tell spring that we want to use a different HTTP header for sending the token:

<bean name="csrfTokenRepository" class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
 <property name="headerName" value="X-XSRF-TOKEN"/>
 </bean>

Finally, we will add the filter and the new token repository to the security section in your spring configuration:

<security:http>
  <security:csrf token-repository-ref="csrfTokenRepository"/>
    ...
  <security:custom-filter ref="csrfTokenAsCookieFilter" after="CSRF_FILTER"/>
</security:http>

With this all in place, Angular will find the CSRF token where it expects it and Spring will know where to look for the token when Angular sents it back.

Custom queries in Spring Data Repositories

With Spring Data it is quite easy to create Repository implementations without writing actual code. All you need to do is specify the interface for the repository and define the query and parameter binding using annotations.

Using Spring Data a typical repository may look something like this:

public interface EmployeeRepository 
   extends CrudRepository<Employee, Long> {

   @Query("select e from Employee e where e.name like :name")
   Employee findByName(@Param("name") String name);
}

Spring Data will pick up this interface and supply a working repository implementation for you at runtime. The Spring Data annotations support parameter binding, all sorts of data types and native queries as well.

Personally, I prefer to keep my repositories as simple as possible. I usually have a service in front of the repository where I can put any additional logic or code that may be required. So usually Spring Data matches perfectly and I hardly ever need to code repositories any more.

But recently I encountered a use case where the standard annotations just weren’t sufficient. I needed to add a result transformer. For this I needed access to the underlying Hibernate session and set the transformer on the query manually. Of course I did not want to add another repository just for this method. I did not want to have to rewrite all the queries that were implemented with the annotations either. Fortunately Spring Data allows to combine the two, add custom methods to a repository interface that uses Spring Data.

First you will need to define a new interface that contains the signature of your custom method:

public interface EmployeeRepositoryCustom {
   List<Employee> findByAddress(String zipcode, String houseNumber);
}

The interface is straight forward and does not contain any special stuff from Spring, Spring Data or even JPA. It simply defines the signature of your custom repository method.

Next we will need to supply an implementation for the custom part of the repository. Personally I had already forgotten what a repository implementation looked like so here is the full listing:

@Repository
@Transactional
public class EmployeeRepositoryCustomImpl 
   implements EmployeeRepositoryCustom {

   private EntityManager entityManager;

   @PersistenceContext
   public void setEntityManager(EntityManager inEntityManager) {
      this.entityManager = inEntityManager;
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<Employee> findByAddress(String zipcode, String houseNumber) {
      String ql = "select e from Employee e where ...";
      Query q = entityManager.createQuery(ql);
      return q.getResultList();
   }
}

Finally, we will make the original repository extend the new custom interface:

public interface EmployeeRepository 
   extends CrudRepository<Employee, Long>, 
           EmployeeRepositoryCustom {
...
}

Since the EmployeeRepository extends the custom interface we can now access all of the original methods and our new custom method. Spring Data will create the implementation for the annotation based same as before but will also use our custom implementation as delegate for the method defined in EmployeeRepositoryCustom.

Please not that this example does not actually do anything specific, it could have been implemented with standard annotations as well. But obviously, with the custom implementation you now have access to the entity-manager and you can add your custom code as needed.

Better API with Java’s Optional

“For a language that has no pointers I sure get a lot of null-pointer exceptions!”

Okay, an old and lame joke. Of course Java has pointers (just no pointer arithmetic) and checking for null values is part of every day live for a Java developer. We are used to writing code like:

String street = person.getAddress() != null?
    person.getAddress().getStreet() : null;

But unless you are a very defensive, paranoid type of developer, changes are that you occasionally skip a check or two. Let’s face it, we have all seen code like this:

String street = person.getAddress().getStreet()

Depending on the context this may or may not be a bug. Perhaps in the particular domain all persons are guaranteed to have an address or maybe this person’s address has already been checked for a null value way before this line is reached. But from the code snippet itself it is not clear if address might be null or not.

Java 8 introduced the Optional class. Optional is a generic class that allows to pass or return values that are explicitly marked as optional: there may or may not be a value. The purpose of Optional is to help design better API’s.

Suppose we change the API of Person to use the optional class:

public class Person {
   public Optional<Address> getAddress() {...}
}

Now it has become very explicit that address may be null and that the calling code needs to deal with null values. For our convenience the Optional class provides all sorts of methods that help doing just that. For example, to safely obtain the street we can now write:

String street = p.getAddress()
   .map(Address::getStreet)
   .orElse(null);

As you can see there is a bit of functional programming going on there. It is Java 8 after all. We pass the getStreet method to the map method and the Optional will either invoke the getStreet function if it contains a value, or return null if there isn’t. If you are not yet familiar with Java 8 and the functional programming API then the latter method will probably be harder to read, cryptic even.

So why the fuss? Well, Optional is a container that wraps a value. It isn’t the value itself. Apart from being a clear indication that the value may be null, you are forced to deal with it as well. You can no longer invoke getAddress().getStreet() anymore. It won’t compile because getAddress returns Optional and not Address. You can not even assign ‘p.getAddress().map(Address::getStreet)‘ to a string since the return value of the map method is an Optional as well. Hence, you are forced to explicitly declare what should happen if there isn’t a value.

But Optional provides more than just plain mapping values. For example:

person.getAddress()
   .filter(address -> "Amsterdam".equals(address.getCity()))
   .map(Address::getStreet)
   .orElse(null));

will give us the street but only if the address is in “Amsterdam”. Again, a bit cryptic if you are new to Java 8 but a lot more compact and more expressive then if you were to write this out using nested if statements.

Using optional can create a better and easier to understand API. However, the optional will not rid us of null-pointers. It wasn’t designed for that either. Just because a method returns the real value instead of an optional, does that mean it will never be null? If you find the occasional Optional in an API, would you trust all other ‘plain’ values never to be null? Probably not. Not yet anyway.

But it will be interesting how Optional will find it’s way into libraries and projects. Will developers use it consistently and will it make a libraries easier to use? Or will we eventually curse all these in between containers and wish for the plain values instead?