Alerte de sécurité dompdf : une vulnérabilité RCE découverte dans une bibliothèque PDF PHP populaire
DeveloperSteve Coochin
18 mars 2022
0 minutes de lectureRécemment, des chercheurs de Positive Security ont publié leurs conclusions, révélant une importante vulnérabilité d’exécution de code à distance (RCE) dans dompdf, une bibliothèque populaire de génération de PDF. Dans leur rapport, ils ont décrit comment du code pouvait être chargé dans une application, puis exécuté à distance pendant la génération d’un PDF.
Dompdf est largement utilisé dans l’écosystème PHP, au sein de plus de 59 000 plateformes et projets open source. La page PHP Composer de dompdf à elle seule recense près de 50 millions d’installations depuis sa première publication sur le gestionnaire de paquets PHP en 2014.
Au moment de la rédaction, aucun correctif n’est disponible pour cette vulnérabilité. Une solution pourrait consister à interdire le chargement de polices personnalisées pendant la génération de PDF, voire à restreindre l’accès en écriture au dossier de cache des polices. Restreindre l’accès au répertoire d’installation de Composer est également une bonne option, selon les bibliothèques utilisées et les fonctionnalités nécessaires dans l’application.
Pour les versions de dompdf >= 0.8.6, le paramètre $isRemoteEnabled peut être désactivé afin d’empêcher le chargement de polices personnalisées via les règles CSS font-face. Attention toutefois : cela pourrait entraîner une régression. De plus, dans les versions <0.8.5, ce paramètre n’est pas utilisé ; il est donc impossible de corriger cette vulnérabilité en le désactivant avec $isRemoteEnabled.
Dans cet article, nous allons voir comment fonctionne cette vulnérabilité. Pour comprendre en profondeur le code et les vulnérabilités, rien de tel que de mettre les mains dans le cambouis. Nous allons donc explorer cette vulnérabilité à l’aide d’une démonstration fonctionnelle basée sur l’application php-goof, disponible dans un dépôt GitHub de Snyk.
Bibliothèques PDF
La génération de PDF dans les applications est l’une des tâches que j’aime le moins en tant que développeur. C’est un processus assez long et répétitif : modifier le code, générer le PDF, modifier le code, générer le PDF, et ainsi de suite, jusqu’à obtenir la bonne mise en page et le bon formatage.
Pourtant, pouvoir convertir du HTML en PDF est extrêmement utile, surtout quand on pense à la fréquence à laquelle les applications doivent générer des PDF. Vous en utilisez presque tous les jours, sur des sites de commerce en ligne ou des sites qui traitent des données transactionnelles liées aux utilisateurs et doivent générer des reçus que ces derniers peuvent enregistrer ou imprimer.
Pour la plupart d’entre nous, utiliser une bibliothèque pour ce type de fonctionnalité dans le développement d’applications permet d’accélérer le processus. Des bibliothèques comme dompdf nous évitent, en tant que développeurs, de réimplémenter des fonctionnalités banales et nous permettent de passer à des sujets plus complexes.
Exploration pratique de la vulnérabilité dompdf
L’examen des conclusions originales sur la sécurité permet de mieux comprendre ce qui se passe au sein de la bibliothèque et comment elle a pu être exploitée.
La bibliothèque dompdf prend essentiellement du HTML standard et le convertit en un PDF mis en forme.
Elle propose une fonctionnalité simple et facile à utiliser, qui évite une tâche autrement très répétitive pour une fonction courante. Son principal avantage est de formater le PDF de sortie à l’aide de simples balises HTML.
Le HTML peut également inclure des styles. Ceux-ci peuvent être intégrés à la balise <html> ou définis dans une feuille de style. Une feuille de style permet notamment de charger une font-family et d’ajouter un lien vers un fichier de police.
C’est là que les choses deviennent intéressantes.
La bibliothèque dompdf ne se contente pas de charger une feuille de style externe via HTML : elle enregistre aussi le fichier de police dans un cache local, l’ajoute à un répertoire de polices sur le serveur et référence la font-family ainsi que son emplacement dans le framework dompdf.
L’étape suivante de l’exploitation consiste à insérer du code PHP dans un fichier de police qui passe la validation de dompdf et peut être stocké sur le serveur, tout en permettant à ce code PHP de s’exécuter depuis le fichier de police. Cela peut sembler compliqué, mais les chercheurs ont découvert que la validation de la bibliothèque vérifie uniquement le type de fichier, pas son contenu.
Dans l’application de démonstration php-goof, vous pouvez voir comment cela fonctionne en examinant le fichier de police personnalisé gotcha-normal.otf. Il s’agit pour l’essentiel d’un fichier de police classique, avec des jeux de caractères tout à fait ordinaires. Mais dans les métadonnées du fichier se trouve du code PHP destiné à être exécuté sur le serveur de l’application cible — <php? phpinfo(); ?> — dans le champ des droits d’auteur des métadonnées… Oui, c’est aussi simple que ça !

Ouvrez ensuite le fichier de police dans un éditeur de code et copiez son contenu dans un fichier .php, ou renommez simplement le fichier. Cette étape est importante : dompdf valide les en-têtes de police du fichier, puis l’enregistre dans le cache sous la forme d’un fichier .php exécutable.
Ensuite, référencez ce nouveau fichier de police factice dans la feuille de style CSS en tant que font-family. Dans php-goof, nous le faisons directement depuis le dépôt php-goof.
Remarque : Il est important d’utiliser ici le même nom que celui du fichier de police pour la valeur de font-family, sans quoi cela ne fonctionnera pas dans dompdf.
Il ne reste plus qu’à injecter la feuille de style dans le HTML utilisé pour générer le PDF. dompdf enregistrera alors la police sur le serveur, où elle pourra être exécutée à distance. Cette étape peut s’avérer délicate, car le nom du fichier est haché et le répertoire des polices peut se trouver ailleurs.
Dans php-goof, le framework dompdf facilite cette étape en permettant de trouver l’emplacement et le nom du fichier de police. Il utilise $dompdf->getFontMetrics()->getFont(“gotcha”, “normal”) pour déterminer quand la police est détectée dans le cache de polices de dompdf.
Lorsque le fichier de police gotcha est disponible dans le framework, celui-ci renvoie son chemin sous forme de lien dans le PDF généré. Voici quelques captures d’écran de la vulnérabilité telle qu’elle apparaît dans l’application goof :



Restez en sécurité
Un grand merci à l’équipe de Positive Security, qui a non seulement communiqué ouvertement sur ses découvertes, mais a également détaillé les démarches entreprises pour les signaler aux responsables de dompdf.
Pensez toujours à analyser le code de vos applications pour repérer ce type de problème, qui peut survenir à votre insu. Snyk Code peut vous aider à détecter les vulnérabilités dans les frameworks et les fonctions, et à effectuer les vérifications nécessaires pour protéger les utilisateurs finaux et leurs données.
Sécurisez vos dépendances open source
Les outils Snyk, conçus pour les développeurs, génèrent en un clic des pull requests correctives pour vos dépendances open source vulnérables et leurs dépendances transitives.



