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
|