Où stocker JWT dans le navigateur? Comment se protéger contre le CSRF?

159

Je connais l'authentification basée sur les cookies. Les indicateurs SSL et HttpOnly peuvent être appliqués pour protéger l'authentification basée sur les cookies contre MITM et XSS. Cependant, des mesures plus spéciales seront nécessaires afin de le protéger du CSRF. Ils sont juste un peu compliqués. ( référence )

Récemment, j'ai découvert que JSON Web Token (JWT) est une solution d'authentification assez populaire. Je connais les choses sur l'encodage, le décodage et la vérification de JWT. Cependant, je ne comprends pas pourquoi certains sites Web / didacticiels indiquent qu'il n'est pas nécessaire de protéger CSRF si JWT est utilisé. J'ai beaucoup lu et j'essaie de résumer les problèmes ci-dessous. Je veux juste que quelqu'un puisse donner une vue d'ensemble de JWT et clarifier les concepts que j'ai mal compris à propos de JWT.

  1. Si le JWT est stocké dans un cookie, je pense que c'est la même chose que l'authentification basée sur les cookies, sauf que le serveur n'a pas besoin d'avoir des sessions pour vérifier le cookie / jeton. Il y a toujours un risque au CSRF si aucune mesure particulière n'est mise en œuvre. Le JWT n'est-il pas stocké dans un cookie?

  2. Si le JWT est stocké dans localStorage / sessionStorage, alors pas de cookie, donc pas besoin de se protéger contre CRSF. La question est de savoir comment envoyer le JWT au serveur. J'ai trouvé ici suggère d'utiliser jQuery pour envoyer le JWT par l'en-tête HTTP des requêtes ajax. Donc, seules les requêtes ajax peuvent faire l'authentification?

  3. De plus, j'ai trouvé un autre blog pour utiliser "Authorization header" et "Bearer" pour envoyer le JWT. Je ne comprends pas la méthode dont parle le blog. Quelqu'un pourrait-il expliquer plus en détail "En-tête d'autorisation" et "Support"? Cela rend-il le JWT transmis par l'en-tête HTTP de TOUTES les demandes? Si oui, qu'en est-il du CSRF?

Espace temporel7
la source

Réponses:

70

Les jetons JWT sont populaires car ils sont utilisés comme format de jeton par défaut dans les nouveaux protocoles d'autorisation et d'authentification tels que OAuth 2.0 et OpenID Connect .

Lorsque le jeton est stocké dans un cookie, le navigateur l'enverra automatiquement avec chaque demande au même domaine et celui-ci est toujours vulnérable aux attaques CSRF.

L'authentification du support est l'un des schémas d'authentification définis dans HTTP. Cela signifie essentiellement que YOUcoller le jeton (JWT) dans l'en-tête HTTP Authorization d'une requête. Le navigateur le fera NOTautomatiquement pour vous, ce n'est donc pas adapté pour protéger votre site Web. Comme le navigateur n'ajoute pas automatiquement l'en-tête à votre demande, il n'est pas vulnérable à une attaque CSRF, qui dépend de la soumission automatique de vos informations d'authentification au domaine d'origine.

Le schéma de support est souvent utilisé pour protéger les API Web (services REST) ​​qui sont consommées via des appels AJAX ou à partir de clients mobiles.

MvdD
la source
1
@ Timespace7 Non, les jetons JWT sont également souvent utilisés à partir de clients natifs. OAuth 2.0 a des flux ciblant spécifiquement les clients natifs (mobiles). Ce qu'ils ne font pas, c'est l'authentification implicite du navigateur (comme les cookies ou l'authentification de base).
MvdD
5
Je dis que si votre API récupère uniquement le jeton JWT de l'en-tête Authorization, elle n'est pas vulnérable à CSRF. Tout site ou API qui obtient le jeton à partir d'un cookie nécessite une atténuation CSRF.
MvdD
13
Cela signifie-t-il que nous pouvons efficacement stocker le jwt dans un cookie et qu'il sera sécurisé si nous envoyons des demandes avec lui dans l'en-tête d'autorisation?
cameronroe
10
@cameronjroe vous pouvez le stocker dans vos cookies mais uniquement si vous n'utilisez pas vos cookies pour l'authentification (vous utilisez vos en-têtes dans ce cas)
Jaakko
1
Les appels AJAX proviennent également du navigateur. Les jetons JWT sont principalement utilisés pour authentifier les API Web (données de service) par rapport aux cookies utilisés pour authentifier les applications Web (balisage de service, images, css et JavaScript)
MvdD
144

Nous devons stocker le JWT sur l'ordinateur client. Si nous le stockons dans un LocalStorage / SessionStorage, il peut être facilement capturé par une attaque XSS. Si nous le stockons dans des cookies, un pirate informatique peut l'utiliser (sans le lire) dans une attaque CSRF et usurper l'identité de l'utilisateur et contacter notre API et envoyer des demandes pour effectuer des actions ou obtenir des informations au nom d'un utilisateur.

Mais il existe plusieurs façons de sécuriser le JWT dans les cookies pour ne pas être volé facilement (mais il existe encore des techniques avancées pour les voler). Mais si vous voulez vous fier à LocalStorage / SessionStorage, vous pouvez y accéder par une simple attaque XSS.

Donc, pour résoudre le problème CSRF, j'utilise des cookies Double Submit dans mon application.

