19 Sep. 19 Cybersécurité

Vulnérabilité XSS, ou injection de code indirecte à distance ?

Vulnérabilité majeure dans les tests d'intrusion d'applications web

injection code XSS

Une des vulnérabilités les plus couramment identifiées lors des audits en test d’intrusion d’application web est l’injection de code indirecte à distance ou Cross Site Scripting ou XSS.

La vulnérabilité XSS est aussi présente dans le top 10 des risques les plus critiques pour la sécurité des applications Web 2017 de l‘Open Web Application Security Project (OWASP) .

Néanmoins, malgré le fait que cette vulnérabilité soit extrêmement courante, elle reste relativement méconnue (en comparaison par exemple de l’injection de code SQL).

type de vulnérabilités reportées par la plateforme bug bounty hackerone.com : les XSS sont en tête
Figure 1 - Répartition en pourcentage du type de vulnérabilités reportées sur la plateforme de bug bounty hackerone.com en 2018. Les XSS sont largement en tête !

Définition d'une XSS, quels sont les risques ?

Commençons tout d’abord par définir ce qu’est une XSS. Selon Wikipédia :

Le cross-site scripting (abrégé XSS) est un type de faille de sécurité des sites web permettant d’injecter du contenu dans une page, provoquant ainsi des actions sur les navigateurs web visitant la page. Les possibilités des XSS sont très larges puisque l’attaquant peut utiliser tous les langages pris en charge par le navigateur (JavaScript, Java, Flash…) et de nouvelles possibilités sont régulièrement découvertes notamment avec l’arrivée de nouvelles technologies comme HTML5. Il est par exemple possible de rediriger vers un autre site pour de l’hameçonnage ou encore de voler la session en récupérant les cookies.

Les XSS sont donc des injections de code qui vont avoir un impact sur le navigateur de l’utilisateur lors de leur exploitation. L’une des exploitations des XSS les plus utiles pour un pirate est l’injection de code JavaScript dans la page HTML afin de voler le cookie de session de la victime, permettant donc de se connecter à l’application web en se faisant passer pour la victime. Cependant il est possible de faire autre chose en exploitant une XSS comme modifier le contenu d’une page HTML ou bien prendre le contrôle du navigateur de la victime.

Les différents types de XSS

Il existe trois types de XSS différentes, ayant chacune leur spécificité propre et criticité.

XSS réfléchie ou Reflected XSS

Les reflected XSS sont les XSS où l’injection de code ce situe généralement dans les paramètres d’une requête HTTP. L’attaquant va donc devoir forger un lien URL spécifique puis faire en sorte que la victime utilise le lien afin que le code injecté s’exécute dans son navigateur.

Exemple : http://example.com/index.php?user=<script>alert(document.cookie)</script>

Lorsque la victime cliquera sur le lien, le code JavaScript s’exécutera sur son navigateur et affichera une boîte de dialogue contenant ses cookies.

le reflected XSS : l'application injecte dans la page la valeur du paramètre 'name', contrôlée par l’utilisateur via l’URL
Figure 2 – Ici, l'application injecte dans la page la valeur du paramètre 'name', contrôlée par l’utilisateur via l’URL
reflected XSS - Si on injecte du code JavaScript dans le paramètre ‘name’, celui-ci est exécuté dans notre navigateur.
Figure 3 – Si on injecte du code JavaScript dans le paramètre ‘name’, celui-ci est exécuté dans notre navigateur

Bien entendu, dans le cas d’une véritable attaque, une fois que la victime aura cliqué sur le lien, ses cookies seront automatiquement envoyés sur le serveur du pirate sans que la victime ne s’en rende compte.

XSS stockée ou Stored XSS

Contrairement à la reflected XSS, la stored XSS ne nécessite pas une interaction forte de la part de la victime comme cliquer sur un lien. En effet, ici l’injection de code est directement stockée en base de données. Ainsi, lorsque la victime va charger la page vulnérable contenant l’injection de code, celle-ci va automatiquement s’exécuter sans aucune autre intervention de sa part.

Par exemple, prenons le cas d’un site de blog disposant d’un espace de commentaire sous chacun des articles. Si l’espace de commentaires permet d’exploiter une vulnérabilité de type stored XSS, l’attaquant va pouvoir injecter du code JavaScript dans un commentaire qu’il aura rédigé. Ce code JavaScript qui s’exécutera pour chacun des utilisateurs accédant à l’article. En effet, le commentaire malveillant étant stocké en base de données, aucune interaction avec la victime n’est nécessaire et le pirate aura juste à attendre que de nombreux cookies de session arrivent jusqu’à lui.

Figure 4 – Voici un site disposant d’un espace de commentaire
Figure 4 – Voici un site disposant d’un espace de commentaire
Stored XSS - Chaque commentaire est stocké en base de données pour ensuite être affiché à chaque chargement de la page
Figure 5 – Chaque commentaire est stocké en base de données pour ensuite être affiché à chaque chargement de la page
Stored XSS - le paramètre ‘message’ est vulnérable à une Stored-XSS
Figure 6 – Cependant, le paramètre ‘message’ est vulnérable à une Stored-XSS
Stored XSS - A chaque fois qu’un utilisateur chargera la page contenant le commentaire malveillant, le code JavaScript s’exécutera sur son navigateur
Figure 7 – A chaque fois qu’un utilisateur chargera la page contenant le commentaire malveillant, le code JavaScript s’exécutera sur son navigateur

La criticité des stored XSS est bien plus haute que celle des refected XSS, justement à cause de cette absence d’interaction de la part de la victime.

XSS basée sur le DOM ou DOM-based XSS

Le Document Object Model ou DOM est une structure utilisée pour représenter un document dans un navigateur.

Une vulnérabilité DOM-based XSS peut survenir lorsqu’un contenu actif, tel qu’une fonction JavaScript, est modifié par une requête spécialement conçue, telle qu’un élément DOM pouvant être contrôlé par un attaquant.

Comparée aux autres types de XSS, reflected XSS et stored XSS, dans lesquelles un paramètre est transmis par le serveur, renvoyé à l’utilisateur et exécuté dans le contexte du navigateur, les DOM-based XSS s’exécutent en utilisant les éléments du DOM en combinaison de l’injection de code faite par l’attaquant.

Par exemple, si une page HTML contient ce morceau de code vulnérable :

<script>

document.write(« Site is at:  » + document.location.href + « . »);

</script>

un attaquant peut ajouter le code JavaScript :

#<script>alert(document.cookie)</script>

à l’URL pointant sur cette page vulnérable.

Un pop-up s’affichera alors sur le navigateur de la victime qui aura négligemment cliqué sur ce lien URL.

DOM-based XSS - application qui permet de choisir le langage d’affichage de la page
Figure 8 – Cette application permet de choisir le langage d’affichage de la page.
DOM-based XSS - paramètre, contrôlable via l'URL, qui permet de changer la valeur d'un élément du DOM
Figure 9 – Ce paramètre, contrôlable via l'URL, permet de changer la valeur d'un élément du DOM
DOM-based XSS - injection d'un code JavaScript malveillant
Figure 10 – Il ne reste plus qu’à injecter notre code JavaScript malveillant

En fonction du contexte, une DOM-based XSS peut nécessiter ou non une interaction de la part de la victime. Cela va dépendre des éléments du DOM utilisés pour exploiter la vulnérabilité. La criticité de la vulnérabilité est donc plus ou moins haute.

Comment se protéger contre les XSS ( Cross Site Scripting)

Les XSS sont de la famille des « Injection de code ». Comme toutes les vulnérabilités de cette famille, celles-ci sont dues à une absence de vérification des entrées utilisateurs.

Chaque entrée utilisateur doit systématiquement être vérifiée et le cas échéant échappée avant d’être insérée dans une page HTML. Cela vaut pour les paramètres venant de formulaires mais aussi pour les paramètres contenus dans les potentielles URL de l’application web. De nombreuses bibliothèques sont utilisables pour échapper les entrées utilisateurs en fonction de la technologie utilisée par l’application web.

En complément à cela, il peut être intéressant de mettre en place un pare-feu applicatif ou WAF. Le rôle de ce type de pare-feu est de détecter les tentatives d’exploitation de XSS sur l’application web et de les bloquer avant que l’injection de code ne soit exécutée sur le navigateur de la victime.

De plus, pour éviter que l’exploitation d’une XSS permette de voler le cookie des utilisateurs, il est préconisé de mettre le drapeau « HTTPOnly » sur les cookies de session. Cela empêchera l’accès aux cookies via le langage JavaScript.

Enfin, il est possible de paramétrer le serveur web de l’application pour retourner certains entêtes de protection contre les XSS :

                – X-XSS-Protection : active le filtre anti-XSS de certains navigateurs récents.

                – Content Security Policy ou CSP : le CSP défini les sources (images, fichiers CSS ou JavaScript) d’une application web autorisées à être chargées sur le navigateur des utilisateurs. Un CSP bien configuré empêchera un potentiel attaquant de charger des fichiers JavaScript externes par le navigateur des utilisateurs.

Les injections de code indirecte à distance n’ont (presque) plus de secret pour vous !

Cet article vous a fourni les clefs vous permettant de comprendre le concept des XSS et les façons de s’en prémunir.

Pour plus d’informations, n’hésitez pas à contacter les experts Certilience !