web-dev-qa-db-fra.com

Ai-je besoin d'un jeton CSRF pour jQuery .ajax ()?

J'ai donc une méthode de base .ajax () POST dans un fichier PHP.

De quelles mesures de sécurité ai-je besoin?

Quelques articles mentionnés mentionnaient l'utilisation d'un champ de saisie MD5 caché que vous avez envoyé via AJAX et que vous avez vérifié dans le fichier PHP. Est-ce une méthode assez bonne?

26
Nathan Waters

Le CSRF présente le risque qu’un site externe puisse envoyer des données au vôtre et le navigateur de l’utilisateur envoie automatiquement le cookie d’authentification.

Ce dont vous avez besoin, c’est d’une façon que l’action de réception (à laquelle votre méthode $.ajax() envoie des données à POST]) soit en mesure de vérifier que la demande provient d’une autre page de votre site, et non d’un site externe.

Il existe deux façons de procéder, mais la méthode recommandée consiste à ajouter un jeton à la demande que vous pouvez vérifier et que les pirates ne peuvent pas accéder.

Au plus simple:

  • Lors de la connexion, créez un jeton de chaîne aléatoire longue et enregistrez-le contre l'utilisateur.
  • Ajoutez un paramètre à la demande $.ajax() qui inclut le jeton.
  • Sur demande, vérifiez que le jeton correspond à celui que vous avez enregistré pour l'utilisateur.
  • Si le jeton ne correspond pas, vous avez un hack CSRF.

Le pirate informatique ne peut pas accéder à votre base de données et ne peut pas réellement lire la page que vous avez envoyée à l'utilisateur (à moins qu'il ne subisse une attaque XSS, mais c'est un autre problème) et ne peut donc usurper le jeton.

Tout ce qui compte avec le jeton est que vous pouvez prédire (et le valider) et que le pirate ne peut pas

Pour cette raison, il est plus facile de générer quelque chose de long et aléatoire et de le stocker dans la base de données, mais vous pouvez créer un contenu chiffré à la place. Cependant, je ne parlerais pas simplement du nom d'utilisateur MD5: si les attaquants de CSRF découvrent comment générer vos jetons, vous serez piraté.

Une autre méthode consiste à stocker le jeton dans un cookie (plutôt que dans votre base de données), car les attaquants ne peuvent ni lire ni modifier vos cookies, mais simplement les renvoyer. Ensuite, vous êtes le jeton dans le HTTP POST correspond au jeton dans le cookie.

Vous pouvez les rendre beaucoup plus sophistiqués, par exemple un jeton qui change à chaque utilisation (empêchant la resoumission) ou un jeton spécifique à l'utilisateur et à l'action, mais c'est le modèle de base.

35
Keith

En termes de falsification de requête, la manière dont le client envoie la requête importe peu comment elle est reçue. Les mêmes règles CSRF s'appliquent à un message ajax que tout autre type de message. 

Je recommande la lecture du aide-mémoire de prévention CSRF . L'utilisation d'un jeton secret par utilisateur est la forme de protection la plus courante.

2
rook

Voici une démonstration simple que vous pouvez essayer avec Django:

Sur la page HTML

{%block content%}
<form id="userForm">
{%csrf_token%}
  <input type="text" id="username" placeholder="User Name">
  <input type="password" id="password" placeholder="Password">
</form>
{%endblock%}

Code de script Java

%(document).on('submit','#userForm',function(e){
   e.preventDefault();

 $.ajax({

    type = 'POST',

    url:'path/to/url',

    data:{
     username:$('#username').val(),
     password:$('#password').val(),
     csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken').val()
    },

   success:function(data){
       alert('Successfull');
   }
  });

});
0
user7032676

Aucun jeton n'est nécessaire, mais vous devez néanmoins protéger les fonctions qui changent d'état contre CSRF.

Une façon simple de procéder consiste à ajouter un en-tête envoyé avec la demande AJAX. Aucun jeton aléatoire n'est nécessaire.

Cela fonctionne parce que:

  • Les en-têtes HTML ne peuvent pas avoir d'en-têtes personnalisés ajoutés par un attaquant.
  • Les en-têtes personnalisés ne peuvent pas être transmis entre domaines sans que CORS soit activé.

Bien sûr, le code côté serveur doit s'assurer que l'en-tête est présent avant d'exécuter son action.

Plus d'infos: Quel est l'intérêt de l'en-tête X-Requested-With?

0
SilverlightFox