14

I have an API to secure. There will potentially be two types of consumers of this API - our own Single Page Application, and third party services that will integrate with it.

I have read that in general cookies are not favoured for REST APIs, it is better to use header fields. Perhaps this is just convention.

Secure cookies are a better place to hold the auth token in an SPA. It prevents them from being obtained by a cross-site script attack. Also, if the SPA opens a new window/tab, the sessionStorage does not flow accross, causing the user to have to log in again. You can use localStorage, but not a good idea to keep auth tokens there, as it persists.

Should I make the authentication filter on the server side accept either a cookie or a header field? Try the cookie first, and if it is not there then try the header field? Cookies would be used by SPAs, and header fields by other API consumers. Or, would it be better to go with only one way of transmitting the auth token?

6
  • 7
    Clarification: the Secure cookie flag ensures the cookie is only transmitted over HTTPS (mitigates MITM); the HTTPOnly cookie flag ensures that JavaScript can't access the cookie value (mitigates XSS). Transmitting auth stuff in headers can mitigate CSRF. Apr 8, 2016 at 18:28
  • @PlasmaSauna Thanks for that. With cookies, something extra must be added to the requests to prevent CSRF, for example, a sequence number in a header field. Apr 11, 2016 at 10:45
  • (Oh! Facepalm -- you mentioned both Secure and HTTPOnly in the title of your question. Yeah, you probably know what's up with those.) Apr 12, 2016 at 7:37
  • 1
    Cookies are transferred in HTTP header fields. So technically there is potentially very little distinction between the two.
    – user
    Apr 12, 2016 at 7:55
  • Yes, cookies are header fields. What they offer over header fields is that browsers use the 'httponly' and 'secure' flags to handle them in a more secure way. A little distinction, but an important one. Apr 12, 2016 at 8:48

2 Answers 2

6
+25

I don't think there is a big difference in security between cookies or headers, if properly used.

Cookies are meant to maintain server state. So if you have a login call which starts a session, cookies make sense. If you use an API token that is distributed outside of the API, cookies don't make sense.

In the end, cookies are also sent in headers, so there is little distinction between how they are transmitted. The difference is in how browsers handle cookies:

  • It is possible to set cookies as HttpOnly, making them inaccessible from JavaScript;
  • Cookies are included in every request by the browser.

HttpOnly provide some protection against XSS. However, an attacker can call your API any way he wants when he gets XSS, even if he doesn't obtain the cookie.

That cookies are included in every request makes it vulnerable to cross-site request forgery (CSRF): another webpage can trigger a request to your API, and the cookies are included by default.

In a SPA, an alternative to store the token is in a JavaScript variable. This is only kept while the tab is open, and may be secure against XSS if the variable is limited in scope.

Storing tokens in localStorage keeps them there forever, since localStorage is not cleared when the application is closed. However, this isn't so bad, since you can expire tokens on the server. Even if the token is exposed after a while because it was kept in localStorage, the token won't be valid anymore.

There is also the possibility to use two tokens, one in a cookie and one in a header. You would need both tokens to successfully use the API. Since the cookie is HttpOnly, you are protected against XSS. Since the header is not sent on every request, you are protected against CSRF.

1
  • "However, an attacker can call your API any way he wants when he gets XSS, even if he doesn't obtain the cookie." Isn't it a lot more difficult, though? The attacker would have to know something about the APIs to use them. Whereas with the token in hand, he could just log in and use the UI. Oct 23, 2019 at 13:27
1

For the situation as you described, I recommend transmitting authentication information only in cookies. As you mentioned, this prevents the exfiltration of a user's authentication token from your Single-Page Application.

As an added bonus, having the authentication token as a cookie simplifies the logic in your authentication filter, since there's only one place to check.

Do note that if there is an XSS flaw in your SPA, attacker JavaScript can still issue requests impersonating the user whether you use cookies or headers for the authentication token. So, please, sanitize your output :-)

4
  • 1
    Why do so many APIs use header fields for the access token? Paypal, for example: developer.paypal.com/docs/api/auth-headers . I'm concerned that using cookies might be defying convention, even though it would seem to be better from a security view. Apr 12, 2016 at 8:45
  • Is the answer that, since cookies do no prevent XSS, like you describe, they are not really more secure than using a header field? Apr 12, 2016 at 8:52
  • 1
    Not quite. If the attacker steals the value of the authentication token, they can use it from their own computer(s) at a later date as long as the authentication token is still valid server-side. That's a good reason to prevent the theft of the authentication token. Apr 13, 2016 at 3:00
  • 2
    True, but you only make auth tokens valid for a short time. If an attacker can implicitly use the token with XSS attack, then they might as well use it straight away from their script. Apr 13, 2016 at 9:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .