4

The web application framework we use has built-in support for handling Cross-site Request Forgery. This works well when data is posted with a browser to our webserver.

Currently we are developing an API in which an uploaded XML file is processed by the same application framework. Our API requires a unique token in the uploaded XML file for authentication. Since CSRF detection is enabled by default and the XML file does not contain a CSRF token we currently can not upload any data through this API.

However, we can quite easily disable CSRF detection, but is this safe?

A post here states -- quite boldly -- the following.

It is safe to remove csrf for API calls as the particular vulnerability can only be executed through a web browser.

Is this true? Can nothing similar to a CSRF attack happen through an API?

Community
  • 1
  • 1
meijuh
  • 1,067
  • 1
  • 9
  • 23

2 Answers2

2

That depends on how you use the API. Say if the website using the API is vulnerable to CSRF, that means the API is also vulnerable.

Wekipedia says that

CSRF exploits the trust that a site has in a user's browser.

To support API calls the server requires that the credentials be sent along with every request (or some equivalent like digest, security handle, hash). If the credentials are stored in application memory (like mobile app) API is not vulnerable to CSRF. But if the credentials are saved in a session or cookie the API is exposed to CSRF

kranthi117
  • 628
  • 1
  • 8
  • 21
  • In short: if you use sessions, cookies or http authentication, you must keep CSRF protection! – Evert May 01 '13 at 14:03
  • @kranthi117, Please elaborate how its vulnerable to CSRF if credentials are stored in cookies. Since the CSRF attacker is not able to read the cookies, how can he spoof a request containing the cookie values? – Pacerier Jun 06 '14 at 19:17
  • @Pacerier I guess he meant that the credentials are sent to the API in cookie headers, so they are appended to every request automatically by the browser, and not by the client side application... – inf3rno Jun 26 '14 at 00:26
  • @inf3rno, The cookies are sent to the server, not to the attacker. Since the CSRF attacker is not able to read the cookies, how would he be able to spoof a request containing the cookie values? – Pacerier Nov 26 '15 at 10:20
  • @Pacerier I don't understand the question. CSRF is about sending a request to the vulnerable app, which you are logged in. So the attacker sends you a form on a different site, you click on post, and the browser sends the form to the vulnerable app with your session cookies attached. Javascript applications can be CSRF vulnerable only if they use the history api to generate requests as far as I know. – inf3rno Nov 26 '15 at 12:12
  • @inf3rno, That wouldn't work because of the extra checks. For example, our website will have a ``. And the server will check that that the value of the input **matches** the cookie value before proceeding with the request. The only way the attacker can hack this solution is if he somehow is able to read (and thus create) the value `some_value_that_is_also_stored_in_cookie`. – Pacerier Nov 26 '15 at 20:17
  • @Pacerier Yes, that is called CSRF token. That works either. REST is somewhat different, it does not use server side sessions, so there is no way to store the CSRF token on the server. – inf3rno Nov 26 '15 at 21:41
  • @Pacerier If we would store the credentials in cookies by REST, then a possible workaround would be to sign the CSRF token with the user id and send back both the CSRF token and the signature with the request. That way the communication would be both stateless and bound to the user identity. Storing the credentials in the client, and attaching them to the authorization header of every requests by the usage of the client side app - instead of the browser as kranthi117 suggested - is a better way to avoid CSRF with REST. It is stateless too and it does not require server load. – inf3rno Nov 26 '15 at 22:00
  • @inf3rno, Signing is not needed. In fact it's best not to have signing because there will be more complexity in dealing with key revocation and re-issuance. In fact, the revocation list would need a central database as well, so that would sort of defeat the purpose (read: might as well have a db linking unique tokens to userids and be done with it). (Also see my updated answer.) – Pacerier Nov 29 '15 at 11:44
  • @Pacerier If you store something in database, you have to reuse them by multiple sessions. Otherwise you would violate the stateless constraint. Storing any part of client session (including session id) on server is not allowed by REST. – inf3rno Nov 29 '15 at 12:57
0

It depends on what you mean by "disable CSRF detection".

Some pointers:

  • As long as you do validate the unique authentication token without fail, then there is no way the attacker can spoof a valid request without a valid token. This is straightforward.

  • "unique authentication token" here refers to something that is not sent by browsers automatically. (So no using stuff like HTTP Basic / Digest, Cookie header and etc.) It must be something unique that you (the API creator) came up with. This can be as easy as an additional Foobar:the_unique_token header.

  • Note that it is perfectly fine to identify the client based on the Cookie (or other tokens that browsers automatically send), but you must only allow entry when the unique token is provided.

As long as the attacker can spoof a valid request as long as he is able to guess/obtain the token (the_unique_token). So the token needs to be long, random, and single-use to be secure.

Pacerier
  • 86,231
  • 106
  • 366
  • 634
  • Your solution is okay by the CSRF part, but REST has a stateless constraint, which does not allow us to store client session on the server. So I think you need to write something about that too. http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_3 – inf3rno Nov 29 '15 at 13:10