Berceaux de sécurité: CSRF

image

MalgrĂ© le fait que dans la derniĂšre liste publiĂ©e des vulnĂ©rabilitĂ©s des attaques CSRF OWASP Top 10 2017 sont classĂ©es comme «SupprimĂ©es, mais pas oubliĂ©es», nous avons dĂ©cidĂ© qu'il ne serait pas superflu de rappeler Ă  nouveau comment se dĂ©fendre contre les attaques CSRF, en s'appuyant sur celles les mĂȘmes rĂšgles que celles fournies par l'OWASP.

Utilisation du jeton CSRF

L'utilisation d'un jeton (mĂ©thodes sans Ă©tat et avec Ă©tat) est la mĂ©thode de protection principale et la plus populaire. Le jeton doit ĂȘtre unique pour chaque session utilisateur, gĂ©nĂ©rĂ© par un gĂ©nĂ©rateur de nombres pseudo-alĂ©atoires cryptographiquement robuste. OWASP recommande Ă©galement d'utiliser les algorithmes AES256-GCM et SHA256 / 512 pour le chiffrement lors de l'utilisation de HMAC.

Il existe plusieurs approches pour travailler avec des jetons: jeton de synchronisation, modÚle de jeton basé sur le chiffrement, jeton basé sur HMAC

Jeton de synchroniseur

En utilisant l'approche Synchronizer Token (méthode statefull), cela signifie envoyer un jeton à chaque demande, ce qui implique des modifications cÎté serveur. Si le jeton n'est pas valide, le serveur rejette la demande.
Lors de l'envoi d'une demande au serveur, il est recommandĂ© d'ajouter un jeton aux paramĂštres de la demande plutĂŽt qu'Ă  l'en-tĂȘte. Si vous insĂ©rez nĂ©anmoins un jeton dans l'en-tĂȘte de la demande, assurez-vous qu'il n'est pas enregistrĂ© sur le serveur. Le jeton reçu peut ĂȘtre stockĂ© cĂŽtĂ© client dans un champ cachĂ©:

<form action="/post.php" method="post"> <input type="hidden" name="CSRFToken" value="l5824xNMAYFesBxing975yR8HPJlHZ"> ... </form> 


dans les en-tĂȘtes:

 POST /page HTTP/1.1 Accept: application/json, application/xml, text/json, text/x-json, text/javascript, text/xml User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36 Content-Type: application/json Host: example.com X-CSRF-TOKEN: l5824xNMAYFesBxing975yR8HPJlHZ 


ou dans les cookies

 POST /page HTTP/1.1 Host: example.com Set-Cookie: CSRFToken=l5824xNMAYFesBxing975yR8HPJlHZ; Content-Type: application/x-www-form-urlencoded 


OWASP recommande de stocker le jeton dans les en-tĂȘtes, expliquant que mĂȘme si le jeton est ouvert ou expirĂ©, l'attaquant ne pourra toujours pas simuler la demande, en raison des navigateurs.

De plus, pour augmenter le niveau de sĂ©curitĂ© de la mĂ©thode proposĂ©e, il est proposĂ© de gĂ©nĂ©rer un nom de paramĂštre de jeton alĂ©atoire et / ou le jeton lui-mĂȘme pour chaque requĂȘte. Avec cette approche, le temps pendant lequel l'attaquant peut utiliser le jeton volĂ© est minimal. Cependant, cela peut entraĂźner des problĂšmes de convivialitĂ©. Par exemple, un clic sur le bouton «Retour» peut entraĂźner l'envoi d'un token invalide au serveur, qui Ă©tait contenu sur la page prĂ©cĂ©dente.

L'envoi d'un jeton Ă  l'aide d'une demande GET n'est pas recommandĂ©, car avec cette approche, le jeton peut ĂȘtre rĂ©vĂ©lĂ©: dans l'historique du navigateur, les fichiers journaux, les en-tĂȘtes de rĂ©fĂ©rent.

Jeton basé sur le chiffrement

Cette approche est sans état, car elle utilise le chiffrement / déchiffrement pour valider le jeton et ne nécessite donc pas le stockage du jeton cÎté serveur.

