43

I do understand that a header is the "cleaner" solution to transport an auth-token from a trusted system to another in a REST call. But when you are in client-side JavaScript code, the world looks different to me.

Cookies can be marked as "http-only" and thus can't be easily stolen by JavaScript. A header even has to be set by JavaScript, thus the auth token has to be accessible from within JavaScript. But yet, people use auth-headers to submit their auth-tokens from an untrusted client JavaScript to the server.

What has changed from the good old "use cookies with http-only and secure flag" to "let the JavaScript handle the auth token"? Or should the right way be that "on the client side, use cookies and as soon as you enter the trusted world, switch to auth-header"?

PS: I know that there are many answers to similar questions, but I think my questions is from a different point of view "what has changed, is different".

3 Answers 3

24

Cookie Based Authentication

Pros

  1. HttpOnly Flag: Session cookies can be created with the HttpOnly flag which secures the cookies from malicious JavaScript (XSS-Cross-Site Scripting).

  2. Secure flag: Session cookies can be created with Secure flag that prevents the cookies transmission over an unencrypted channel.

Cons

  1. CSRF: Cookies are vulnerable/susceptible to CSRF attacks since the third party cookies are sent by default to the third-party domain that causes the exploitation of CSRF vulnerability.

  2. Performance and Scalability: Cookie based authentication is a stateful authentication such that server has to store the cookies in a file/DB in order to maintain the state of all the users. As the user base increases the backend server has to maintain a separate system so as to store session cookies.

Token Based Authentication:

Pros

  1. Performance and Scalability: Tokens contains the metadata and its signed value(for tamper protection). They are self-contained and hence there is no need of maintaining state at the server. This improves the performance and thus scalability when the expansion is required.

  2. CSRF: Unlike cookie-based authentication, token-based authentication is not susceptible to Cross-Site Request Forgery since the tokens are not sent to third party web applications by default.

Cons

  1. XSS: Since the session tokens are stored in the local data storage of the browser and it is accessible to the JS of the same domain. Hence there is no option to secure session identifier from XSS attacks unlike HTTPOnly security flag which is available in the cookie-based authentication.

Conclusion

Both of the mechanisms have their own pros and cons as mentioned.In the present era of Application Development Frameworks, cons such as XSS and CSRF are taken care by the underlying framework itself and hence I feel it is without a doubt a clear trade-off on which developers and the stakeholders takes the decision.

14
  • 10
    I just learned that a combination might yield better results: a JWT stored as cookie together with a CSRF id send as header and stored as check in the JWT...
    – rdmueller
    Feb 23, 2018 at 16:58
  • 5
    let's drop this video (which helped me) here and close the question: youtube.com/watch?v=67mezK3NzpU
    – rdmueller
    Feb 23, 2018 at 17:39
  • 7
    cons for cookies are wrong. 1. Even when you use token, the browser continue to send third party cookies to third party domain. Thus this belongs to your app in a whole and do not belongs to your cookies 2. You can store TOKEN as session identificator. Thus no need server has to store the cookies in a file/DB. See here Oct 29, 2018 at 12:32
  • 10
    Surprised to see this has so many upvotes. Both cons for cookies are wrong as @EugenKonkov mentioned. This answer is conflating session based auth with cookies. Cookies are a transport mechanism, they are neither stateful or stateless, it's what you put inside them that is. Also "cookies are sent by default to the third-party domain" is wrong, cookies are only sent to the site they were issued by. Another site can make a request to the target and the cookies belonging to the target may be sent along with it - which is where the CSRF threat can arise. May 20, 2019 at 8:02
  • 5
    The answer is conflating two things: Storage method (Cookies vs LocalStorage) and Authentication Method: (Session vs JWT). You can mix and match all of them: Sessions in Cookies; Sessions in LocalStorage; JWT in Cookies; JWT in LocalStorage. Storage choice is mostly front-end. If you do use Cookies, then make sure it's HttpOnly and make sure you use CORS. If you use LocalStorage, make sure you're safe from XSS. AUTH choice is mostly back-end choice. I suggest HTTPOnly JWT Cookies with CORS on the server which allows fully unaware & transparent requests from JS. (Use 401/403/200 codes.)
    – ShortFuse
    Sep 2, 2019 at 17:15
20

The accepted answer is conflating session based authentication - where a session is maintained in backend database and is stateful with cookies, which are a transport mechanism and so the pros and cons are flawed.

As to whether an auth token should be stored in a cookie or a header, that depends on the client. If the client is another REST api, then passing it via the header makes sense.

If the client is a browser you could store the token in local/session storage and then send the token via the header (as the accepted answer says), but as you mentioned - this has vulnerabilities and is not recommended (see more on this here: https://auth0.com/docs/security/store-tokens).

If the client is an SPA you could just store the tokens in memory - which is probably the safest option, but then you will need retrieve new tokens between pages.

If you need persistence between pages, "the old fashioned way" may still be the best option - providing your cookies are http-only, secure, and you have implemented csrf protection (though soon this may not be necessary because of the same-site property). Providing you do implement csrf protection you will get all of the benefits of "cookie-less token based auth" and additional protection against XSS.

2
  • 1
    I agree that the accepted answer is mixing cookies with session and access token with local storage. Actually, we can have 4 combinations regardless of vulnerabilities.
    – blackr1234
    May 13, 2021 at 23:18
  • When you say "If the client is an SPA you could just store the tokens in memory", is this something that someone will actually do in real world? IMHO, the major reason why cookie or local storage is used is to maintain state even if the user closes the webpage. Will certain implementations, such as using React Redux for state management, still cause the data to be vulnerable to XSS attack?
    – blackr1234
    May 13, 2021 at 23:22
7

The accepted answer is totally wrong!

Please don't mix Cookie, Token, Stateful, Stateless. So many people consider Cookie == Stateful. No it's totally wrong!

Stateful == Session-based -> You store data on server and client just hold session_id, opaque_token.

Stateless -> You don't store anything on server, all data is embedded into token, client hold token and send to server to authentication/authorization. Token can be in JWT, PASETO or any format.

Cookie is just transportation. You can use Cookie or Authorization Header to send token/session_id/opaque_token.

1
  • So what's the advantage/disadvantage of header or cookie transportation? Jul 6, 2022 at 8:23

You must log in to answer this question.

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