Dompurify 3.0.9 bypass - Node type confusion
03 mai 2024
Cet article se base sur les recherches de slonser_ (https://blog.slonser.info/posts/dompurify-node-type-confusion/).
Confusion HTML et XML
Au sein d'un document HTML, rien n'empêche un noeud XML d'avoir un noeud HTML en tant que parent. C'est par exemple le cas d'un SVG intégré au sein d'une page HTML :
L'image vectorielle s'affichant sans erreur au sein de la page.
L'interface ProcessingInstruction
L'interface ProcessingInstruction
représente un noeud qui intègre une instruction de traitement spécifique à une application XML. Elle possède le format suivant :
Par exemple :
Lorsque Dompurify assainit une chaîne de caractères de type XML, et que l'option adéquate est :
Les instructions de traitement (processing instructions) ne semblent pas être assainies par la bibliothèque. L'évenement onerror
ainsi que l'appel à la méthode alert()
ne sont pas supprimés :
Malheureusement, le code est commenté par le navigateur, empêchant ainsi son exécution :
Toutefois, le navigateur commente le code jusqu'à rencontrer le prochain caractère >
, il est donc possible d'exploiter ce comportemement de la façon suivante :
L'affichage de la page HTML provoque dorénavant l'exécution de la méthode alert()
:
Par défaut, Dompurify traite la chaîne de caractères comme du HTML, et non du XML, excepté si l'option {PARSER_MEDIA_TYPE: 'application/xhtml+xml'}
est spécifée. De plus, il est assez rare d'identifier une cible imposant ce type de média et intégrant ensuite la donnée assainie au sein d'un document HTML.
Assainissement d'un noeud
La manière la plus fréquente d'utiliser la méthode sanitize()
de Dompurify est de lui passer une chaîne de caractères en tant que paramètre :
Mais bien que moins utilisé, il est également possible de lui passer directement un noeud :
Toutefois, lorsque le noeud est un noeud XML, le même comportement que précédent est possible lors de l'utilisation des instructions de traitement.
L'exemple suivant illustre une fonctionnalité permettant à l'utilisateur de fournir une URL afin de charger un fichier SVG, qui sera assaini par Dompurify avant d'être intégré au document HTML :
Lorsque l'utilisateur renseigne une URL vers un fichier SVG, tel que :
Dompurify échoue à assainir le noeud et permet l'exécution du code Javascript :
Correction
Le correctif, apporté par la version 3.0.10 de Dompurify, consiste à l'ajout du masque SHOW_PROCESSING_INSTRUCTION
lors du traitement des noeuds XML. Cela permet de traiter les noeuds de type ProcessingInstruction
:
Cette constante est définit par l'API DOM et utilisée par la méthode createNodeIterator()
(https://developer.mozilla.org/en-US/docs/Web/API/Document/createNodeIterator).
Labs
Afin de tester et d'exploiter ce contournement, une image Docker est disponible ici.
Dernière mise à jour