Analyse des Métriques XSS : comprendre l’Impact des injections de code côté client

Lors des tests d’intrusion, l’injection de code côté client est généralement plus aisée à découvrir qu’une injection côté serveur. Le nombre de paramètres dynamiques transitant du back au front, la difficulté d’échapper correctement à l’entrée et à la sortie et la multitude d’encodage liés à l’affichage peuvent être des vrais casse-têtes pour qui souhaite faire la chasse à la XSS. Le JavaScript malveillant semble ainsi avoir de beaux jours devant lui. Cependant, il n’est pas rare qu’à l’issu de l’audit, la criticité d’une telle injection découle directement de la configuration des cookies présents sur l’application. En effet, l’absence de l’attribut HttpOnly majore irrémédiablement les risques liés à ce type d’attaque. Néanmoins, cela signifie-t-il que la présence de cet attribut doive absolument amenuiser la criticité d’une injection ?

Il est courant d’attribuer une criticité « Majeure » à une injection de code JavaScript dans un environnement où les cookies ne disposeraient pas de l’attribut HttpOnly. L’effet miroir de cette constatation n’est pas forcément une vérité. La criticité d’une injection dans un environnement où les cookies seraient correctement configurés ne doit pas être automatiquement en deçà de « Majeure ». En réalité, le type d’injection, sa persistance et la facilité d’écriture du code jouent un rôle au moins équivalent à la configuration des cookies de sessions.

Réfléchie ou stockée ?

Lorsqu’on parle de type d’injection de code JavaScript, l’un des premiers éléments déterminant sa criticité est sa persistance dans l’application. Est-elle réfléchie ou stockée ? Pour rappel, une injection de type réfléchie voit sa charge utile généralement passée au travers d’un paramètre GET. Cette dernière est exécutée lors de l’ouverture du lien par la victime. Il est dit ici « généralement », car associée à une vulnérabilité de type CSRF, la charge utile peut également être présente au sein d’un paramètre. La difficulté première pour un attaquant dans ces configurations est de dissimuler le lien malveillant et le soumettre à sa/ses victimes. Encore une fois, le contexte définira la criticité. Si l’application concernée est un forum, permettant, sans compte utilisateur d’insérer un lien sur une page publique, la vulnérabilité y sera bien plus impactante qu’au sein d’un backoffice, nécessitant un compte utilisateur et la dissimulation et l’envoi du lien via un formulaire de contact ou par mail.

Dans le cadre d’une XSS stockée, où le code malveillant est enregistré en base de données et exécuté au sein du DOM à chaque appel de la page, les mêmes problématiques doivent-être prises en compte. L’exécution d’une charge sur la homepage d’un site e-commerce, impactant ainsi utilisateur et administrateur n’aura forcément pas la même criticité qu’une injection au sein d’une vue du backoffice d’un CMS, accessible uniquement par un utilisateur ayant un compte au moins « éditeur » (dans le cadre d’un CMS type WordPress).

Dans le même ordre, il conviendra de considérer intelligemment le plus risqué pour une application (par extension, une entreprise) entre un impact sur l’ensemble des utilisateurs d’un e-commerce, via l’ajout d’un lien corrompu (xss réfléchie avec des cookies de sessions protégés) sur la page d’accueil d’un forum ou l’injection d’un code stocké dans une vue d’un module peu utilisé. La simple équation « xss stockée + absence de HttpOnly = Majeure & xss stockée + HttpOnly défine = important ou mineure » trouve ici ses limites.  

Ainsi, de part ces considérations, il convient de reconnaître que la nature des cookies de sessions n’est qu’un élément en plus à prendre en compte et non l’élément déterminant pour calculer la criticité de la vulnérabilité.

XSS Basique

Jusqu’où peut-on aller avec une XSS

Ce biais considérant la criticité d’une injection de code côté client uniquement sur la capacité à l’attaquant à récupérer des identifiants ou voler le cookie de session masque les capacités effrayantes de JavaScript. Le langage créé en dix jours seulement en 1995 avait pour simple but de permettre la modification du DOM via le navigateur. Il semblait ainsi être un langage gadget pour dynamiser les sites web. Aujourd’hui il se présente comme un langage puissant aux capacités souvent insoupçonnées (plus d’infos).

Ainsi, l’exploitation malveillante du langage ne se cantonne pas qu’au vol du cookie de session :

  • Enregistreur de touches
  • Géolocalisation de la victime
  • Instantané de la page accrochée/visitée
  • Code source de la page accrochée/visitée (avec les éventuels données techniques/confidentielles au sein de la page, il devient alors possible de les exfiltrer)
  • Exfiltration des données du champ de saisie
  • Afficher la boîte d’alerte
  • Redirection abusive
  • Interruption de service, voir exploitation des navigateurs vulnérables

Plusieurs Frameworks proposent des environnements de tests et des charges utiles pour exploiter au mieux une XSS.Il est possible de citer :

BeEF
Hook.js de BeEF

Des scripts injectables disponibles sur ces environnements permettent de rapidement se rendre compte qu’à défaut de cookies non sécurisé, une injection efficace peut mettre à mal l’ensemble des utilisateurs d’une application.

Construction dynamique de scripts

Une situation complexe, mais dangereuse, réside dans la possibilité d’injecter directement au sein du script JavaScript et non plus dans le DOM de la page Web. Ce cas arrive lorsque le code front est construit dynamiquement avec des valeurs enregistrées en base de données ou passées via l’URL.

