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
Stockez JWT dans un cookie HttpOnly et utilisez-le en mode sécurisé pour transférer via HTTPS.
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.
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 $http
service 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-TOKEN
sur le domaine actuel côté serveur et lorsque notre API reçoit un appel du client, elle doit vérifier l'en- X-XSRF-TOKEN
tête et le comparer avec le XSRF-TOKEN
dans 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 localStorage
ou 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: