112

Quick note: this is not a duplicate of CSRF protection with custom headers (and without validating token) despite some overlap. That post discusses how to perform CSRF protection on Rest endpoints without discussing if it is actually necessary. Indeed, many CSRF/Rest questions I've read on this site talk about securing the endpoints via CSRF tokens without actually discussing whether or not it is necessary. Hence this question.

Is CSRF Protection necessary for Rest API endpoints?

I've seen lots of discussion about securing REST endpoints against CSRF attacks, but having given the topic lots of thought, I'm very certain that CSRF tokens on a REST endpoint grant zero additional protection. As such, enabling CSRF protection on a REST endpoint just introduces some useless code to your application, and I think it should be skipped. I may be missing something though, hence this question. I think it will help to keep in mind why CSRF protection is necessary in the first place, and the attack vectors it protects against:

Why CSRF?

It really boils down to the browsers ability to automatically present login credentials for any request by sending along cookies. If a session id is stored in a cookie the browser will automatically send it along with all requests that go back to the original website. This means that an attacker doesn't actually have to know authentication details to take an action as the victim user. Rather, the attacker just has to trick the victims browser into making a request, and the credentials to authenticate the request will ride along for free.

Enter a REST API

Rest API endpoints have a very important difference from other requests: they are specifically stateless, and should never accept/use data from either a cookie or session. As a result, a REST API that sticks to the standard is automatically immune to such an attack. Even if a cookie was sent up by the browser, any credentials associated with the cookie would be completely ignored. Authentication of calls to a REST API are done in a completely different fashion. The most common solution is to have some sort of authentication key (an OAuth Token or the like) which is sent along in the header somewhere or possibly in the request body itself.

Since authentication is application-specific, and since the browser itself doesn't know what the authentication token is, there is no way for a browser to automatically provide authentication credentials even if it is somehow tricked into visiting the API endpoint. As a result, a cookie-less REST endpoint is completely immune from CSRF attacks.

Or am I missing something?

  • Some REST API are limiting calls per ip, that may be an edge case where it could make sense to implement a csrf protection. – Xavier59 Aug 3 '17 at 18:51
  • 1
    Thanks for the input @Xavier59. Do you mind clarifying: why would rate limiting necessitate CSRF protection? – Conor Mancone Aug 3 '17 at 19:01
  • So I'm not confident that this is necessarily applicable to your case, but let's say you use google as an oauth provider. Your user logs in to some malicious site which also uses google as an oauth provider. The malicious site could use the user's token (ish, depending on client settings and such) for your site. See here for more: spring.io/blog/2011/11/30/cross-site-request-forgery-and-oauth2 – Jesse K Aug 3 '17 at 19:02
  • @ConorMancone If site A has a REST API limiting call per ip to 1/second, an attacker could trick Bob to go on attacker site B which send tens of request per second. It could result in getting Bob's ip banned from this REST API or preventing him to use the REST API correctly. I agree that's a bit farfetched but not totally impossible. – Xavier59 Aug 3 '17 at 19:48
  • 1
    @Xavier59 That is somewhat the equivalent of trying to DDoS a website by getting an img tag with the website as its source attribute on a high-traffic website. It isn't necessarily far-fetched. That being said, I don't see why CSRF tokens would do anything to mitigate such an attack. – Conor Mancone Aug 3 '17 at 20:11
118

I wasn't originally aiming for a self-answer, but after more reading I've come up with what I believe to be a comprehensive answer that also explains why some might still be interested in CSRF protection on REST endpoints.

No cookies = No CSRF

It really is that simple. Browsers send cookies along with all requests. CSRF attacks depend upon this behavior. If you do not use cookies, and don't rely on cookies for authentication, then there is absolutely no room for CSRF attacks, and no reason to put in CSRF protection. If you have cookies, especially if you use them for authentication, then you need CSRF protection. If all you want to know is "Do I need CSRF protection for my API endpoint?" you can stop right here and leave with your answer. Otherwise, the devil is in the details.

h/t to paj28: While cookies are the primary attack vector for CSRF attacks, you are also vulnerable if you use HTTP/Basic authentication. More generally, if the browser is able automatically pass along login credentials for your app, then CSRF matters. In my experience cookies are the most common technology being exploited to make CSRF happen, but there are some other authentication methods that are used which can result in the same vulnerability.

REST = Stateless

If you ask someone "what is REST" you will get variety of answers that discuss a variety of different properties. You can see as much because someone asked that question on stack overflow: https://stackoverflow.com/questions/671118/what-exactly-is-restful-programming

One property of REST that I have always relied upon is that it is stateless. The application itself has state of course. If you can't store data in a database somewhere, your application is going to be pretty limited. In this case though, stateless has a very specific and important meaning: REST applications don't track state for the client-side application. If you are using sessions, then you are (almost certainly) keeping track of client-side state, and you are not a REST-full application. So an application that uses sessions (especially for logins) that are tracked via cookies is not a REST-full application (IMO), and is certainly vulnerable to CSRF attacks, even if it otherwise looks like a REST application.

I think it is worth a quick note that one reason that client-side statelessness is important for REST applications is that the ability of intermediaries to cache responses is also a desirable part of the REST paradigm. As long as the application is tracking client-side state, caching is not possible.

Rest ≠ Cookieless

For these reasons, I initially assumed that a fully-compliant REST application would never need sessions, never need cookies, and therefore never need CSRF security. However, there is at least one use-case that may prefer cookies anyway: persistent logins.

