web-dev-qa-db-fra.com

Différence entre CSRF et X-CSRF-Token

Quelle est la différence entre l'utilisation X-CSRF-Token dans l'en-tête ou le jeton dans un champ caché?

Quand utiliser un champ caché et quand utiliser l'en-tête et pourquoi?

Je pense que X-CSRF-Token c'est quand j'utilise javascript/ajax mais je ne suis pas sûr

17
monkeyUser

La protection CSRF se décline en plusieurs méthodes.

La méthode traditionnelle ( le modèle "jeton de synchronisation" ) implique généralement de définir une valeur de jeton valide unique pour chaque demande, puis de vérifier cette valeur unique lors de l'envoi ultérieur de la demande. Cela se fait généralement en définissant un champ de formulaire masqué. La valeur du jeton est généralement de courte durée et associée à cette session, donc si un pirate tente de réutiliser une valeur qu'il a vue précédemment sur la page, ou essaie de deviner la valeur, il échouera probablement. Ainsi, seules les demandes de votre application fonctionneront et les demandes falsifiées de l'extérieur de votre application/domaine (alias la contrefaçon de demande intersite) échoueront.

L'inconvénient est que votre application doit définir ce jeton caché sur tous les formulaires HTML. Ces pages doivent maintenant être générées dynamiquement par une application, alors qu'elles étaient peut-être auparavant en HTML statique. Il peut également casser le bouton de retour (car vous devez actualiser le formulaire pour régénérer une autre valeur CSRF unique). Vous devez également maintenant garder une trace des jetons valides côté serveur et vérifier que toutes les demandes utilisent un jeton valide. Cela peut prendre un peu d'effort supplémentaire pour mettre en œuvre et maintenir à l'avenir.

Une approche alternative (appelée le modèle de "jeton de cookie à en-tête" ) consiste à définir un cookie une fois par session et à avoir JavaScript lu ce cookie et défini un en-tête HTTP personnalisé (souvent appelé X-CSRF-TOKEN ou X-XSRF-TOKEN ou juste XSRF-TOKEN) avec cette valeur. Toute demande enverra à la fois l'en-tête (défini par Javascript) et le cookie (défini par le navigateur comme un en-tête HTTP standard), puis le serveur pourra vérifier cette valeur dans le X-CSRF-TOKEN l'en-tête correspond à la valeur de l'en-tête du cookie. L'idée étant que seul JavaScript exécuté sur le même domaine aurait accès au cookie, donc JavaScript d'un autre domaine ne pouvait pas définir cet en-tête à la bonne valeur (en supposant que la page n'est pas vulnérable à XSS qui donnerait accès à ce cookie) . Même les faux liens (par exemple dans un e-mail de phishing) ne fonctionneraient pas non plus, car même s'ils semblaient provenir du bon domaine, seul le cookie sera défini mais pas X-CSRF-TOKEN entête.

Cela peut être BEAUCOUP plus facile à implémenter que le modèle de jeton Synchronizer car vous n'avez pas besoin de définir le jeton pour chaque appel à chaque formulaire, et la vérification est relativement simple aussi (vérifiez simplement que le cookie correspond à l'en-tête) plutôt que de suivre les jetons CSRF validité. Il vous suffit de définir un cookie sur une valeur aléatoire pour chaque session. Certains frameworks frontaux généreront même automatiquement l'en-tête pour vous s'ils voient le cookie (par exemple AngularJS le fait par exemple).

L'inconvénient est qu'il nécessite JavaScript pour fonctionner (mais cela peut ne pas être un problème si votre application ne fonctionne pas sans JavaScript de toute façon) et il ne fonctionnera que pour les demandes émises par JavaScript (par exemple les demandes XHR) - demandes de formulaire HTML régulières ne définirait pas l'en-tête. Une variation à ce sujet (le modèle "Double Submit Cookie" ) met le X-CSRF-TOKEN valeur dans un champ de formulaire masqué plutôt que dans un en-tête HTTP pour contourner ce problème, tout en conservant la logique côté serveur plus simple que le modèle de jeton de synchroniseur traditionnel. Il convient de noter cependant que OWASP indique certaines faiblesses avec la méthode Double Submit , lorsque l'attaquant est en mesure de définir le cookie (ce qui est souvent plus facile que de lire le cookie) recommande donc de valider le jeton CSRF dans ce Cas.

De plus, le modèle de jeton Synchronizer peut permettre à des contrôles supplémentaires d'appliquer le flux (par exemple, le jeton CSRF de champ caché ne sera défini que lorsque l'application pense que vous avez envoyé une demande valide pour obtenir ce formulaire).

Oh, et certains scans de sécurité détecteront le fait que le cookie n'est pas défini avec le HTTP-Only flag peut donc être lu par JavaScript - mais c'est délibéré car il doit pouvoir le lire! Fausse alerte. Vous penseriez que tant que vous utilisez un nom commun comme X-CSRF-TOKEN ils sauraient ne pas signaler cela, mais l'ont vu souvent.

32
Barry Pollard

Tous sont destinés à la protection contre la contrefaçon de demandes intersites et vous devez utiliser un seul d'entre eux lors de l'envoi d'une demande au backend.

csrf:

  • Utilisé dans les formulaires html (pas ajax)
  • nous ne pouvons pas définir l'en-tête de demande dans les formulaires html, nous devons donc l'envoyer via la saisie du formulaire comme champ masqué.

jeton x-csrf:

  • Il est ajouté à l'en-tête de demande pour les demandes ajax.
  • Lorsque vous utilisez laravel comme backend. laravel vérifie cet en-tête automatiquement et le compare à un csrf valide dans la base de données.

jeton x-xsrf:

  • Il est ajouté à l'en-tête de demande pour les demandes ajax.
  • Les bibliothèques populaires comme angular et axios, obtiennent automatiquement la valeur de cet en-tête à partir de xsrf-token cookie et l'envoyer à chaque demande.
  • Parce qu'il est populaire, laravel crée ce cookie dans chaque réponse.
  • donc quand vous utilisez par exemple axios et laravel vous n'avez rien à faire. L'utilisateur doit simplement être connecté, puis utiliser le middleware 'auth' fera le travail.
  • C'est une chaîne plus grosse que x-csrf-token car les cookies sont cryptés dans laravel.
3
Ahmad Mobaraki