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 XSS
Il y a quelques lignes directrices que vous pouvez suivre pour vous aider à protéger vos applications contre les attaques XSS. Heureusement, vous pouvez déjà en anticiper certaines.

1. Filtrer toutes les données étrangères
Le conseil le plus important est de filtrer toutes les données étrangères. Si vous découvrez une vulnérabilité dans l'une de vos applications, elle devrait être due à un défaut de logique de filtration, et non à une complète absence de logique de filtration.

2. Utiliser des fonctions existantes
Laissez PHP vous aider. Des fonctions comme htmlentities(), strip_tags(), et utf8_decode() peuvent vous aider à écrire votre logique de filtrage. La clé de la sécurité est de d'exploiter les fonctions intégrées de PHP autant que possible. Par exemple, si vous voulez vous assurer que les entités HTML sont proprement encodées, il est beaucoup plus sûr d'utiliser htmlentities() que d'écrire votre propre fonction qui fait la même chose. Sans considérer la performance (htmlentities() est aussi plus rapide), la fonction clé-en-main a été certainement revue et testée par plus de gens que votre code, et elle doit sûrement contenir moins d'erreurs qui conduisent à des vulnérabilités.

3. Seulement autoriser un contenu validé
Quand vous écrivez votre logique de filtrage, autorisez seulement le contenu que vous considérez sûr plutôt que d'essayer d'exclure le contenu que vous jugez peu sûr. Par exemple, si un utilisateur fournit un nom de famille, vous pouvez commencer en autorisant seulement les ca-ractères alphabétiques et les espaces, puisqu'ils sont plutôt sûrs (bien sûr, vous voulez vous assurer également que la longueur est réaliste). Alors si des noms comme Berners-Lee et O'Reilly sont rejetés alors qu'ils sont parfaitement valides, vous résoudrez facilement ce problème. Un rapide changement dans votre logique de filtration pour permettre également les apostrophes et les traits d'union est tout ce qu'il faudra. Avec le temps, vous allez perfectionner votre logique de filtration, et éviter ce type de problème.

La bonne démarche est de ne pas hésiter à oublier un ca-ractère valide lors de la conception de votre filtre, plutôt que d'avoir un recours trop laxiste aux caractères généraux : il est bien pire d'autoriser un caractère dangeureux que d'en rejeter un sûr. De plus, quand vous vous trompez par trop de prudence, une rapide correction résout le problème et ceux qui ont rencontré le problème vous le feront savoir. Si vous créez une vulnérabilité XSS, vous allez apprendre la réalité par la méthode la plus difficile : vous ne le saurez que lorsqu'il sera trop tard, et que votre application est déjà compromise.

4. Utiliser une convention de nommage stricte
Il y a de nombreuses conventions de dénomination que les développeurs utilisent pour savoir si une variable particulière contient des données filtrées ou non filtrées. Choisissez celle qui vous semble la plus intuitive parmi celles-ci et utilisez-la régulièrement dans tous vos développements. La plupart de ces conventions de nommage utilisent des termes descriptifs comme propre (clean) et sale (dirty), faisant respectivement allusion aux données filtrées et non filtrées (le processus de filtrage des données est communément appelé nettoyage ou "scrubbing"). Certaines des données non filtrées sont polluées. Si vous employez l'une de ces conventions de nommage, c'est plus facile pour vous de garder la trace de vos données. Le plus important pour implémenter une convention de nommage est d'extraire uniquement les données filtrées et de s'assurer qu'aucune des données non filtrées ne soit improprement nommée.

5. Soyez créatifs
Armé d'une bonne compréhension du web ainsi que de votre propre application, vous êtes la personne la plus qualifiée pour assurer la sécurité et protéger votre application et ses utilisateurs, des attaques. Il est important d'être créatif et d'essayer de ne pas faire de suppositions sur la manière dont les utilisateurs interagissent avec votre site. Les données étrangères peuvent venir de n'importe quoi, et vous verrez bientôt que même un utilisateur légitime peut être complice d'une attaque, sans le savoir. Ne faites confiance à aucune donnée tant que votre filtrage des données ne l'a pas approuvé.

Cross-Site Request Forgeries
Cross-Site Request Forgeries (CSRF) sont un style d'attaques à l'opposé des XSS. Plutôt que d'exploiter la confiance de l'utilisateur en un site, elles exploitent la con-fiance du site web faite à ses utilisateurs. Dans le cas des attaques XSS dont nous venons de discuter, l'utilisateur est la victime. Dans le cas de CSRF, l'utilisateur est un complice sans le savoir.

Parce que CSRF implique la simulation de requête HTTP, il est important de comprendre d'abord ce qu'est une requête HTTP. Le web est un environnement client/serveur, et HTTP (Hypertext Transfer Protocol) est le protocole que les clients et les serveurs web utilisent pour communiquer. Les clients Web (les fournisseurs étant l'exemple le plus courant) envoient des requêtes HTTP aux serveurs web, et ces serveurs renvoient une réponse HTTP. Une demande et sa réponse correspondante constituent une transaction HTTP. Un exemple de base d'une requête HTTP est le suivant :

GET /image.png HTTP/1.1
Host: www.exemple.org

La caractéristique la plus importante de cette demande est qu'elle est identique à la première demande excepté pour le chemin de la ressource. Ceci est dû au fait que les demandes d'images ne sont pas différentes des demandes de toutes les autres URL. Une ressource est une ressource; il n'y a pas de méthode pour que le browser puisse savoir que le serveur web va lui retourner une image. La figure 3 illustre la manière dont l'attaque CSRF abuse de ce comportement.
Dans le but d'apprécier le danger que ce comportement représente, considérez un simple forum web situé à l'adresse http://forum.exemple.org/ qui utilise le formulaire HTML suivant pour permettre aux utilisateurs d'ajouter un message :

<form action="/developpeur/add_post.php">
  <p>Sujet : <input type="text" name="post_subject" /></p>
  <p>Message : <textarea name="post_message"></textarea></p>
  <p><input type="submit" value="Envoyer" /></p>
</form>

Comme la méthode du formulaire n'est pas mentionnée, une requête GET est envoyée, et les champs du formulaire sont inclus en tant que variables URL. Si un utilisateur saisit "foo" en tant que sujet et "bar" comme message, une requête HTTP similaire à la suivante est envoyée (en admettant que la session d'identification est propagée via un cookie):

GET /add_post.php?post_subject=foo&post_message=bar HTTP/1.1
Host: forum.exemple.org
Cookie: PHPSESSID=123456789

Si quelqu'un veut simuler des envois de message dans un tel forum, tout ce qu'il doit faire est de dupliquer le format de cette demande et de le faire envoyer par la victime. Alors que cela ne semble pas facile à faire, la réalité est bien différente. Considérez la balise <img> suivante :

<img src="http://forum.exemple.org/add_post.php?post_subject=foo
&post_message=bar" />

Quand un navigateur demande cette image, la requête HTTP semble identique à celle de l'exemple précédent, y compris le cookie de session. Avec un simple changement dans l'URL référencé dans cette balise <img>, un attaquant peut modifier le sujet et le message par tout ce qu'il désire. Tout ce que doit faire l'attaquant pour lancer l'attaque est que la victime visite une URL qui contienne cette balise <img>, et la victime va poster un message de l'attaquant sur le forum. Parce que les demandes de ressources intégrées ne sont pas censées être indiquées, la victime n'aura pas connaissance de cette attaque.
Les types d'attaques CSRF les plus dangereux peuvent falsifier les commandes qui règlent des achats sur un site web ou assurent des fonctions administratives sur une application, même hors web. Considérez une application intranet située à l'URL http://192.168.0.1/admin/ qui permet aux utilisateurs autorisés de renvoyer des employés. Même avec un mécanisme de session parfait, qui est immunisé contre l'usurpation d'identité, combiné avec le fait que cette application ne peut pas être accessible aux utilisateurs à l'extérieur du réseau local, une attaque CSRF peut réussir avec quelque chose d'aussi simple que cette balise HTML. La figure 4 illustre ce type particulier d'attaque CSRF et comment il peut être utilisé pour pénétrer un autre réseau local sécurisé.

La plus frustrant dans les attaques CSRF est que l'utilisateur légitime fait lui-même la requête. Alors, sans regarder le niveau de perfection d'identification de l'utilisateur et/ou du mécanisme de gestion des sessions, une attaque CSRF malgré tout réussir. C'est pourquoi, comme il n'est pas réaliste d'empêcher les sites d'utiliser la balise <img> (particulièrement puisque l'attaque pourrait forcer la victime à visiter le propre site de l'attaquant), le problème doit être résolu par le site victime.

Page 1 | 2 | 3

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