Cela commence comme un ticket de performance. Une fonctionnalité de génération de PDF à partir d’un gabarit met jusqu’à cinq minutes et échoue de temps en temps. Cela finit par l’exécution d’une commande système sur l’infrastructure du client. Présentée en quelques minutes lors de la session de rumps de BarbHack 2026, cette enquête vaut surtout pour le chemin parcouru entre les deux.
Quatorzième volet de notre couverture de BarbHack. Si vous exploitez une chaîne de génération de documents, cet article est pour vous.
Des conditions d’audit tout à fait ordinaires
Il faut insister sur le décor, parce qu’il est représentatif et qu’il explique la difficulté. L’équipe ne disposait d’aucun gabarit, d’aucune documentation, et le client lui-même ne savait pas dire quelle technologie produisait ses PDF. L’environnement était contraint au point d’imposer de travailler depuis une machine Windows précise.
Ce n’est pas un laboratoire, c’est une mission réelle. Et le premier constat est déjà un résultat d’audit : personne, côté client, ne pouvait répondre à la question « qu’est-ce qui s’exécute quand un utilisateur clique sur Générer le PDF ? ».
L’indice : un mot que personne ne reconnaît
Après avoir débloqué un problème de droits d’accès, l’équipe récupère enfin un gabarit. Il contient une chaîne de caractères inconnue, manifestement un mot-clé technique. Les moteurs de recherche ne renvoient rien. Les modèles de langage interrogés ne renvoient rien non plus.
Cette absence de résultat est en soi une information. Un composant qui tourne en production chez un client et dont le nom ne produit aucune trace exploitable est une dépendance fantôme : personne ne la suit, personne ne la met à jour, personne ne reçoit ses avis de sécurité.
La piste finit par venir des chemins d’erreur. Les messages d’échec exposaient l’arborescence interne du composant, ce qui a permis de remonter jusqu’au projet open source correspondant. Un projet modeste au regard des géants du secteur, mais suffisamment adopté pour que le problème ne soit pas anecdotique.
La révélation : ce n’était pas un moteur de gabarits
La documentation du projet livre alors sa véritable nature : ce composant exécute du code JavaScript, dans une sandbox, avec plusieurs moteurs d’isolation possibles selon la configuration.
Tout s’éclaire d’un coup, y compris le ticket de départ. Les cinq minutes de génération et les erreurs intermittentes n’étaient pas un défaut de configuration : c’était le coût normal de l’interprétation de code. Le symptôme de performance et le problème de sécurité avaient la même cause.
De là, l’hypothèse s’impose : si le gabarit est du code, alors les données injectées dans le gabarit peuvent l’être aussi. L’équipe a construit une charge utile passant par le mécanisme d’injection de données prévu par le composant, et a obtenu l’exécution d’une commande système sur l’environnement cloud hébergeant la fonctionnalité. Évasion de sandbox, puis exécution de commande à distance.
Nous ne nommons pas le composant et ne publions pas le vecteur. Les raisons sont détaillées en fin d’article.
Ce n’est pas un cas isolé, et c’est ce qui devrait inquiéter
Le scénario appartient à une famille bien identifiée, l’injection de gabarit côté serveur, décrite de longue date et toujours d’actualité. La logique est invariable : un moteur conçu pour évaluer des expressions reçoit une expression choisie par l’attaquant, et évalue consciencieusement ce qu’on lui donne. Voir à ce sujet le document de référence de PortSwigger sur le sujet.
Quant à l’idée qu’une sandbox JavaScript constitue une barrière, l’historique public est accablant :
- vm2, longtemps la bibliothèque d’isolation de référence dans l’écosystème Node, a accumulé les évasions critiques jusqu’à être abandonnée par son auteur.
- SandboxJS a connu en 2026 une série d’avis de sécurité pour évasion de sandbox, dont un classé au score maximal de 10. Pollution de prototype, fuite de constructeurs, contournement par des chemins auxquels personne n’avait pensé : les variations sont nombreuses, le résultat est toujours le même.
- Côté gabarits, le même enchaînement a déjà été publié ailleurs, notamment sur un outil de rédaction de rapports où un modèle malveillant permettait de s’échapper de la sandbox JavaScript et d’exécuter du code sur le serveur.
La conclusion est désagréable mais nette : « sandbox » décrit une intention, pas une garantie. Ces bibliothèques isolent correctement du code maladroit. Elles ne tiennent pas durablement face à du code hostile, parce qu’elles s’exécutent dans le même processus, sur le même moteur, avec les mêmes objets fondamentaux que ce qu’elles prétendent contenir.
Ce qu’on en retient chez Humanix
- Une dépendance que personne ne sait nommer est un problème de gouvernance avant d’être un problème technique. La question « qu’est-ce qui s’exécute quand l’utilisateur clique ici » doit avoir une réponse, et cette réponse doit être écrite quelque part. Un inventaire des composants, même imparfait, vaut infiniment mieux que la mémoire d’un prestataire parti il y a trois ans.
- Un gabarit qui évalue des expressions est du code. Il doit donc être traité comme tel : relu, versionné, et jamais fourni par un utilisateur. Si votre application accepte qu’un client dépose son propre modèle de document, vous acceptez qu’il dépose du code.
- Ne faites jamais reposer une frontière de sécurité sur une sandbox applicative. Si votre modèle de menace suppose qu’elle tienne, mettez une vraie frontière en dessous : processus séparé, conteneur dédié, utilisateur sans privilèges, aucun accès réseau sortant, aucun secret accessible. Ainsi, le jour où l’évasion arrive, elle débouche sur une impasse.
- Un symptôme de performance mérite un regard sécurité. Cinq minutes pour produire un document, ce n’est pas de la lenteur, c’est le signe que quelque chose est interprété. Les anomalies de durée sont des anomalies tout court, et elles se trouvent dans vos journaux applicatifs, pas dans ceux de votre antivirus.
- Vos messages d’erreur sont une carte. Ce sont eux qui ont permis d’identifier le composant. Ils rendent le même service à un attaquant. Vérifiez ce que vos pages d’erreur exposent réellement en production.
- Enfin, c’est la forme normale du travail réel. Une mission qui démarre sur un ticket de lenteur et se termine sur une exécution de commande, ce n’est pas un scénario de conférence, c’est un mardi. Personne n’avait mal fait son travail, et pourtant la faille était là. C’est pourquoi nous ne venons pas distribuer des mauvais points : nous venons montrer ce qui s’exécute vraiment. La preuve avant le verdict.
À retenir
- Point de départ : une génération de PDF lente et instable, sans gabarit, sans documentation, et un client incapable de nommer la technologie sous-jacente.
- Le mot-clé trouvé dans le gabarit ne renvoyait aucun résultat : une dépendance sans trace publique dans sa propre production est une dépendance que personne ne met à jour.
- L’identification est venue des chemins d’erreur, qui exposaient l’arborescence interne du composant.
- Le composant n’était pas un moteur de gabarits mais un interpréteur JavaScript en sandbox. La lenteur et la faille avaient la même cause.
- Les données injectées dans le gabarit étaient évaluées comme du code, d’où une évasion de sandbox puis une exécution de commande à distance.
- À faire chez vous : inventorier les composants de votre chaîne documentaire, traiter les gabarits comme du code, n’accepter aucun modèle fourni par un utilisateur, et placer une vraie frontière d’isolation sous toute sandbox applicative.
Note et choix éditoriaux. Compte-rendu, à visée pédagogique, d’une intervention courte de la session de rumps de BarbHack 2026, complété par nos soins sur le contexte public de ce type de vulnérabilité. Nous ne nommons pas le composant concerné et ne décrivons pas le vecteur d’injection, pour deux raisons : le nom relevé dans le compte-rendu est manifestement altéré et ne correspond à aucun projet identifiable avec certitude, et surtout rien n’indique que la vulnérabilité ait été signalée puis corrigée. Publier un nom et une méthode d’exploitation encore valides reviendrait à diffuser une attaque, pas à faire de la pédagogie. Les vulnérabilités citées en comparaison sont, elles, publiques et documentées. Si vous exploitez une génération de documents à partir de gabarits, la vérification utile ne demande pas de connaître ce composant : identifiez ce qui interprète vos modèles, et déterminez si des données utilisateur y parviennent. Quatorzième volet de notre couverture de l’événement. Besoin d’un état des lieux de votre chaîne de génération documentaire ? Contactez-nous.