Le serveur gĂ©nĂšre un jeton composĂ© d'un identifiant de session et d'un horodatage (pour empĂȘcher une attaque de relecture). Pour le chiffrement, il est recommandĂ© d'utiliser l'algorithme de chiffrement AES256 en mode de chiffrement par bloc GSM / GSM-SIV. L'utilisation du mode ECB est fortement dĂ©conseillĂ©e. Le jeton chiffrĂ© par le serveur est retournĂ© au client de la mĂȘme maniĂšre que dans le cas de «Synchronizer Token» dans le champ de formulaire masquĂ© ou dans l'en-tĂȘte / paramĂštre de rĂ©ponse. À la rĂ©ception du jeton, le serveur doit le dĂ©chiffrer, puis vĂ©rifier l'identifiant de session et Ă©galement vĂ©rifier l'horodatage avec l'heure actuelle et s'assurer qu'il ne dĂ©passe pas la durĂ©e de vie du jeton dĂ©finie.
Si la vĂ©rification de l'identifiant de session rĂ©ussit, mais pas la chronologie, la demande peut ĂȘtre considĂ©rĂ©e comme valide. Dans tous les autres cas, il est recommandĂ© de rejeter la demande et de l'enregistrer afin de mieux comprendre comment rĂ©pondre Ă  ces demandes.

Jeton basé sur HMAC

