Search code examples
javaweb-servicesjakarta-eejax-rscsrf

Webservice and Cross-Site Request Forgery


I'm having difficulties how to prevent CSRF against my JAX-RS webservice.

the setup

The REST-webservice provides data to a JavaScript MVC-Framework, which runs client-side. The Framework will call the webservice via ajax-requests.

All users are authenticated and the webservice methods are secured with @RolesAllowed annotations. This works fine.

But the service is open for Cross-Site Request Forgery.

a solution

Now I understand the concept how to prevent CSRF. Tomcat (which I'm using) has a build in system to prevent it, which works with filters.

web.xml

 <filter>
   <filter-name>CsrfFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CsrfPreventionFilter</filter-class>
    <init-param>
      <param-name>entryPoints</param-name>
      <param-value>/index.xhtml</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CsrfFilter</filter-name>
    <url-pattern>/api/*</url-pattern>
  </filter-mapping>

Now you could encode all URLs with HttpServletResponse#encodeRedirectURL(String) and use them in a form like this <form action="<%=urlActionBEncoded %>" method="POST">

the problem

Since I'm not using jsp/jsf this won't work for me. All requests are made via ajax, so I'd have to inject these encoded URLs in the JavaScript code.

questions

  • How could I inject the encoded URL in the JavaScript? Would this be a possible / reasonable solution?
  • I've found some other methods to prevent CSRF, but they all involve JSF or JSP-sites. Are there any other possible methods to prevent CSRF in webservices?

Thanks in advance :)


Solution

  • RESTful webservices are stateless, with authentication for non-form based clients performed on every request. There shouldn't be a problem there since authentication is on every request (see the comments here). However, if using another framework, then you want to use the "Synchronizer Token Pattern". You pass a generated token to the server which the server validates. If you aren't using forms to set this token, then I'm assuming that you'd need to read into which lib to use to safely include it in your requests from the client to the server.

    What exactly do you mean by "inject the encoded URL in the JavaScript?". Are you talking about how to encode your request params/query strings? Here is someone using the URL to prevent CSRF.

    Some interesting links when I searched:

    http://docs.spring.io/spring-security/site/docs/3.2.x-SNAPSHOT/reference/springsecurity.html http://docs.spring.io/spring-security/site/docs/3.2.x-SNAPSHOT/reference/web-app-security.html https://code.google.com/p/csrf-filter/