Méthode de double soumission des cookies

  1. Stockez JWT dans un cookie HttpOnly et utilisez-le en mode sécurisé pour transférer via HTTPS.

  2. La plupart des attaques CSRF ont une origine ou un en-tête de référent différent avec votre hôte d'origine dans leurs requêtes. Vérifiez donc si vous en avez dans l'en-tête, proviennent-ils de votre domaine ou non! Sinon, rejetez-les. Si l'origine et le référent ne sont pas disponibles dans la demande, ne vous inquiétez pas. Vous pouvez vous fier au résultat des résultats de validation d'en-tête X-XSRF-TOKEN que j'explique à l'étape suivante.

  3. Bien que le navigateur fournisse automatiquement vos cookies pour le domaine de la demande, il existe une limitation utile: le code JavaScript qui s'exécute sur un site Web ne peut pas lire les cookies d'autres sites Web. Nous pouvons en tirer parti pour créer notre solution CSRF. Pour éviter les attaques CSRF, nous devons créer un cookie supplémentaire lisible par Javascript qui s'appelle: XSRF-TOKEN. Ce cookie doit être créé lorsque l'utilisateur est connecté et doit contenir une chaîne aléatoire et impossible à deviner. Nous enregistrons également ce numéro dans le JWT lui-même en tant que revendication privée. Chaque fois que l'application JavaScript souhaite faire une demande, elle devra lire ce jeton et l'envoyer dans un en-tête HTTP personnalisé. Parce que ces opérations (lecture du cookie, définition de l'en-tête) ne peuvent être effectuées que sur le même domaine de l'application JavaScript,

Angular JS vous simplifie la vie

Heureusement, j'utilise Angular JS dans notre plate-forme et les packages Angular l'approche de jeton CSRF, ce qui nous simplifie la mise en œuvre. Pour chaque demande que notre application Angular fait au serveur, le $httpservice Angular fera ces choses automatiquement:

  • Recherchez un cookie nommé XSRF-TOKEN sur le domaine actuel.
  • Si ce cookie est trouvé, il lit la valeur et l'ajoute à la requête en tant qu'en-tête X-XSRF-TOKEN.

Ainsi, l'implémentation côté client est gérée pour vous, automatiquement! Nous avons juste besoin de définir un cookie nommé XSRF-TOKENsur le domaine actuel côté serveur et lorsque notre API reçoit un appel du client, elle doit vérifier l'en- X-XSRF-TOKENtête et le comparer avec le XSRF-TOKENdans le JWT. S'ils correspondent, alors l'utilisateur est réel. Sinon, c'est une demande falsifiée et vous pouvez l'ignorer. Cette méthode est inspirée de la méthode "Double Submit Cookie".

Mise en garde

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 requêtes au nom de vos utilisateurs en utilisant XSS.

Que vous stockiez votre JWT dans le localStorageou que vous stockiez votre jeton XSRF dans un cookie non HttpOnly, les deux peuvent être facilement saisis par XSS. Même votre JWT dans un cookie HttpOnly peut être capturé par une attaque XSS avancée comme la méthode XST .

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 // <![CDATA[balises et les attributs HTML qui entraînent l'évaluation de JavaScript.

En savoir plus ici:

Iman Sedighi
la source
1
@AranDehkharghani oui je suppose que cela empêche les attaques de relecture, surtout si vous changez le JWT et expirez le JWT précédent à chaque fois qu'il est utilisé par l'API. cela signifie que votre JWT deviendra comme un mot de passe à usage unique (OTP). Vous pouvez utiliser JWT de différentes manières en fonction de votre intérêt pour la sécurité de votre plate-forme.
Iman Sedighi
7
Comme vous l'avez mentionné, si un site Web est vulnérable à XSS, ce n'est qu'une question de temps avant que l'utilisateur ne soit exploité. Il semble que nous négocions une complexité importante contre une très petite augmentation de la sécurité.
shusson
3
@shusson Vous devez vous occuper des attaques XSS et XSRF pour protéger votre JWT. Je ne suis pas d'accord pour dire que vous négociez une complexité importante contre une très petite augmentation de la sécurité. Si la sécurité est importante, vous devez tout mettre en œuvre pour ne pas avoir de vulnérabilités XSS. Cette méthode est conçue pour protéger votre jeton contre les attaques XSRF. mais cela ne signifie pas que vous pouvez ignorer les vulnérabilités XSS.
Iman Sedighi
5
@ImanSedighi Je n'étais pas clair, en stockant le jwt dans un cookie, vous ajoutez de la complexité et vous devez maintenant vous protéger contre XSRF. Alors, pourquoi ne pas simplement utiliser le stockage local avec des jetons à courte durée de vie et se concentrer sur la prévention du XSS?
shusson
2
@Royi Namir: L'usurpation d'identité par Wireshark ne devrait pas être un problème si vous utilisez un certificat SSL à 10 $! Si la sécurité du site Web est importante, vous devez crypter les données et utiliser le protocole HTTPS.
Iman Sedighi
2

Un autre angle sur toute la question du stockage des JWT:

  1. Les JWT ne doivent jamais être stockés dans votre stockage local
  2. En fait, ils ne devraient même pas être stockés dans vos cookies , sauf si vous êtes en mesure de mettre en œuvre une protection CSRF très stricte

Vérifiez ceci pour la motivation

  • JWT en tant que jeton id_token est comme vos informations d'identification utilisateur
  • JWT en tant que jeton d'accès est comme votre jeton de session

L'option la plus sécurisée est en mémoire . Vérifiez ceci pour une plongée en profondeur

Humain
la source