Les injections CSS - Attribute Selector
06 Novembre 2022 (mis à jour le 19 Aout 2024)
Les injections CSS ne sont pas les vulnérabilités les plus connues, mais permettent tout de même certaines exploitations. Pour illustrer cela, nous commençons par la récupération de valeurs d'attributs HTML grâce aux sélecteurs d'attributs CSS.
Utilisation des Feuilles de style en cascade (CSS)
Le CSS est un langage informatique qui décrit la présentation des documents HTML et XML. Trois méthodes permettent d'appliquer un style aux documents.
La feuille de style externe
La méthode la plus couramment utilisée est de lier directement la feuille de style :
à la page HTML grâce à l'élément <link>
:
La feuille de style interne
La seconde méthode est d'utiliser une feuille de style interne directement dans le document HTML grâce à l'élément <style></style>
:
Bien que l'ajout de la balise <style></style>
se fait communément au sein de la balise <head></head>
, rien n'empêche le développeur de l'ajouter au sein de la balise <body></body>
:
Le style en ligne
Et finalement, la méthode sans doute la moins usitée est le style en ligne (inline style) :
Exploitation d'une injection XSS via un élément CSS
Dans les cas les plus simples, une injection au sein d'un code CSS peut mener à une vulnérabilité de type Cross-Site Scripting (XSS) :
Bien que l'injection se situe au sein d'une balise <style></style>
, aucune particularité liée au CSS n'intervient dans l'exploitation de cette vulnérabilité. Il suffit de procéder comme pour une XSS classique, c'est-à-dire ici de fermer la balise de style, puis de charger le code JavaScript désiré :
Suite à cette mésaventure, le développeur souhaite toujours laisser la possibilité à ses utilisateurs de personnaliser le style du site et notamment la couleur du titre de la page grâce au paramètre color
, mais tout en protégeant son site. Etant maintenant sensibilisé aux vulnérabilités Web, la donnée non fiable est assainie par la méthode htmlspecialchars()
transformant ainsi les caractères <
, >
, "
et '
en entités HTML.
De ce fait, l'injection précédente n'est maintenant plus possible :
Dans ce cas, l'application est-elle maintenant correctement protégée ? Qu'elles sont les exploitations toujours possibles pour un tel code ?
Exploitation d'une injection CSS
Récupération de la valeur d'un attribut d'un élément HTML via les sélecteurs d'attribut CSS
En CSS, les sélecteurs d'attributs permettent d'effectuer un traitement sur un élément, selon un de ses attributs ou de leur valeur. Il est possible d'utiliser cette mécanique afin de récupérer de l'information grâce à une injection CSS.
Le code vulnérable exploité possède un élément HTML <input>
de type password
et ayant comme valeur le mot de passe de la victime :
L'idée de l'exploitation va être d'utiliser les sélecteurs CSS afin de récupérer le mot de passe de la victime caractère par caractère. Voici un exemple de sélecteur d'attribut :
Le style va s'appliquer pour les éléments HTML <input>
, dont l'attribut name
est égal à "password" et dont la value
commence par (le caractère ^
indique le début de chaîne) "valeur". Si un tel élément est trouvé, alors le navigateur appliquera le style background-image
en récupérant l'image disponible à l'URL spécifiée.
L'attaquant va ainsi modifier le sélecteur comme ceci :
Et amener sa victime à suivre le lien malicieux exploitant l'injection :
Lorsque le navigateur de la victime chargera la page, la condition sera remplie et une requête sera effectuée vers le serveur de l'attaquant :
L'attaquant continuera son attaque en itérant sur les prochains caractères :
Récupération de la valeur d'un attribut d'un élément HTML de type hidden via les sélecteurs d'attribut CSS
Malheureusement, la technique précédente ne fonctionne pas sur les champs <input>
de type hidden
. Cela pourrait pourtant être utile dans le cas ou l'application vulnérable utilise des champs cachés pour transmettre des jetons anti-CSRF par exemple :
Cela est en fait possible en utilisant les combinateurs ~
et *
à la suite du sélecteur CSS :
Le combinateur ~
(general sibling combinator) sélectionne les frères d'un élément, même dans le cas où ils ne sont pas adjacents, mais doivent avoir le même parent. Il est possible également d'utiliser le combinateur +
(adjacent sibling combinator) mais son utilisation est alors plus restreinte.
Le sélecteur*
(universal selector) correspond à un élément de n'importe quel type.
Le lien malicieux devenant alors :
Et la requête effectuée par le navigateur de la victime sera :
L'attaquant devra continuer son attaque pour récupérer ainsi les caractères restants :
L'inconvénient de ces techniques est qu'elles sont limitées à la récupération d'une information présente au sein d'un attribut. Impossible donc ici de récupérer le contenu d'un élément <span></span>
, d'un <script></script>
ou d'un paragraphe <p></p>
par exemple.
Il existe toutefois d'autres techniques permettant cela et qui seront vues dans les prochaines parties de cet article.
Récupération de la valeur d'un attribut d'un élément HTML de type hidden via la pseudo-class CSS has()
has()
Une alternative pouvant répondre à certaines limites des combinateurs CSS est d'utiliser le sélecteur CSS has()
de la façon suivante :
Automatisation de l'attaque
Un script d'automatisation exploitant l'injection CSS afin de récupérer une valeur d'un attribut existe déjà ici : https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e. Son utilisation nécessite que la victime accède à la page malicieuse et que l'application vulnérable ciblée soit iframable (entêtes X-Frame-Options et frame-ancestors). Toutefois, ce PoC ne possède pas la partie back-end. Il faudra donc le développer, mais il reste toutefois assez simple. De plus, étant donné qu'une seule requête est effectuée par position de caractère, il est possible que l'iframing résulte en une erreur HTTP 414 URI Too Long
et que l'attaque échoue.
Ci-dessous, plusieurs PoC tentant de résoudre ces problèmes.
PoC - Récupération de la valeur d'un attribut d'un élément HTML via les sélecteurs d'attribut CSS
Un PoC est disponible ici.
PoC - Récupération de la valeur d'un attribut d'un élément HTML de type hidden via la pseudo-class CSS has()
has()
Un PoC est disponible ici.
PoC - Récupération de la valeur d'un attribut d'un élément HTML via les Popups
Il existe une autre technique utilisant les popups et qui ne nécessite pas l'iframing du site vulnérable. Malheureusement, il faudra soit un clic en plus de la part de la victime afin de lancer l'attaque ou alors qu'il autorise l'ouverture des popups au sein de son navigateur. De plus, cette attaque est très bruyante puisque la victime voit directement les fenêtres s'ouvrir et se rafraichir.
Un PoC est disponible ici.
Références
Dernière mise à jour