Gotenberg est une API Docker stateless très populaire pour générer et manipuler des PDF (utilisée par des milliers de microservices et apps SaaS pour la génération de factures, rapports, contrats). CVE-2026-40281 (CVSS 10.0) révèle une vulnérabilité critique dans l'endpoint d'écriture de métadonnées : un caractère newline dans la valeur d'une metadata permet d'injecter des pseudo-tags ExifTool arbitraires, débouchant sur la réécriture de fichiers ou la création de symlinks/hardlinks arbitraires dans le système de fichiers du conteneur.
C'est un bypass du correctif incomplet introduit en v8.30.1 (qui validait les clés mais pas les valeurs). La version corrigée est 8.31.0.
Détails techniques
Comment Gotenberg utilise ExifTool
Gotenberg délègue la manipulation des metadata PDF à ExifTool, l'outil de référence pour lire/écrire les metadata des fichiers multimédias. L'endpoint vulnérable accepte une requête HTTP qui spécifie des paires clé/valeur de metadata à écrire :
POST /forms/pdfengines/metadata HTTP/1.1
Content-Type: multipart/form-data; boundary=...
[fichier PDF]
Title=Mon Document
Author=John Doe
En interne, Gotenberg construit une commande ExifTool puis passe les paires clé/valeur via stdin :
exiftool -overwrite_original -@ - input.pdf
Le format -@ - indique à ExifTool de lire les arguments une ligne par argument depuis stdin. Gotenberg écrit alors :
-Title=Mon Document
-Author=John Doe
Le bug
Le correctif en v8.30.1 a validé les clés pour les caractères de contrôle (rejet de \n, \r, etc.). Mais les valeurs sont restées non sanitisées. Un attaquant envoie une valeur contenant un newline :
Title=Document\n-FileName=/etc/passwd
ExifTool reçoit sur stdin :
-Title=Document
-FileName=/etc/passwd
→ ExifTool interprète la deuxième ligne comme un pseudo-tag séparé : -FileName n'est pas un tag PDF, c'est un pseudo-tag ExifTool qui renomme le fichier vers le chemin spécifié.
Pseudo-tags ExifTool dangereux exposés
| Pseudo-tag | Effet |
|---|---|
-FileName | Renomme/déplace le fichier traité vers un chemin arbitraire |
-Directory | Déplace le fichier vers un répertoire arbitraire |
-SymLink | Crée un lien symbolique du PDF vers un chemin arbitraire |
-HardLink | Crée un lien physique vers un chemin arbitraire |
Un attaquant peut :
- Écraser des fichiers de configuration du conteneur (
/etc/passwd, configs d'app) - Créer un symlink depuis un chemin sensible (
/etc/cron.d/,/proc/self/mem) vers le PDF qu'il contrôle - Hardlink vers des fichiers privilégiés pour exfiltration
Caractéristiques
| Champ | Valeur |
|---|---|
| CVSS 3.1 | 10.0 (CRITICAL) |
| Vecteur | AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:H |
| CWE | CWE-77 (Command Injection) + CWE-20 (Improper Input Validation) |
| Scope | Changed (S:C) — l'attaque dépasse le binaire Gotenberg pour impacter le filesystem |
| Authentification | Aucune |
Produits et versions affectés
| Produit | Versions affectées | Version corrigée |
|---|---|---|
| Gotenberg | ≤ 8.30.1 | 8.31.0 |
À noter : la v8.30.1 elle-même était un correctif incomplet d'un problème antérieur — d'où l'urgence de patcher.
Vérifiez votre version :
# Docker
docker inspect gotenberg --format '{{.Config.Image}}'
# Ou via l'endpoint health
curl https://gotenberg.example.com/health
Exploitation et impact
Conditions d'exploitation
- Gotenberg accessible HTTP (souvent en interne dans un cluster K8s, mais parfois exposé via Ingress public pour des intégrations B2B)
- L'endpoint d'écriture de metadata est non authentifié par défaut dans Gotenberg
- L'attaquant peut envoyer un PDF + une valeur de metadata avec newline injecté
Impacts concrets
1. Réécriture de la config du conteneur
Si Gotenberg tourne en root (cas courant en Docker), l'attaquant peut écraser /etc/passwd ou ajouter des entrées à /etc/cron.d/. La persistance dépend de la durée de vie du conteneur — sur des déploiements Kubernetes avec PVCs, l'altération peut survivre aux redémarrages.
2. Escape vers le host via symlink + volume mount
Si Gotenberg a un volume Docker monté en write (typique : /tmp ou un volume pour les PDFs traités), un symlink créé via la CVE peut pointer vers /host/etc/cron.d/malicious.sh si le volume est mappé au host filesystem. Variante : sur Kubernetes, accès aux secrets/configmaps mountés en volume.
3. Vol de PDF d'autres tenants (multi-tenant)
Si Gotenberg traite des PDFs pour plusieurs clients (cas SaaS), un attaquant peut créer un symlink qui pointe vers un PDF d'un autre tenant en cours de traitement, et le récupérer en sortie de pipeline.
4. DoS du service
Trivial : écraser le binaire Gotenberg lui-même ou ses fichiers de configuration → crash et indisponibilité.
PoC concept
# Préparation du PDF + metadata malveillante
curl -X POST "https://gotenberg.example.com/forms/pdfengines/metadata" \
-F "files=@input.pdf" \
-F "metadata={\"Title\":\"Doc\n-FileName=/tmp/owned\"}"
ExifTool exécute ensuite la première ligne (-Title=Doc) puis la seconde (-FileName=/tmp/owned), renommant le PDF en /tmp/owned.
Détection et IOC
Logs Gotenberg
# Activer le mode debug et chercher les patterns suspects
docker logs gotenberg 2>&1 | grep -iE "exiftool|filename|symlink|directory"
Indicateurs :
- Erreurs ExifTool sur des arguments inattendus
- Logs montrant des paths absolus dans les valeurs de metadata (
/etc,/var,/proc) - Apparition de fichiers inhabituels dans le filesystem du conteneur
Audit filesystem du conteneur
# Liste les fichiers récemment modifiés
docker exec gotenberg find / -newer /tmp -type f 2>/dev/null | head -20
# Liste les symlinks vers des chemins sensibles
docker exec gotenberg find / -type l -ls 2>/dev/null | grep -E "etc|var|proc"
Règle WAF
# Bloquer les newlines dans les valeurs de metadata
SecRule ARGS_NAMES "@beginsWith metadata" \
"id:'2026040281',phase:2,deny,status:403,\
chain,\
msg:'Gotenberg CVE-2026-40281 metadata newline injection'"
SecRule ARGS "@rx \\\\n|\\\\r|%0a|%0d" \
"t:none,t:lowercase"
Mitigation et patch
Action immédiate : mettre à jour
# Docker
docker pull gotenberg/gotenberg:8.31.0
docker compose up -d
# Kubernetes
kubectl set image deployment/gotenberg gotenberg=gotenberg/gotenberg:8.31.0
Workaround si patch impossible
- Désactiver l'endpoint metadata si non utilisé :
# Gotenberg accepte des flags pour désactiver des modules
command:
- "gotenberg"
- "--api-disable-routes=/forms/pdfengines/metadata"
- Mettre un proxy/WAF devant qui filtre les
\n,\r,%0a,%0ddans les paramètres - Faire tourner Gotenberg en non-root (impact réduit du compromission filesystem)
- Read-only filesystem sur le conteneur :
# docker-compose
services:
gotenberg:
read_only: true
tmpfs:
- /tmp
Hardening durable
- Authentification sur les endpoints Gotenberg (proxy d'auth devant si non supporté nativement)
- Network policy Kubernetes restreignant qui peut atteindre Gotenberg
- Audit régulier des images Docker en production
Pourquoi surveiller en continu vos microservices Docker
Les microservices DevOps comme Gotenberg, ImageMagick, FFmpeg-as-a-service, Tika, sont déployés massivement en interne sans visibilité particulière. Une CVE comme CVE-2026-40281, exploitant un binaire externe (ExifTool) intégré au microservice, peut passer sous le radar des scanners de vulnérabilités traditionnels qui n'inspectent pas les binaires embarqués dans les images Docker.
Avec cveo.tech, inventoriez vos microservices DevOps (générateurs PDF, convertisseurs d'images, moteurs de templating) et soyez alerté automatiquement dès qu'une CVE critique cible une de vos versions exactes — pour ne plus découvrir l'exploitation après les faits.