4

I have two different web application. Services web app has REST Services defined. Client web app has JSP pages which makes call to REST services using Ajax to get the data and display in the UI. I want to implement OWASP CSRF Gaurd 3 for my REST services.

How can I get CSRF token value in Client application so that it can pass token value as header and rest services gets validated and executed?

Let me tell my architecture bit clearly. Services Project - It is a spring/JPA project with REST web services defined. This project requires to be protected with CSRF. Its web context is /Services. So url might be in localhost like http://localhost:8080/Services/RESTSERVICE

Client Project - It is a JSP/Servlet project with jsp/html web pages. This project makes AJAX calls to Services project's REST Services to fetch the data and show it in UI. URL is like http://localhost:8080/Client/index.jsp

Now my doubt is if I implement CSRF Guard in Services Project, Client project required CSRF token to call protected REST Services. How do I get this token value into Client projects jsp pages?

I tried with adding cookie into the response of rest services, but Client javascript is unable to read it so with cookie i was not able to share token to the client. Is there any other approach? Any help will be appreciated...

  • Depending on how your authentication works, an AJAX based webapplication might not even need CSRF tokens. Those tokens are only needed because the browser implicitly adds cookies to each request. If you manually add an authentication header to each request, this implicit authentication doesn't happen, and CSRF is irrelevant. – CodesInChaos Dec 17 '13 at 8:41
2

Just implement a /token endpoint that provides a CSRF token given a session cookie. Remember, as long as client side JS on a different domain cannot fetch and use this to construct requests (the most client side JS can do is dislpay it in an isolated iframe), CSRF is not possible. Allow the client app to fetch the token via CORS if the domains differ.

  • Couldn't a CSRF attack be used to get the CSRF token in your example? – Abe Miessler Oct 8 '13 at 14:52
  • @AbeMiessler How? The token could be retrieved without the user's consent, but it wouldn't be accessible because of CORS. Normally, CSRF tokens are stored in the HTML of a page. This is the same thing, just more machine-friendly. – Manishearth Oct 8 '13 at 14:53
  • 2
    Well a malicious user could make a POST request to the /token endpoint if the user has an active session, correct? You are right that this is not a vulnerability though, because the attacker would have no way to read the token that was returned. Does that make sense? – Abe Miessler Oct 8 '13 at 15:04
  • @AbeMiessler Yep. The /token endpoint is a GET one anyway. – Manishearth Oct 8 '13 at 15:36
  • 1
    @user31699 You can do that, or have the server for the client webapp request the token internally by providing the cookie. It won't be vulnerable; as the /token service cannot be both fetched and read with your cookie without your knowledge due to CORS. – Manishearth Oct 9 '13 at 8:57
0

I recently had to do this and ended up putting the CSRF token in a global javascript variable. Then when I would make my calls I would include this token as a parameter. Since an attacker would not be able to read any state from your browser it should be safe there.

Example:

$.ajax({
  type: "POST",
  url: "some.php",
  data: { name: "John", location: "Boston", _csrf: _GLOBALS._csrf }
});
  • Thank you Abe Miessler... My issue is to get token value in client application from my webservice app.. since both are having different web context – MShah Oct 9 '13 at 7:36
0

I've faced the same problem and have decided to use “one-time token requests”. Something like this:

  1. Enter login-password, authenticate, authorize, load main project page
  2. Call method /csrf-token before any other requests, e.g. during initial bootstrap stage
    • The server generate token and then somewhere in the server session data makes note, that csrf token has been already requested, so all future calls of /csrf-token will fail.
  3. Client remember that token and use it for all future requests; it could rememeber in some javascript namespace for example, so it will be accessible only from that page/tab.

Major drawback from this method: you have to sign if you reload the page for example.

0

Adding the CSRF Token in the Client

pom.xml:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>js-cookie</artifactId>
    <version>2.1.0</version>
</dependency>

Import it in HTML:

<script type="text/javascript" src="/webjars/js-cookie/js.cookie.js"></script>

then we can use Cookies convenience methods in xhr:

$.ajaxSetup({
beforeSend : function(xhr, settings) {    
      xhr.setRequestHeader("X-XSRF-TOKEN",
          Cookies.get('XSRF-TOKEN'));
    }
  }
}
});

source: https://spring.io/guides/tutorials/spring-boot-oauth2/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.