
Detecta o padrão de rewrite CVE-2026-42945 em configurações do nginx: rewrite com ? na substituição mais uma captura sem nome consumida no mesmo location
Encontra configurações vulneráveis ao CVE-2026-42945, o estouro de buffer no heap no ngx_http_rewrite_module do nginx.
Executar uma versão do nginx afetada (0.6.27 a 1.30.0) não é suficiente para ser explorável. A configuração precisa conter um par específico de diretivas, e esse par é raro: duas varreduras independentes de configurações reais encontraram zero configurações exploráveis em 1465 e uma em 35633. Este script diz em que lado dessa linha você está.
Um rewrite cuja substituição contém um ? com argumentos depois dele, seguido por uma captura sem nome ($1 a $9) lida no mesmo location:
location / {
rewrite ^(.*) /new?c=1; # the ? here raises the internal is_args flag
set $myvar $1; # ...which was never cleared, and leaks into this
return 200 $myvar;
}
Uma passagem dimensiona o buffer para a string bruta; a seguinte copia uma versão escapada para ele. As duas metades parecem corretas isoladamente.
Cada regra abaixo foi medida no nginx 1.30.0 em vez de inferida, porque as descrições publicadas erram duas delas.
| Configuração dentro de um location | Crash |
|---|---|
rewrite ^(.*) /new?c=1; + set $x $1; | sim |
rewrite ^/old/(.*)$ /new?x=1; + set $x $1; | sim |
rewrite ^/old/(.*)$ /new/$1?; + set $x $1; | não |
rewrite ... /mid?c=1; depois rewrite ... /new; depois set $x $1; | não |
rewrite ^(.*) /new?c=1 break; + set $x $1; | não |
rewrite ^(?<tail>.*) /new?c=1; + set $x $1; | sim |
rewrite ^(?<tail>.*) /new?c=1; + set $x $tail; | não |
Duas consequências que valem a pena explicitar:
Um ? no final não é perigoso. /new/$1? é como se elimina a query string herdada, e isso aparece em uma grande parcela das configurações de migração. Sinalizar todo ? gritaria com metade da internet.
"Capturas nomeadas são seguras" está errado. O que importa é como a captura é lida, não como foi declarada. Um grupo nomeado lido como $1 causa crash exatamente como um sem nome.
Também são ignorados, pelas mesmas razões medidas: um ? dentro da própria regex (um quantificador), e redirect / permanent / break, que encerram o processamento antes de o consumidor ser executado.
nginx -T | python3 check_rewrite.py
python3 check_rewrite.py /path/to/dump.txt
python3 check_rewrite.py --json /path/to/dump.txt
Python 3, apenas biblioteca padrão.
Códigos de saída: 0 limpo, 1 um par foi encontrado, 2 a configuração não pôde ser lida ou analisada. O terceiro é o ponto principal: uma aspa não fechada ou chaves desbalanceadas truncam a análise, e um verificador que responde "nada encontrado" para um arquivo que não conseguiu ler é pior do que um que quebra. Quando isso acontece, ele avisa e retorna 2.
Alimente-o com nginx -T, não com arquivos individuais: os includes podem estar em qualquer lugar, e uma configuração gerada só é verdadeira no servidor em execução. As descobertas são reportadas com o arquivo e a linha em que a diretiva realmente está, não com o offset no dump.
$ python3 check_rewrite.py samples/vuln-nginx-T.txt
[HIGH] находка #1
location: location / (/etc/nginx/nginx.conf:14)
rewrite: rewrite ^(.*) /new?c=1 (/etc/nginx/nginx.conf:15)
захват $N: set -> set $myvar $1 (/etc/nginx/nginx.conf:16)
почему: обработка продолжается в этом же location без редиректа
Итого находок: 1
Também impressos no final de cada relatório, para ninguém confundir a ferramenta com uma garantia:
location é reportado;rewrite e set diretamente em server, em vez de dentro de um location, não são rastreados;set $tmp $1; e depois usar $tmp) não são seguidas;try_files, error_page e locations nomeados não são seguidos;if que nunca é executado ainda é reportado.Atualizar é mais confiável do que qualquer verificação de configuração. Pegue a versão estável ou mainline atual em nginx.org.
python3 -m unittest test_check_rewrite -v
29 testes. A maioria são casos negativos, já que o risco de uma ferramenta assim é reclamar de configurações que estão bem. Ela também foi executada contra uma configuração de produção de 250 linhas em onze arquivos incluídos, com uma regex de map e um cabeçalho CSP cheio de ponto e vírgula entre aspas: zero descobertas, zero reclamações de parse e exatamente uma descoberta depois que um par real foi injetado nela.
MIT