Why not store JWT access token in memory and refresh token in cookie?

Viewed 2223

A lot of questions have already been asked on the topic of storing JWT tokens securely when dealing with a browser-based application. The consensus seems to be that http-only, secure cookies should be used. However, many variations seem to exist on storing JWT tokens when both short-lived access tokens and longer-lived refresh tokens are involved.

I have identified the following variations:

1. Store both JWT access token and refresh token in http-only, secure cookies

Pros:

  • Access token and refresh token cannot be accessed from Javascript

Cons:

  • Introduces CSRF vulnerabilities so CSRF token must be added as well

The top answer here advises to add CSRF tokens: https://stackoverflow.com/a/37396572/6735966

2. Store a JWT access token in memory and refresh token in http-only, secure cookie

Pros:

  • Refresh token cannot be accessed from Javascript
  • Access token sent through Javascript so access token is not vulnerable to CSRF
  • Refresh cookie can only be used to obtain new access token. With the correct CORS setup, reading the access token from the response is not possible through a cross-site request by a malicious party. Therefore, this approach seems safe from CSRF.

Cons:

  • Access token can be accessed through Javascript (but access token expires quickly)

Recommended here but received a lot less votes than the top post: https://stackoverflow.com/a/63593954/6735966

3. Store a refresh token in memory and JWT access token in http-only, secure cookie

Pros:

  • Access token cannot be accessed from Javascript
  • Refresh token sent through Javascript so refresh token is not vulnerable to CSRF

Cons:

  • Longer-lived refresh token can be accessed from Javascript
  • Access token is vulnerable to CSRF

A similar approach is described in the top answer here: https://stackoverflow.com/a/54378384/6735966

Considering the pros and cons storing a JWT access token in memory and refresh token in http-only, secure cookie definitely seems like a good idea to me. However, even though there are many questions on this topic, none of the top voted answers even consider this approach. Therefore my question is: Why not store JWT access token in memory and refresh token in cookie and instead use one of the other approaches?

1 Answers

Storing the cookie in memory would work, but one issue is if you have multiple instances of the same client.

An alternative is to do it like they do in ASP.NET core, where by default the cookies are stored encrypted in the session cookie. However, this cookie can't be used to access any API's, as it is inaccessible from JavaScript. Also, to avoid the CSRF issues, you typically add the common antiforgery token/cookie to prevent CSRF attacks.

So, the most way is to store the tokens in ASP.NET Core is in the session cookie. But at the sametime, this make the cookie to grow quite a bit, so when you feel the cookie size grows to big, then you start looking at storing them in memory or in database/Redis storage.

In .NET for example, the support for this is already built in by using a SessionStore. The picture below tries to show how this works where the SessionKey is stored in the cookie and then tokens are stored in memory/backend.

enter image description here

Yes, this is how it works in ASP.NET Core and I am sure you can find the similar approaches in other platforms as well.

An alternative is to look at using the BFF pattern that seems to get more and more popular.

Related