TUTORIELS 
PHP : se protéger contre les attaques XSS et CSRF
(Fourni par Direction|PHP)

Page 1 | 2 | 3

Tout ce qu'il faut savoir pour éviter de faire de son application PHP un danger potentiel pour son site.
 (octobre 2003)
 
Discutez en sur les forums
Se protéger contre CSRF
Protéger vos applications contre des attaques CSRF est plus difficile que de les protéger contre des attaques XSS. Cependant, il existe quelques conseils que vous pouvez sui-vre pour diminuer le risque de voir une attaque réussir.

1. Utilisez la méthode POST dans les formulaires
Parce que les demandes pour les ressources intégrées sont faites en utilisant la méthode de requête GET, une des manières de distinguer les requêtes légitimes HTTP des requêtes simulées utilisant la falsification de la balise <img> est d'utiliser la méthode POST comme méthode de formulaire. Le formulaire utilisé pour soumettre un post à forum.exemple.org pourrait spécifier ceci, comme suit :

<form action="/developpeur/add_post.php" method="post">

Bien sûr, ce n'est pas une bonne idée de choisir aveuglément la méthode POST pour chaque formulaire, mais les formulaires qui sont des cibles potentielles pour les attaques devraient certainement utiliser POST plutôt que GET. Comme avec n'importe quelle mesure de sécurité, cette étape ne garantit pas une protection totale, et vos uti-lisateurs peuvent être dupés en envoyant bien des requêtes POST falsifiées. Par exemple, ils peuvent cliquer sur une image qui soumet un formulaire, incluant n'importe quel nombre de champs de formulaire cachés. L'exemple suivant illustre cette technique :

<form action="/developpeur/add_post.php" method="post">
  <input type="hidden" name="post_subject" value="Exemple CSRF" />
  <input type="hidden" name="post_message" value="C'est pas moi!" />
  <input type="image" src="http://images.exemple.org/csrf.png" />
</form>

Ce style d'attaque, cependant, est plus visible pour la victime, parce qu'un navigateur considère la requête POST comme une ressource apparentée. Aussi, l'utilisateur prendra conscience qu'il est victime d'un piège, même si ce n'est qu'après être tombé de dedans (en regardant l'écran affichant le nouveau POST).

2. Utiliser le tableau $_POST plutôt que les variables créées grâce à register_globals
Si forum.exemple.org a activé l'option register_globals, et que des références entre $post_subject et $post_message et le tableau $_POST ont été exploitées dans le script add_post.php, l'utilisation de la méthode POST pour le formulaire n'aide en rienpour vous permettre de faire la distinction entre une requête légitime et une attaque CSRF. Alors que les register_globals ont acquis une mauvaise réputation ces dernières années, ceci est principalement dû à une programmation inadéquate par les développeurs inexpérimentés. Les attaques CSRF sont une raison légitime de désactiver l'option register_globals, quelles que soient votre expérience et expertise en terme de sécurité.
Bien sûr, on pourrait vous dire que $_POST peut être uti-lisé conjointement avec l'option register_globals, mais cela irait à l'encontre du sujet. Un autre argument légitime pour la défense de l'option register_globals peut être qu'il est possible de se protéger contre CSRF malgré l'option register_globals, en essayant de contraindre vos visiteurs à utiliser uniquement vos propres formulaires. Alors que ceci est un argument solide, cela suggère seulement que les register_globals sont une méthode, pas un trou de sécurité ; c'est un risque de sécurité.

3. Ne simplifiez pas les actions importantes
Le risque est plus grand si un seul clic d'un utilisateur légitime peut provoquer une action très importante, que si plusieurs requêtes sont nécessaires pour arriver au même résultat. Même une simple page de vérification peut être utile, tant que la page ne peut pas être contournée (par exemple, s'il suffit d'avoir ?verified=yes dans l'URL, ça ne sert à rien). De même, plusieurs requêtes GET consécutives peuvent être simulées en utilisant une série d'images, mais plusieurs requêtes POST consécutives sont plus difficiles à contre-faire.

4. Obligez l'utilisateur à utiliser vos formulaires HTML
Le coeur du problème de CSRF est qu'une requête falsifiée peut imiter un formulaire. Si vous pouvez, de quelque manière que ce soit, déterminer si votre propre page web a été utilisée pour soumettre le formulaire, vous pouvez pratiquement éliminer le risque d'une attaque un CSRF. Après tout, si l'utilisateur n'a pas demandé le formulaire récemment, pourquoi un formulaire venant de cet utilisateur serait considéré comme valide ? C'est, bien sûr, plus facile à dire qu'à faire, mais il y a quelques moyens techniques pour le faire. Mes techniques préférées sont celles qui impliquent un secret partagé entre le serveur et l'utilisateur légitime. Par exemple, étudiez le listing 3 comme un remplacement du formulaire utilisé pour poster un message sur forum.exemple.org.

<?php
  $token = md5(time());
  $_SESSION['token'] = $token;
  $_SESSION['token_timestamp'] = time();
?>
<form action="/developpeur/add_post.php" method="post">
  <input type="hidden" name="token" value="<? echo $token; ?>" />
  <p>Subject: <input type="text" name="post_subject" /></p>
  <p>Message: <textarea name="post_message"></textarea></p>
  <p><input type="submit" value="Add Post" /></p>
</form>

A chaque fois qu'un utilisateur demande ce formulaire, une nouvelle marque est générée et cette marque est sauvegardée sur le serveur (dans la session de l'utilisateur, remplaçant les précédentes) et incluse dans le formulaire comme une variable cachée du formulaire. Ainsi, quand un message est posté, non seulement la marque est comparée à celle de la session de l'utilisateur, mais un temps mort peut également être appliqué pour minimiser davantage le risque. Cette tactique rend une attaque CSRF extrêmement difficile et par conséquent représente un fort niveau de protection.

Conclusion
J'espère que vous avez maintenant une bonne compréhension de XSS et CSRF aussi bien que de la sécurité d'une application web en général. La clé de la sécurité est de faciliter la vie aux utilisateurs légitimes et de la rendre difficile aux pirates. Aucune application n'est complètement sécurisée, aussi essayez de vous concentrer sur la manière de rendre les attaques aussi difficiles à réaliser que possible. Chaque obstacle aide et même un peu de secret peut être utile, en dépit de ce que certaines personnes peuvent vous faire croire.

Page 1 | 2 | 3

 
[ Chris ShiflettDirection|PHP pour JDNet
 
Accueil | Haut de page