Par exemple, considérons un point d’accès à la page d’accueil construit ainsi : une multitude de paramètres sont passés en GET, ces derniers correspondent la plupart du temps à des valeurs de configuration propre à la construction dynamique de la page :

  • Langue ;
  • URL de provenance ;
  • Timestamp

Et parfois, chemin d’accès à des scripts locaux. Forcément la première idée d’un auditeur sera de modifier ces paramètres afin de forcer le serveur à inclure des scripts malveillants, ou provoquer une redirection abusive. Avec les nouveaux Framework Web, les éléments du front seront la plupart du temps correctement échappé. Les entêtes HTTP empêcheront l’injection de ressources extérieures et le typage des éléments protégera l’injection au sein des valeurs numériques comme le Timestamp.

Param appellant un script local

Néanmoins, il peut arriver que le script « js » prenne lui-même des paramètres. La construction de tels scripts peut se faire avec un routing spécifique en PHP, avec Ext Js, ou n’importe quelle technologie backend, basée sur JavaScript ou non.

Script dynamique

Ainsi, le paramètre « param » du script « my-custom-script.js » au sein des paramètres fourni à la page d’accueil sera inscrit directement dans le code JavaScript. Une configuration telle que celle-ci est autrement plus dangereuse qu’une injection dans le DOM. En effet, le code est totalement légitime, le script est hébergé sur le serveur cible, et l’injection ne souffre d’aucune contrainte propre aux injections dans le DOM. Difficultés d’échappements des guillemets, écriture dans des attributs HTML, restrictions des caractères etc…

De même, il sera difficile pour l’utilisateur de détecter une modification malveillante de l’URL dans ces conditions.

Spectre et Spook.js

En 2017 les Common Vulnerabilities and Exposures CVE-2017-5753 et CVE-2017-5715 furent émises. Ces dernières traitent de vulnérabilités impactant les micro-processeurs. Sans rentrer dans les détails extrêmement complexes de ce type de vulnérabilités concernant des couches très basses, il en résulte la possibilité d’extraire des informations sensibles en forçant un programme à accéder à certains espaces mémoires. Le danger de cette vulnérabilité réside dans le fait qu’elle concerne un ensemble de programme vulnérables. En effet, basée sur défaut d’une implémentation visant à rendre plus performant les programmes, de nombreux logiciels se voient ainsi potentiellement affectés.

Incluant ainsi les navigateurs Web. Un bout de code JavaScript exécuté par un navigateur a permis aux chercheurs d’extraire de la donnée provenant de la mémoire vive du même navigateur. Les possibilités d’attaques sur le navigateur peuvent dès lors être affranchies de l’isolation du « bac à sable ». En effet, il n’est normalement pas possible pour un code JavaScript exécuté au sein d’un onglet d’interagir avec un autre onglet. Cela est aussi inconcevable qu’obtenir la valeur d’un cookie défini en HttpOnly par un code côté client. Pourtant, en interagissant sur une couche bien plus basse, l’exploitation s’affranchit de ces protections.

Spook.js fût la première attaque JavaScript exploitant la faille Spectre.

Spectre n’est pas la seule vulnérabilité des navigateurs exploitables. De nombreux autres vecteurs d’attaques côté client existent :

Il est aisé d’imaginer qu’une injection de code JavaScript peut servir de vecteurs à l’exploitation de ces vulnérabilités. Ainsi, il convient toujours lors d’un audit et de la rédaction des livrables liés, de prendre en compte à la fois le contexte métier de la vulnérabilité découverte, l’exploitabilité, l’environnement applicatif mais aussi celui des utilisateurs. La méthodologie propre à Digitemis sera donc une étude au cas par cas de chaque découverte, afin d’en conclure la juste criticité et proposer un plan d’action cohérent et réalisable, au lieu de copier/coller une métrique qui ne devrait servir que de base de réflexion.

Je partage

Derniers articles

Illustration de sécurité WordPress avec logo central et éléments numériques de sécurité

Renforcer la sécurité WordPress, du développement des plugins à la configuration serveur

Il y a peu, dans le cadre de recherches sur des plugins WordPress, notre pentester Vincent Fourcade a découvert une injection de code, côté client, dans un module du célèbre CMS. Celle-ci fut vérifiée et validée par les équipes de WPScan. Aujourd’hui, une CVE lui a été attribuée. L’occasion de revenir aujourd’hui sur la sécurité, au sens large, dans le CMS WordPress, que ce soit au niveau de la couche applicative, de la configuration du serveur ou du bureau. C’est parti !

Lire l'article

Analyse des Métriques XSS : comprendre l’Impact des injections de code côté client

Lors des tests d’intrusion, l’injection de code côté client est généralement plus aisée à découvrir qu’une injection côté serveur. Le nombre de paramètres dynamiques transitant du back au front, la difficulté d’échapper correctement à l’entrée et à la sortie et la multitude d’encodage liés à l’affichage peuvent être des vrais casse-têtes pour qui souhaite faire la chasse à la XSS. Le JavaScript malveillant semble ainsi avoir de beaux jours devant lui. Cependant, il n’est pas rare qu’à l’issu de l’audit, la criticité d’une telle injection découle directement de la configuration des cookies présents sur l’application. En effet, l’absence de l’attribut HttpOnly majore irrémédiablement les risques liés à ce type d’attaque. Néanmoins, cela signifie-t-il que la présence de cet attribut doive absolument amenuiser la criticité d’une injection ?

Lire l'article