About storing JWT tokens in browsers


The JWT open standard officially appeared in 2015 ( rfc7519 ) promising interesting features and broad prospects. Proper storage of the Access token is vital for building an authorization and authentication system on the modern Web, where sites built using SPA technology are becoming more and more popular.

Incorrect storage of tokens leads to their theft and reuse by attackers.

So where to store?


Consider the main options for storing JWT Access token in a browser:

  1. Local Storage / Session Storage - the method is not safe and is susceptible to attacks like XSS, especially if you connect scripts from third-party CDNs (adding the integrity attribute cannot guarantee 100% security), or you are not sure if the scripts you connect do not have the ability to "merge" data from storages to the side. Moreover, if Local Storage is available between tabs, then Session Storage is available in only one tab and opening a site in a new tab will only cause a new round of access token / authorization.
  2. , , fetch . – .
  3. Cookies. «» cookie sessions. Access cookie CSRF. XSS . CSRF Cookie SameSite Strict– , , credentials, CSRF .
    – Access JS httpOnly, Secure .

    An important point is to set a cookie only for the domain / path api so that requests to public statics do not contain an overhead in the header.

What is the result?


Cookies, when used correctly, are the appropriate and safest solution for storing the JWT Access token at the moment and must follow the following rules:

  1. Be installed for the domain / path API to avoid overhead when requesting static files (public images / styles / js files).
  2. Have a Secure flag (for transfer only via https).
  3. Have the httpOnly flag (for inability to access from JavaScript).
  4. The SameSite attribute must be Strict to protect against CSRF attacks, prohibit the transfer of cookies if the transition to your API was not from the domain set in the cookie.

On the server side, it should also be configured:

  1. Content-Security-Policy - restrict trusted domains to prevent possible XSS attacks
  2. X-Frame-Options header to protect against clickjacking attacks.
  3. X-XSS-Protection - force the built-in protection mechanism of the browser from XSS attacks.
  4. X-Content-Type-Options - to protect against the substitution of MIME types.

Compliance with these measures, coupled with frequent rotation of Access / Refresh tokens, should help ensure a high level of security on the site.

Limitations


Despite the fact that the SameSite attribute is supported in many popular browsers , there are also browsers that do not support it or partially support it (hello IE and Safari for Mac). For these cases, you need a fallback to CSRF tokens. In this case, along with requests to the API, the CSRF token must also be transmitted. The correct CSRF token must be generated by the server taking into account the user's fingerprint in order to minimize the likelihood of its substitution.

All Articles