Request Smuggling in HTTP/2 Downgrades

Reading time: 6 minutes

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

HTTP/2 è generalmente considerato immune al classic request-smuggling perché la lunghezza di ogni frame DATA è esplicita. Quella protezione scompare non appena un proxy front-end “downgrada” la richiesta a HTTP/1.x prima di inoltrarla a un back-end. Nel momento in cui due parser diversi (il front-end HTTP/2 e il back-end HTTP/1) cercano di concordare su dove una richiesta finisce e la successiva inizia, tutti i vecchi trucchi di desync tornano – più alcuni nuovi.


Perché avvengono i downgrade

  1. I browser parlano già HTTP/2, ma gran parte dell'infrastruttura legacy di origine comprende ancora solo HTTP/1.1.
  2. I reverse-proxy (CDN, WAF, load-balancer) quindi terminano TLS + HTTP/2 al confine e riscrivono ogni richiesta come HTTP/1.1 per l'origine.
  3. Il passaggio di traduzione deve creare entrambi gli header Content-Length e/o Transfer-Encoding: chunked in modo che l'origine possa determinare la lunghezza del corpo.

Ogni volta che il front-end si fida della lunghezza del frame HTTP/2 ma il back-end si fida di CL o TE, un attaccante può costringerli a non essere d'accordo.


Due classi primitive dominanti

VarianteLunghezza front-endLunghezza back-endPayload tipico
H2.TEFrame HTTP/2Transfer-Encoding: chunkedIncludere un corpo di messaggio chunked extra il cui finale 0\r\n\r\n non viene inviato, quindi il back-end attende la “prossima” richiesta fornita dall'attaccante.
H2.CLFrame HTTP/2Content-LengthInviare un CL più piccolo rispetto al corpo reale, quindi il back-end legge oltre il confine nella richiesta successiva.

Questi sono identici nello spirito ai classici TE.CL / CL.TE, solo con HTTP/2 che sostituisce uno dei parser.


Identificare una catena di downgrade

  1. Usa ALPN in un handshake TLS (openssl s_client -alpn h2 -connect host:443) o curl:
bash
curl -v --http2 https://target

Se appare * Using HTTP2, il confine parla H2. 2. Invia una richiesta CL/TE deliberatamente malformata sopra HTTP/2 (Burp Repeater ora ha un menu a discesa per forzare HTTP/2). Se la risposta è un errore HTTP/1.1 come 400 Bad chunk, hai la prova che il confine ha convertito il traffico per un parser HTTP/1 a valle.


Flusso di sfruttamento (esempio H2.TE)

http
:method: POST
:path: /login
:scheme: https
:authority: example.com
content-length: 13      # ignored by the edge
transfer-encoding: chunked

5;ext=1\r\nHELLO\r\n
0\r\n\r\nGET /admin HTTP/1.1\r\nHost: internal\r\nX: X
  1. Il front-end legge esattamente 13 byte (HELLO\r\n0\r\n\r\nGE), pensa che la richiesta sia finita e inoltra tanto all'origine.
  2. Il back-end si fida dell'intestazione TE, continua a leggere fino a vedere il secondo 0\r\n\r\n, consumando così il prefisso della seconda richiesta dell'attaccante (GET /admin …).
  3. Il resto (GET /admin …) è trattato come una nuova richiesta in coda dietro quella della vittima.

Sostituisci la richiesta smuggled con:

  • POST /api/logout per forzare la fissazione della sessione
  • GET /users/1234 per rubare una risorsa specifica della vittima

h2c smuggling (upgrade in chiaro)

Uno studio del 2023 ha mostrato che se un front-end passa l'intestazione HTTP/1.1 Upgrade: h2c a un back-end che supporta HTTP/2 in chiaro, un attaccante può tunnelare frame HTTP/2 raw attraverso un edge che ha convalidato solo HTTP/1.1. Questo bypassa la normalizzazione delle intestazioni, le regole WAF e persino la terminazione TLS.

Requisiti chiave:

  • L'edge inoltra entrambi Connection: Upgrade e Upgrade: h2c invariati.
  • L'origine incrementa a HTTP/2 e mantiene la semantica di riutilizzo della connessione che consente l'accodamento delle richieste.

La mitigazione è semplice: rimuovere o hard-codificare l'intestazione Upgrade all'edge tranne che per i WebSocket.


CVE reali notevoli (2022-2025)

  • CVE-2023-25690 – Le regole di riscrittura mod_proxy di Apache HTTP Server potrebbero essere concatenate per la divisione e lo smuggling delle richieste. (risolto in 2.4.56)
  • CVE-2023-25950 – Smuggling di richieste/riposte in HAProxy 2.7/2.6 quando il parser HTX gestiva in modo errato le richieste in pipeline.
  • CVE-2022-41721 – Go MaxBytesHandler ha causato che i byte del corpo rimanenti venissero analizzati come frame HTTP/2, abilitando lo smuggling cross-protocol.

Strumenti

  • Burp Request Smuggler – dalla versione v1.26 testa automaticamente H2.TE/H2.CL e il supporto ALPN nascosto. Abilita “HTTP/2 probing” nelle opzioni dell'estensione.
  • h2cSmuggler – PoC Python di Bishop Fox per automatizzare l'attacco di upgrade in chiaro:
bash
python3 h2csmuggler.py -u https://target -x 'GET /admin HTTP/1.1\r\nHost: target\r\n\r\n'
  • curl/hyper – creazione di payload manuali: curl --http2-prior-knowledge -X POST --data-binary @payload.raw https://target.

Misure difensive

  1. HTTP/2 end-to-end – eliminare completamente la traduzione di downgrade.
  2. Fonte unica di verità sulla lunghezza – quando si effettua il downgrade, generare sempre un valido Content-Length e rimuovere eventuali intestazioni Content-Length/Transfer-Encoding fornite dall'utente.
  3. Normalizzare prima della rotta – applicare la sanificazione delle intestazioni prima della logica di routing/riserve.
  4. Isolamento della connessione – non riutilizzare le connessioni TCP del back-end tra gli utenti; “una richiesta per connessione” sconfigge gli exploit basati su coda.
  5. Rimuovere Upgrade a meno che non sia WebSocket – previene il tunneling h2c.

Riferimenti

tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks