JWT doit-il être stocké dans localStorage ou cookie? [dupliquer]

100

Dans le but de sécuriser l'API REST à l'aide de JWT, selon certains documents (comme ce guide et cette question ), le JWT peut être stocké dans localStorage ou Cookies . Basé sur ma compréhension:

  • localStorage est soumis à XSS et il n'est généralement pas recommandé d'y stocker des informations sensibles.
  • Avec les cookies, nous pouvons appliquer le drapeau "httpOnly" qui atténue le risque de XSS. Cependant, si nous devons lire le JWT à partir des cookies sur le backend, nous sommes alors soumis au CSRF.

Donc, sur la base du principe ci-dessus, il sera préférable de stocker JWT dans les cookies. À chaque demande adressée au serveur, le JWT sera lu à partir des cookies et ajouté dans l'en-tête d'autorisation en utilisant le schéma de support. Le serveur peut alors vérifier le JWT dans l'en-tête de la requête (au lieu de le lire à partir des cookies).

Ma compréhension est-elle correcte? Dans l'affirmative, l'approche ci-dessus présente-t-elle des problèmes de sécurité? Ou en fait, pouvons-nous simplement nous en sortir en utilisant localStorage en premier lieu?

pkid169
la source
@ lrn2prgrm comme on ne doit pas utiliser (sans état) JWT et sémantique de la session (stateful) ensemble.
ozanmuyes

Réponses:

56

J'aime la méthode XSRF Double Submit Cookies mentionnée dans l'article que @ pkid169 a dit, mais il y a une chose que l'article ne vous dit pas. Vous n'êtes toujours pas protégé contre XSS car l'attaquant peut injecter un script qui lit votre cookie CSRF (qui n'est pas HttpOnly), puis faire une demande à l'un de vos points de terminaison d'API à l'aide de ce jeton CSRF avec le cookie JWT envoyé automatiquement.

Donc, en réalité, vous êtes toujours vulnérable au XSS, c'est juste que l'attaquant ne peut pas voler votre jeton JWT pour une utilisation ultérieure, mais il peut toujours faire des demandes au nom de vos utilisateurs en utilisant XSS.

Que vous stockiez votre JWT dans un stockage local ou que vous stockiez votre jeton XSRF dans un cookie non http uniquement, les deux peuvent être facilement récupérés par XSS. Même votre cookie JWT dans HttpOnly peut être capturé par une attaque XSS avancée.

Ainsi, en plus de la méthode Double Submit Cookies, vous devez toujours suivre les meilleures pratiques contre XSS, y compris les contenus qui s'échappent. Cela signifie supprimer tout code exécutable qui amènerait le navigateur à faire quelque chose que vous ne voulez pas qu'il fasse. En règle générale, cela signifie supprimer les balises // <! [CDATA [et les attributs HTML qui entraînent l'évaluation de JavaScript.

Iman Sedighi
la source
11
Pouvez-vous clarifier comment un cookie JWT dans HttpOnly peut être saisi? Il peut être utilisé par XSRF si le jeton XSRF est compromis par XSS, mais peut-il vraiment être saisi?
Jacek Gorgoń
1
Je sais que c'est un ancien message, mais j'aimerais poser quelques questions ... Cela signifie-t-il que des scripts bien conçus peuvent lire à la fois localStorage et cookie? Si tel est le cas, est-il prudent de supposer qu'un JWT peut éventuellement être volé, peu importe où nous le stockons dans un navigateur? Ensuite, j'ai l'impression que se fier uniquement à un JWT est très risqué.
Hiroki
2
"Même votre JWT dans le cookie HttpOnly peut être capturé par une attaque XSS avancée." c'est faux. Publication originale modifiée pour corriger cela.
java-addict301
"Même votre JWT dans le cookie HttpOnly peut être saisi par une attaque XSS avancée" Je peux imaginer que quelqu'un saisit le cookie en l'envoyant à son propre serveur. Pour cela, il peut utiliser fetch avec la valeur appropriée de l'indicateur d'identification. Le problème principal ici est la protection CORS mais dans certaines circonstances, je pense que c'est possible.
bartnikiewi.cz
"injecter un script qui lit votre cookie CSRF (qui n'est pas HttpOnly)" L'implémentation par défaut de Html.AntiForgeryToken()dans ASP.NET MVC utilise un cookie HttpOnly pour le jeton CSRF. Je pense que vous êtes toujours sensible à certains XSS, mais j'ai pensé que cela valait la peine d'être mentionné.
Lovethenakedgun
21

Un message opportun de Stormpath a à peu près élaboré mes points et répondu à ma question.

TL; DR

Stockez le JWT dans les cookies, puis passez le JWT dans l'en-tête Authorization sur chaque demande comme je l'ai mentionné, ou comme le suggère l'article, comptez sur le backend pour empêcher CSRF (par exemple, xsrfTokenen cas d'utilisation angulaire).

pkid169
la source
2
Bonjour, je ne sais pas si cela est correct, mais y a-t-il des inconvénients particuliers à utiliser des cookies pour stocker jwt lorsque vous implémentez CrossOrigin pour vos contrôleurs, c'est une scène où mon application serveur est située à un endroit différent et nous appelons le api de celui-ci dans notre application client qui se trouve par exemple dans une autre ville? N'est-ce pas la raison pour laquelle de nombreux fournisseurs de services Web s'abstiennent d'utiliser des cookies?
valik
CrossOrigin ne signifie pas des emplacements physiques. Il fait référence aux demandes provenant d'autres domaines. Dans .net core, lorsque vous décidez d'utiliser CORS, vous spécifiez les domaines que vous allez autoriser; quels en-têtes vous autoriserez, etc.
Brian Allan West
11
  • Ne stockez pas votre jeton dans LocalStorage ou SessionStorage, car un tel jeton peut être lu à partir de javascript et est donc vulnérable aux attaques XSS.
  • Ne stockez pas votre jeton dans Cookie. Le cookie (avec le drapeau HttpOnly) est une meilleure option - il est sujet au XSS, mais il est vulnérable aux attaques CSRF

Au lieu de cela, lors de la connexion, vous pouvez fournir deux jetons: le jeton d'accès et le jeton d'actualisation. Le jeton d'accès doit être stocké dans la mémoire Javascript et le jeton d'actualisation doit être stocké dans HttpOnly Cookie. Le jeton d'actualisation est utilisé uniquement et uniquement pour créer de nouveaux jetons d'accès - rien de plus.

Lorsque l'utilisateur ouvre un nouvel onglet ou lors de l'actualisation du site, vous devez effectuer une demande de création d'un nouveau jeton d'accès, en fonction du jeton d'actualisation stocké dans le cookie.

Je recommande également vivement de lire cet article: https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/

devstructeur
la source
5
Pourquoi cette complexité supplémentaire lorsque vous pouvez simplement traiter le jeton d'actualisation comme un jeton d'accès? Comment cette approche plus sûre donné que je marque mon jeton d' accès comme secure, samesite: strict, http-only?
Charming Robot
ce n'est pas plus sûr
Chris Hawkes
2

Pour éviter les attaques CSRF qui tirent parti des cookies existants, vous pouvez définir votre cookie avec la SameSitedirective. Réglez-le sur laxou strict.

Il s'agit toujours d' un brouillon et à partir de 2019, il n'est pas entièrement pris en charge par tous les navigateurs actuels , mais en fonction de la sensibilité de vos données et / ou de votre contrôle sur les navigateurs que vos utilisateurs utilisent, cela peut être une option viable. La définition de la directive avec SameSite=laxautorisera "les navigations de haut niveau qui utilisent une méthode HTTP" sûre "."

Ian Hunter
la source