Il ne nécessite pas non plus de stockage de jeton, le principe de fonctionnement est similaire au jeton basé sur le chiffrement, sauf qu'au lieu de chiffrer le jeton, la fonction HMAC (code d'authentification de message basé sur le hachage) est utilisée pour générer le jeton (il est recommandé d'utiliser SHA256 ou un algorithme plus puissant). Dans ce cas, le jeton est le résultat de la fonction HMAC de l'identifiant de session utilisateur + horodatage.

Automatisation des jetons

Le principal problÚme dans la lutte contre les attaques CSRF est que les développeurs oublient souvent simplement d'ajouter des fonctionnalités pour travailler avec des jetons. Pour éviter de tels problÚmes, il vaut la peine d'automatiser ce processus:

‱ Ă©crire un wrapper qui ajoute automatiquement un jeton aux requĂȘtes via la balise form ou lors de l'utilisation d'ajax. Par exemple, Spring Security adopte une approche similaire chaque fois que la balise <form: form> est utilisĂ©e.

‱ Ă©crire un hook qui intercepte le trafic et ajoute des jetons Ă  toutes les ressources vulnĂ©rables. Puisqu'il est assez difficile d'analyser quelle demande le changement d'Ă©tat effectue, nĂ©cessitant un jeton, il est recommandĂ© d'inclure des jetons dans toutes les rĂ©ponses POST, mais cela vaut la peine de considĂ©rer le coĂ»t des performances

‱ ajouter automatiquement un jeton lors du rendu d'une page. Cette approche est utilisĂ©e par CSRF Guard: des jetons sont ajoutĂ©s Ă  tous les attributs href et src, aux champs cachĂ©s et dans toutes les formes

Avant d'essayer d'Ă©crire votre propre systĂšme de gĂ©nĂ©ration automatique de jetons, il est recommandĂ© de prĂ©ciser si le framework que vous utilisez a la capacitĂ© de fournir une protection contre les attaques CSRF par dĂ©faut. Par exemple, le mĂȘme framework Django implĂ©mente une protection contre CSRF.


Connexion CSRF

En utilisant CSRF dans le formulaire de connexion, un attaquant peut se connecter,
déguisé en victime. De telles vulnérabilités ont été rencontrées par des géants tels que PayPal et Google.
Vous pouvez gérer CSRF dans le formulaire de connexion en créant des pré-sessions qui sont créées avant l'authentification de l'utilisateur et en incluant des jetons dans le formulaire de connexion.


Cookie Samesite

SameSite Cookie est un attribut dĂ©crit dans la RFC6265bis dont le but est de contrer les attaques CSRF. Cela fonctionne comme suit. L'une des mĂ©thodes de protection consiste Ă  vĂ©rifier l'origine et les en-tĂȘtes de rĂ©fĂ©rent, grĂące auxquels vous pouvez comprendre d'oĂč provient la demande, mais cette approche nĂ©cessite la mise en Ɠuvre d'un mĂ©canisme de vĂ©rification. En utilisant l'attribut SameSite, nous restreignons l'envoi de cookies avec une demande de ressources Ă©trangĂšres. Cet attribut a plusieurs valeurs possibles: Strict, Lax et None.
L'utilisation de la valeur stricte signifie que le navigateur n'enverra pas de cookies provenant de sources qui ne correspondent pas au nom de domaine de la ressource actuelle.
La valeur lax permet de ne pas bloquer les cookies des ressources externes, dont la transition a été effectuée de maniÚre sécurisée - en utilisant le protocole HTTPS. Lax établit un équilibre entre convivialité et sécurité.

La définition d'un attribut est assez simple:

 Set-Cookie: JSESSIONID=xxxxx; SameSite=Strict Set-Cookie: JSESSIONID=xxxxx; SameSite=Lax 


Au moment de la rédaction, la prise en charge de l'attribut par les navigateurs ressemble à ceci:

image


Il est important de se rappeler que cet attribut doit ĂȘtre utilisĂ© comme mesure de protection supplĂ©mentaire et non comme un moyen de se passer de l'utilisation du jeton CSRF.

VĂ©rification des en-tĂȘtes

Comme mentionnĂ© ci-dessus, l'une des mĂ©thodes de protection consiste Ă  vĂ©rifier les valeurs de rĂ©fĂ©rence et d'origine de l'en-tĂȘte de demande.
L'essence de cette vĂ©rification est de vĂ©rifier les valeurs des en-tĂȘtes cĂŽtĂ© serveur. S'ils correspondent Ă  la ressource, la demande est considĂ©rĂ©e comme correcte, sinon elle est rejetĂ©e. Si l'en-tĂȘte Origin est manquant, vous devez vous assurer que la valeur Referrer correspond Ă  la ressource actuelle. OWASP recommande de rejeter les demandes qui ne contiennent pas d'en-tĂȘtes Origin ou Referrer. Vous pouvez Ă©galement enregistrer toutes ces demandes afin de les analyser plus tard et de dĂ©cider comment les traiter.

Cependant, les choses se compliquent si votre application se trouve derriĂšre un serveur proxy, car l'URL dans l'en-tĂȘte sera diffĂ©rente. Dans ce cas, il existe plusieurs options:
‱ Configurez votre application afin de toujours connaĂźtre l'origine de la demande. Le problĂšme avec cette approche est de dĂ©finir la bonne valeur si votre application est dĂ©ployĂ©e dans plusieurs environnements (par exemple, dev, QA, production), ce qui conduit Ă  un problĂšme de support
‱ utilisez l'en-tĂȘte Host. Cet en-tĂȘte vous permettra de dĂ©terminer la source de la demande, quel que soit l'environnement.
‱ utiliser l'en-tĂȘte X-Forwarded-Host, dont le but est de stocker les en-tĂȘtes d'origine reçus par le serveur proxy

Toutes les mĂ©thodes dĂ©crites ne fonctionnent que lorsque les en-tĂȘtes d'origine et de rĂ©fĂ©rence sont prĂ©sents. Mais il y a des cas oĂč ces en-tĂȘtes sont manquants. Voici quelques cas oĂč ces en-tĂȘtes ne sont pas inclus dans la demande:
‱ IE 11 n'inclut pas l'en-tĂȘte Origin pour les sites de confiance. Il ne reste plus qu'Ă  s'appuyer sur l'en-tĂȘte Referer.
‱ dans le cas d'une redirection, Origin n'est pas inclus dans la demande, car on pense qu'il peut contenir des informations confidentielles qui ne devraient pas ĂȘtre envoyĂ©es Ă  une autre source
‱ L'en-tĂȘte d'origine est activĂ© pour toutes les demandes intersites, mais la plupart des navigateurs l'ajoutent uniquement pour les demandes POST / DELETE / PUT

En rĂšgle gĂ©nĂ©rale, une petite quantitĂ© de trafic tombe dans les catĂ©gories dĂ©crites, mais souvent vous ne voulez pas perdre mĂȘme cette petite partie d'utilisateurs, par consĂ©quent, il est considĂ©rĂ© comme valide de demander avec une valeur nulle pour origin / referrer ou avec une valeur correspondant Ă  la liste des domaines de confiance.

Double soumettre le cookie

Cette approche est assez simple Ă  implĂ©menter et ne nĂ©cessite pas de stockage du token cĂŽtĂ© serveur (sans Ă©tat). L'essence de la mĂ©thode est d'envoyer le jeton dans le paramĂštre de demande et dans les cookies par l'utilisateur. Pour chaque demande nĂ©cessitant un changement d'Ă©tat, nous vĂ©rifions la valeur du jeton dans les cookies et dans la demande. Si la vĂ©rification de l'identifiant de session rĂ©ussit, mais pas la chronologie, la demande peut ĂȘtre considĂ©rĂ©e comme valide

Source: https://habr.com/ru/post/fr476880/


All Articles