Publications

Frontend JWT token storage

How to store properly JWT token in a browser

Résumé

Sur plusieurs applications, j’avais constaté que le jeton JWT était rangé dans le local storage, le session storage ou un cookie non sécurisé. Ces techniques sont vulnérables aux attaques XSS et au vol de jeton, autrement dit au détournement de session. Cet article explore trois alternatives sur une petite preuve de concept, un frontend jQuery et un backend Express qui émet et vérifie le jeton.

La première garde le jeton en mémoire, dans la portée locale d’une fonction anonyme: aucun autre script ne peut l’atteindre, mais un rechargement de page le perd et l’utilisateur doit se reconnecter. Un jeton qui expire au bout de cinq minutes et se renouvelle toutes les quatre limite les dégâts. La deuxième passe par un cookie sécurisé, httpOnly, sameSite, secure et à durée courte: le JavaScript ne peut plus le lire et il survit au rechargement, mais il n’est pas disponible entre domaines.

La troisième est un service worker. Il tourne dans un thread séparé, donc le jeton survit au rechargement; il est posé uniquement par le service worker à la réponse de connexion, jamais renvoyé au client, et injecté dans les requêtes fetch interceptées. C’est la plus sûre et la plus complexe, et tous les navigateurs ne la prennent pas en charge.

Il n’y a pas de bonne réponse unique: c’est un compromis entre la sécurité et l’expérience, en particulier la survie au rechargement. Le dépôt qui accompagne l’article implémente chaque technique sur sa propre branche.

Idées clés

  • Local storage, session storage et cookie non sécurisé exposent le jeton à tout script injecté: c’est le vol de session.
  • Une closure met le jeton hors de portée de tout autre script, au prix d’une reconnexion à chaque rechargement.
  • Un cookie httpOnly, sameSite, secure et à courte durée survit au rechargement mais ne traverse pas les domaines.
  • Un service worker garde le jeton dans son propre thread et l’injecte dans les requêtes fetch; le plus sûr, le plus complexe, pas encore universel.

Pourquoi j’ai écrit cet article

Sur plusieurs applications, j’avais constaté que le jeton JWT était stocké dans le local storage, le session storage ou un cookie non sécurisé, des techniques faibles, vulnérables aux attaques XSS et au vol de jeton.

Dépôts associés