Mauvaise Saint Valentin pour Christine Boutin

parodie martine n'a pas de culotte

une des merveilles du défunt "Martine cover generator"

Cas d’école : un exemple d’injection de code css par transmission de formulaire.

Les faits

Mardi 14 février, jour de la Saint Valentin, Christine Boutin annonce qu’elle retire sa candidature, au profit du candidat de l’UMP.

Dans la journée, des messages (sur Facebook, twitter, des blogs, le mail ou autre)
invitent à cliquer sur un lien, qui amène au site de campagne officiel de l’intéressée, mais
surprise, le site habituel est recouvert par une photo animée illustrant d’une manière très peu montrable (et très pornographique) la phrase qui s’affiche en gros en haut de la page :
« Chritine Boutin se retire » (on laissera l’imagination du lecteur tenter de reconstituer la scène).

Revoyons la scène au ralenti (enfin, la scène…)

Le lien cliqué est le suivant (éventuellement masqué par un
raccourcisseur d’url) :

http://www.boutin2012.fr/search?q=%22%3E%3Cstyle%3E%23header{background:url(http://a.yfrog.com/img193/2041/yb5.png)}%23main{background:url(http://i.imgur.com/MdjZA.png)%20no-repeat}%23main{height:900px}%3C/style%3E%3C/form%3E%3C/div%3E%3Cdiv%20style=%22display:none%22%3E`

On décode facilement le début de l’url : search?q= indique que
search est un dossier qui
contient vraisemblablement un fichier index.php ou similaire, qui sera exécuté
en attribuant au paramètre de nom q la valeur qui suit le signe =.
Le paramètre q désigne probablement une requête (query en anglais)
fournie au moteur de recherche du site.

Si on examine le code source de la page générée en effectuant une
requête anodine :

capture d'écran requête sarkozy

code source de la page avec une requête anodine

on retrouve notre requête dans une balise a. C’est à cet emplacement que la requête « malicieuse » se retrouvera lorsqu’on chargera ce même script php à partir de l’url « pirate ».

Dans cette requête,
les signes % suivis de deux chiffres désignent des caractères
spéciaux. En particulier, %22, qui est le premier caractère de
notre requête pirate, désigne le signe >. Si cette requête est
reprise telle quelle et affichée au même endroit que la requête
anodine, voici ce que cela donnera (en remplaçant les caractères
spécieux, pardon spéciaux) :

<a href="/search?page=2&q="><style>#header{background:url(http://a.yfrog.com/img193/2041/yb5.png)}#main{background:url(http://i.imgur.com/MdjZA.png) no-repeat}#main{height:900px}</style></form></div><div style="display:none">" rel="next">2</a>

Ou, si l’on veut le voir comme le navigateur l’interprétera :

<a href="/search?page=2&q=">
  <style>
    #header{background:url(http://a.yfrog.com/img193/2041/yb5.png)}
    #main{background:url(http://i.imgur.com/MdjZA.png) no-repeat}
    #main{height:900px}
  </style>
</form>
</div>
<div style="display:none"> etc.

Ce qui a donc pour effet de faire afficher, par le
script php exécuté sur le serveur, du code html et css envoyé par
l’utilisateur. En l’occurrence, du code css qui fera afficher une
image particulière dans l’en-tête (#header), et une autre dans l’élément
principal (#main), en donnant à ce dernier une hauteur probablement plus
grande pour que la plaisanterie soit plus visible.

On appelle ce genre d’attaque injection de code, ou XSS pour cross-site scripting, même si cette dernière appellation est un peu trompeuse.

Dans notre exemple, il est possible que la page ait été modifiée depuis (en plus d’avoir
corrigé la faille de sécurité, ce qui pouvait se faire sans modifier
le code html produit) puisqu’ici la suite du code ne
correspond pas au code dans lequel il est injecté : c’est une balise
form qui est fermée à la place de la balise a. Mais on comprend
bien l’intérêt du div style "display:none" qui suit : il a pour
effet de rendre invisible le reste du code d’origine du site jusqu’à
la prochaine balise div fermante.

Comment éviter ce type d’injection

Lorsqu’on doit générer du code html dans lequel figurera une chaîne de
caractère fournie par l’utilisateur, cette chaîne doit au préalable
être passée par la fonction php htmlentities,
qui code les caractères spéciaux de façon à ce qu’ils
ne soient pas interprétés comme tels.

Exemple :

$q = $_GET['nom'];
$q = htmlentities($q);
echo "<p>votre requête est : $q.</p>";
Cette entrée a été publiée dans Cours, avec comme mot(s)-clef(s) , , , , , , , , . Vous pouvez la mettre en favoris avec ce permalien.

3 réponses à Mauvaise Saint Valentin pour Christine Boutin

  1. Faute de frappe au début : « raccourciceur » (« raccourcisseur »).

  2. Winter Mute dit :

    htmlspecialchar() est encore vulnérable à une attaque par UTF-7 (exemple: http://blog.kotowicz.net/2010/10/xss-hackme-challenge-solution-part-2.html).
    Ne faudrait il pas plutôt passer par htmlentities() qui n’est plus vulnérable à cette attaque?

  3. Christophe dit :

    Ouh c’est vilain en effet :)
    Bon, je vais pas chipoter, puisque htmlentities existe, autant l’utiliser, c’est vrai. C’est corrigé.
    Mais le coup de l’utf7 suppose qu’on n’ait pas défini le charset dans la page où on l’affiche, ni dans l’appel à htmlspecialchars (ce que je n’ai pas fait et j’ai eu tort).
    Merci pour vos remarques en tout cas.

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>

Merci de répondre à cette question pour prouver que vous n'êtes pas un robot :

Combien font 8 x 6 ?