Consider a typical client-side (in this case browser, not mobile) web application. You get started by logging in, which uses a REST API to validate user credentials and in return is given a token to authorize future requests. For single page applications, you can just keep that token in memory, but doing so will effectively log the user out if they close the page. As a result, it would be good to persist the state somewhere that can last longer than a single browser session. Local storage is an option, but is also vulnerable to XSS attacks: a successful XSS attack can result in the attacker grabbing your login tokens and sending them off to the attacker to be used at their discretion.

For this reason, I have seen some suggest using cookies to store login tokens. With a cookie you can set the http-only flag, which prevents the application from reading the cookie after it is set. As a result, in the event of an XSS attack, the attacker can still make calls on your behalf, but they can't walk away with the authorization token all together. This use of cookies doesn't directly violate the statelessness requirement of REST because the server still isn't tracking client-side state. It is just looking for authentication credentials in a cookie, rather than the header.

I mention this because it is potentially a legitimate reason to use cookies with a REST API, although it is obviously up to a given application to balance the various security and usability concerns. I would personally try to avoid using cookies with REST APIs, but there may very well be reasons to use them anyway. Either way, the overall answer is simple: if you are using cookies (or other authentication methods that the browser can do automatically) then you need CSRF protection. If you aren't using cookies then you don't.

  • 2
    You're pretty much spot on. HTTP basic authentication can be vulnerable to CSRF as can IP-based auth and others. Conversely, Cookies can be safe if it's only ever a bespoke client that consumes the service, not a browser. That probably doesn't affect your decisions, but is worth bearing in mind. I've found people trying to define what is "proper REST" to be one of the least constructive discussions in IT. In practical terms, most services need authentication, and sessions are a reasonable way to do it. – paj28 Aug 7 '17 at 17:48
  • Thanks @paj28. HTTP basic authentication is a great point to mention. It's a lot less common, I think (which is why I forgot to mention it), but it is good to mention the exceptions when you are trying to come up with a comprehensive answer. – Conor Mancone Aug 7 '17 at 17:59
  • I didn't get your third point, Do I still need csrf protection if I store token in a session cookie? – Rathma Dec 20 '17 at 8:47
  • @HFA If you use cookies, especially for authentication, then you need CSRF protection. It doesn't matter what you are storing in the cookie: if the contents of a cookie are used to authenticate your users with your app, then CSRF is necessary because the browser automatically attaches cookies to all requests to your site. – Conor Mancone Dec 20 '17 at 12:58
  • I store authentication token inside a cookie with session life time in and use that cookie's content to intercept every http request and add an authorization header to http requests, does that count too? ;) – Rathma Dec 20 '17 at 13:01
7

"there is no way for a browser to automatically provide authentication credentials even if it is somehow tricked into visiting the API endpoint"

Just be careful on private networks using integrated windows/kerberos authentication. In this scenario the brower will automatcially provide credentials (kerberos or NTLM token) if configured to do so.

So - I believe in this case CSRF is required.

  • Yep. owasp.org/index.php/Top_10_2007-Cross_Site_Request_Forgery "Authorizes requests based only on credentials that are automatically submitted such as the session cookie if currently logged into the application, or “Remember me” functionality if not logged into the application, or a Kerberos token if part of an Intranet participating in integrated logon with Active Directory is at risk." – Eran Medan Jul 16 at 22:39
4

Rest API endpoints have a very important difference from other requests: they are specifically stateless, and should never accept/use data from either a cookie or session.

If that is how you define "REST API", then no CSRF is possible. CSRF, also called "session riding" [citation], obviously won't work if there is no session to "ride."

  • 1
    If you disagree with part of my statement I would be happy to hear it. IMO, statelessness is a central goal of REST APIs. Sessions definitely make an API stateful. Cookies... technically I suppose you could use cookies and not be storing state server side, depending on how you use them. – Conor Mancone Aug 3 '17 at 20:44
  • 1
    Well I'd rather answer the question than quibble over terminology. But the S in HATEOS and the S in REST both stand for state. As long as client state isn't held on the server I don't think you've "violated" the spirit of the REST approach. – John Wu Aug 7 '17 at 16:13
  • I absolutely agree with you. It wasn't my desire to quibble over terminology. Part of the problem is that I wasn't clear enough in my original question: I was specifically talking about client state, not application state. – Conor Mancone Aug 7 '17 at 17:40
  • Yes State Transfer, that's the important point. The state isn't stored on the server side. The client tells the server about his state. And CSRF makes only sense if the api is accessible through regular web browsers. Some http methods like DELETE, PUT/PATCH are not even supported by todays browsers which makes the api only accessible to stand-alone http clients. – Sebi2020 Sep 13 '18 at 1:54
4

Whether or not CSRF protection is needed is based on 2 factors: -

Is the request doing a state changing action (not the same as REST API Statelessness) - State changing actions are any action that will change the state of the application.. for example delete something, add something, update something. These are actions using which the application will change the backed state of the user. All Post requests and a few Get requests will come under this category. REST APIs can have state changing actions.

Is the authentication provided by browser (not limited to cookies) - CSRF happens because authentication information is included in the request by browser irrespective of whether the request was started by the user, or some other open tab. So any kind of authentication in which browser can self include information needs CSRF protection. That includes both cookie based sessions and basic authentication.

For all requests that fall in above 2 categories CSRF protection is needed.

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.