Store Auth-Token in Cookie or Header?

  • 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".

  • Shiv Sahni

    Shiv Sahni Correct answer

    3 years ago

    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.

    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...

    Yes you have learnt correct. The combination is indeed better. I hope you got the answer.

    let's drop this video (which helped me) here and close the question: https://www.youtube.com/watch?v=67mezK3NzpU

    The XSS one is not quite right. With XSS the cookies authentication is only slightly better, because attacker can still CSRF. XSS allows attacker to bypass CSRF token.

    `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

    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.

    @Melbourne2991, I believe you need to re-read the answer as it solely talks about the comparison of session management using cookies and stateless tokens such as JWT. Also, I think you need to patiently read the complete line for the better understanding of the context i.e. "third party cookies are sent by default to the third-party domain" which means that the third party cookies are sent by default to their RESPECTIVE domains. I hope this helps now!

    @ShivSahni in that case the answer needs editing, because it says "third party domains" which has a different meaning altogether. I can store a stateless JWT in a cookie instead of local storage - which is actually safer - so how can you say that cookies are stateful? Session based auth is stateful - where you are maintaining a session id in the backend, but this is a separate issue.

    @rdmueller "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..." this is correct!

    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.)

    The CSRF problem of cookies goes away with the `sameSite` flag.

    I think this answer is mixing cookies with session and access token with local storage. Saying "Cookie based authentication is a stateful authentication" is wrong because you can have a JWT stored as a cookie. Actually, we can have 4 combinations regardless of vulnerabilities. And indeed, many suggest that we should store the access token as an HttpOnly, SameSite, Secure cookie instead of local storage to prevent from CSRF and XSS attacks (can also combine with the use of a CSRF token). Would have downvoted this answer but I don't have sufficient reputation.

    I think Cookie != Stateful. You can use cookie to store access token

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM