Moshe Arad Moshe Arad - 1 month ago 21
Ajax Question

CSRF token protection with AJAX GET method

I'm a bit confused from the online information.

I'm using CSRF protection using Spring security on my back-end.

I wanted to ask is it safe to send CSRF token from my angular front-end, while I'm passing the token within HTTP header using Ajax GET method?

Because according to Spring docs I shouldn't use GET method, but on the other hand it doesn't say anything about if it's okay to use GET Ajax when I pass it in HTTP header.

Second,

If I shouldn't use GET, how do I use REST service & CSRF protection? should I give up GET method or CSRF protection?

Answer

Since GET requests should not modify any state on the server and should be "read-only" usually CSRF protection should not be needed for GET requests.

The problem about leakage is mostly related to browser usage because GET requests usually do not contain a body and thus the token is sent as request parameter. Thus the CSRF token could be visible through shoulder surfing, stored as a bookmark, appear in the browser history or logged on the server (altough logging also applies to AJAX requests).

Since you are talking about AJAX requests most of this leakage does not apply, although setting it in header may help in case of URLs appearing in the logs, but logs could also contain headers.

But actually using a custom header (with or without token) is often used to prevent CSRF attacks because AJAX requests cannot set custom headers cross-domain other than

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type

Thus using a custom header like X-Requested-With: XMLHttpRequest which is e.g. set by jQuery and verifying this header on the server can prevent CSRF attacks.

Last but not least there is one interesing article about having the same token for GET and POST requests and having same-origin access to the GET request via an XSS vulnerability of a separate web application in the same origin where the token can be leaked from the GET request and used for a POST. The solution there is to either not use CSRF tokens for GET or use different tokens for GET and POST.

Basically regarding your questions, if your GET does not have any side-effects, a CSRF token is not really needed but would not hurt. On the other hand, if your GET request changes something on the server, you should think about using another verb (e.g. POST) depending on what you want to do and then protect your POST requests with a CSRF token or a custom header.