Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Less secure that HttpOnly cookies, which are not accessible by third-party JavaScript. LocalStorage also doesn't have automatic expiration.


Tradeoff is all the edge cases of cookies, CSRF etc. It's not a simple "cookies are better"


But when you can use them, cookies are demonstrably better. XSS is the main argument against localstorage. Even this article[0], which pillories cookies, starts off with:

   ...if your website is vulnerable to XSS attacks, where a third party can run arbitrary scripts, your users’ tokens can be easily stolen [when stored in localstorage].
The reasons to avoid cookies:

* APIs might require an authorization header in the browser fetch call.

* APIs might live on a different domain, rendering cookies useless.

CSRF is a danger, that's true. can be worked around. My understanding is that XSS has a wider scope and that many modern frameworks come with CSRF protection built in[1]. Whereas XSS is a risk any time you (or anyone in the future) includes any JS code on your website.

0: https://pilcrowonpaper.com/blog/local-storage-cookies/

1: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Re...


> * APIs might live on a different domain, rendering cookies useless.

That's when you implement a BFF which manages your tokens and shares a session cookie with your frontend while proxying all requests to your APIs. And as said, you "just" have to setup a way for your BFF to share CSRF tokens with your frontend.


Yup, big fan of the BFF. Philippe de Ryck did a presentation on the fundamental insecurity of token storage on the client that he allowed us to share: https://www.youtube.com/watch?v=2nVYLruX76M

If you can't use cookies (which as mentioned above, have limits) and you can't use a solution like DPoP (which binds tokens to clients but is not widely deployed), then use the BFF. This obviously has other non-security related impacts and is still vulnerable to session riding, but the tokens can't be stolen.


> Philippe de Ryck

Almost certain it is one of those presentations which got me on the BFF bandwagon. Really awesome speaker.


CSRF is not as big of an issue as it used to be, and when it is an issue it can be solved more easily and comprehensively than XSS:

1. The default value for SameSite attribute is now "Lax" in most browsers. This means that unless you explicitly set your authentication cookies to SameSite=None (and why would you?), you are generally not vulnerable to cookie-based CSRF (other forms of CSRF are still possible, but not relevant to the issue of storing tokens in local storage or cookies).

2. Most modern SSR and hybrid frameworks have built-in CSRF protection for forms and you have to explicitly disable that protection in order to be vulnerable to CSRF.

3. APIs which support cookie authentication for SPAs can be deployed on another domain and use CORS headers to prevent CSRF, even with SameSite=None cookies.

On the other hand, there are no mechanisms which offer comprehensive protection from XSS. It's enough for a single JavaScript dependency that you use to have a bug and it's game over.

For this reason, OAuth 2.0 for Browser-Based Applications (draft)[1] strongly recommends using a HttpOnly cookie to store the access token:

"This architecture (using a BFF with HttpOnly cookies) is strongly recommended for business applications, sensitive applications, and applications that handle personal data."

With regards to storing access tokens and refresh tokens on local storage without any protection it says:

"To summarize, the architecture of a browser-based OAuth client application is straightforward, but results in a significant increase in the attack surface of the application. The attacker is not only able to hijack the client, but also to extract a full-featured set of tokens from the browser-based application.This architecture is not recommended for business applications, sensitive applications, and applications that handle personal data."

And this is what it has to say about storing the refresh token in a cookie, while keeping the access token accessible to JavaScript:

"When considering a token-mediating backend architecture (= storing only access token in local storage), it is strongly recommended to evaluate if adopting a full BFF (storing all tokens in a cookie) as discussed in Section 6.1 is a viable alternative. Only when the use cases or system requirements would prevent the use of a proxying BFF should the token-mediating backend be considered over a full BFF."

In short, the official OAuth WG stance is very clear:

1. HttpOnly cookies ARE better in terms of security. 2. Storing Refresh Tokens in local storage is only recommended for low-security use cases (no personal data, no enterprise compliance requirements). 3. Storing short-lived Access Tokens in local storage should only be considered if there are technical complexities that prevent you from using only cookies.

[1] https://datatracker.ietf.org/doc/html/draft-ietf-oauth-brows...


enable same-site??

if you're doing things not from same-site, I'd posit you're doing something I want blocked anyways.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: