Duas RCE críticas no Next.js e o Gitea sob exploração
Semana passada eu escrevi que o Next.js tinha marcado 26 de agosto para publicar uma falha crítica, e que a parte boa da história era o aviso prévio. A data chegou um dia antes e com o dobro do problema. Foram duas falhas críticas, não uma, e a equipe antecipou a publicação porque achou a segunda no meio do caminho. Serviu exatamente para o que o aviso existe: quem gastou os dias levantando em que versão cada aplicação estava de verdade atualizou na terça. Quem não gastou passou a terça descobrindo que tem um painel interno rodando 15.4 desde o ano passado.
O segundo fio é o mesmo de sete dias atrás, com outro nome no lugar. Era o GitLab, agora é o Gitea: servidor de repositório que time pequeno sobe uma vez e esquece, com uma falha de 9,8 que roda comando com a conta de serviço. A diferença é que aqui não é mais hipótese. Tem relato de instância comprometida, prazo federal já vencido e a correção disponível desde julho.
E teve um amontoado de release entre segunda e quarta: Chrome 152, Node 26.8, Kubernetes 1.37 e o próprio Next.js, tudo em quarenta e oito horas. Oito itens. Três desenvolvidos.
Destaques
Next.js: duas RCE críticas, e a faixa afetada começa na 10.0.0
Em 25 de agosto saíram a 16.3.3 e a 15.5.24, um dia antes do combinado. A antecipação foi anunciada na manhã do mesmo dia: apareceu uma segunda falha crítica numa dependência de terceiro e eles preferiram juntar as duas numa correção só, para ninguém precisar atualizar duas vezes.
A primeira é a
GHSA-2xp9-vwfh-vxw4,
CVSS v4 de 9,5, e é onde mora o problema de verdade. A falha é do libheif, que
o sharp usa, e o sharp é quem o Next.js usa para otimizar imagem. Otimizar
um AVIF controlado pelo atacante dá execução remota de código sem autenticação
nenhuma. A faixa afetada é da 10.0.0 até a 15.5.23, mais tudo antes da 16.3.3,
ou seja: praticamente qualquer aplicação Next.js que faça otimização de imagem
nos últimos cinco anos. A correção desliga a otimização de AVIF enquanto o
upstream não sai. Vale o incômodo: você troca alguns por cento de compressão por
não executar decodificador de imagem em cima de arquivo que veio de fora.
A segunda é a CVE-2026-75604, também crítica, também execução remota sem autenticação, e essa é mais estreita: só pega aplicação que usa Pages Router e App Router ao mesmo tempo, sem Cache Components, com o servidor em sistema de arquivos Windows. Linux e macOS não são afetados. Não existe contorno, só atualizar.
O que muda na prática depende de onde a aplicação roda, e essa parte a Vercel
deixou explícita no changelog:
quem está hospedado lá já está protegido, sem upgrade, sem redeploy, sem mexer
em configuração. Eles desligaram AVIF no serviço de otimização de imagem deles e
a infra é Linux. Quem faz self-host carrega as duas. E aqui vai a parte que eu
acho mais fácil de errar: a faixa da falha de AVIF é tão larga que "a gente está
atualizado" não responde nada. Vá ver a versão instalada, uma por uma, incluindo
o container que ninguém reconstrói. Se a aplicação usa next/image apontando
para domínio remoto que o usuário influencia, ela está na pior configuração
possível para essa falha.
Gitea: 9,8 sendo explorado, com correção disponível desde julho
Em 25 de agosto a CISA colocou a CVE-2026-60004 no catálogo de exploração ativa, com prazo federal para o dia 28. A descrição no registro do CVE é curta e desagradável: Gitea antes da 1.27.1 permite execução remota de código pela API de diffpatch, através da instalação de git hook. CVSS 3.1 de 9,8, vetor de rede, complexidade baixa, sem privilégio e sem interação. A faixa afetada começa na 1.17.
O detalhe que importa é o caminho. A falha pede acesso de escrita a um repositório, o que soa como uma barreira até você lembrar que existe registro aberto. Onde ele está ligado, o atacante cria a conta, cria o repositório dele e ganha a escrita de graça. O relato que a Help Net Security recolheu é de uma instância self-hosted comprometida por um scanner automatizado, que registrou conta, criou repositório e subiu minerador. O comando roda com a conta de serviço do Gitea, que é justamente a conta que enxerga todos os repositórios da máquina.
O que muda na prática é a conta de tempo, e ela é constrangedora. A 1.27.1 saiu em 27 de julho, o advisory no dia seguinte, e a exploração automatizada apareceu um mês depois. Um mês é bastante para um projeto que se atualiza com uma troca de tag de imagem. Se você tem Gitea em algum lugar, a versão de linha hoje é a 1.27.3, de 29 de agosto, e a atualização é o menor dos trabalhos. Os outros dois são: confira se o registro aberto está ligado e se ele precisa estar, e, se a instância ficou exposta, olhe os git hooks dos repositórios antes de dar por encerrado. Correção fecha a porta, não desfaz o que entrou por ela.
Kubernetes 1.37: autoscaler chegando a zero, e um detalhe de SELinux que quebra pod
O Kubernetes v1.37, apelidado de Garhwal, saiu em 26 de agosto com 67 melhorias: 16 promovidas a estável, 23 a beta, 27 entrando em alfa e uma remoção. Três coisas dali mudam decisão.
A primeira é o HorizontalPodAutoscaler escalando até zero, que virou beta e vem
ligado por padrão. Com spec.minReplicas: 0, workload que usa métrica de objeto
ou externa some quando não tem trabalho e volta quando a métrica sobe. Não vale
para CPU e memória, porque essas métricas dependem de pod vivo, e é justamente
por isso que a mira do recurso é consumidor de fila, job em lote e carga com
GPU. Enquanto segura em zero, o HPA registra a condição ScaledToZero, que é o
que distingue "eu escalei para zero" de "alguém desligou isso na mão". Para quem
paga GPU ociosa, esse é o item mais caro da lista, no bom sentido.
A segunda é a que eu leria antes de subir a versão. SELinuxMount e
SELinuxChangePolicy viraram estáveis e ligados por padrão: volume passa a ser
montado com -o context=<label> em vez de ser rotulado recursivamente, desde
que o driver CSI opte por isso. A consequência está no próprio anúncio, com
todas as letras: pods com rótulos SELinux diferentes que compartilham um volume
no mesmo nó, e que conviviam sob a rotulagem recursiva, agora podem falhar ao
iniciar. Dá para voltar ao comportamento antigo pondo .spec.seLinuxChangePolicy
em Recursive no pod, e dá para desligar no cluster inteiro por mais uma
versão, porque o travamento fica para a 1.38. Cluster sem SELinux não sente
nada.
A terceira é chata e vale para quem escreve controller. A inicialização
resiliente do watch cache fechou em estável, e o efeito é que o kube-apiserver
agora rejeita requisição cara com HTTP 429 em vez de deixar a fila crescer
contra o etcd durante a partida e a recuperação. Isso protege o control plane em
cluster grande, e transfere trabalho para o cliente: seu operador precisa tratar
429 respeitando o Retry-After, com backoff exponencial. Código que trata 429
como erro genérico e sai repetindo vai ter comportamento pior depois do upgrade,
não melhor. Na mesma leva, o KYAML e a API metrics.k8s.io chegaram a estável,
essa última depois de quase nove anos em beta.
Em nota
- Node 26.8.0 trouxe zip na biblioteca padrão. A
versão saiu em 26 de agosto
na linha Current e entraram as classes
ZipEntry,ZipFileeZipBuffernonode:zlib, maisStatementSync.prototype.close()e oSymbol.disposedo SQLite embutido, modos SIV e GCM-SIV noCipher, e umMIMEType.parseque não lança. Zip nativo tira uma dependência de árvore de projeto que só descompactava arquivo, e o SQLite comSymbol.disposefecha statement porusing. É linha Current, então trate como material de experimento, não de produção. No mesmo dia saiu a 26.8.1, fora de banda, só para consertar onode --versionque estava reportando versão alfa. - O Chrome 152 ganhou uma allowlist de conexão declarativa. A
versão começou a sair em 25 de agosto
com o cabeçalho
Connection-Allowlist, que restringe a quais endpoints externos a página pode se conectar. É CSP com outro nome e outro escopo, e é o tipo de coisa que ajuda contra script de terceiro que resolve conversar com domínio novo. Vieram junto uma API de performance de CPU, para a página se adaptar à capacidade do aparelho, eCSSPseudoElementpara::backdrop,::scroll-markere::view-transition. - A Assistants API da OpenAI foi desligada. O
changelog registra o
desligamento em 26 de agosto, com migração para Responses e Conversations. Na
mesma entrada entrou o fim de vida de
whisper-1,gpt-4o-transcribe,gpt-4o-mini-transcribeegpt-4o-transcribe-diarize, com desligamento marcado para 26 de fevereiro de 2027. O primeiro já quebrou quem não migrou. O segundo é o que vale anotar hoje, porque pipeline de transcrição é o tipo de coisa que roda sozinha e ninguém olha até parar. - Foi uma semana cheia no catálogo de exploração ativa da CISA. Além do Gitea, entraram dez CVEs entre 26 e 27 de agosto, incluindo NetScaler, SQL Server e uma da JFrog Artifactory. Essa última merece nota porque é ferramenta de quem constrói: a CVE-2026-66384 é travessia de caminho no cache de artefato Docker de repositório remoto, permite usuário autenticado escrever fora do diretório previsto, e afeta versões antes da 7.146.35 e da 7.161.0 até a 7.161.16. O CVSS dela é 5,3, média. Está sendo explorada mesmo assim, o que é o lembrete de sempre: nota de severidade não prevê exploração, contexto prevê.
- Nvidia comprando a Hugging Face, segundo a imprensa e ninguém mais. A
história saiu em 26 de agosto pelo The Information e foi repercutida por
TechCrunch,
CNBC e
Forbes,
falando em 12,9 bilhões de dólares. Registro com a ressalva que ela merece:
até aqui nem a Nvidia nem a Hugging Face confirmaram, e a
sala de imprensa da Nvidia não tem nada
sobre isso. Se confirmar, muda quem controla o lugar de onde metade do mundo
baixa peso de modelo. Mas a pergunta prática independe do desfecho: se o seu
build faz download de
hf.coem tempo de deploy, você já tem um ponto único de falha que não é seu, e isso valia consertar na semana passada.
O que eu faria com isso esta semana
- Levantar a versão real de Next.js de cada aplicação, não a do repositório
principal. A falha de AVIF pega da 10.0.0 em diante, então o critério não é
"estamos atualizados", é qual número aparece no
node_modulesda imagem que está no ar. Self-host atualiza para 16.3.3 ou 15.5.24. Quem está na Vercel não precisa fazer nada, mas confirme que é mesmo o caso antes de assumir. - Atualizar Gitea hoje e olhar o registro aberto. A correção é de julho, a exploração automatizada é desta semana e o alvo é o servidor que guarda seu código. Depois de atualizar, decida se o registro aberto precisa estar ligado naquela instância, e confira os git hooks se ela esteve exposta.
- Antes de subir para o Kubernetes 1.37, procurar volume compartilhado entre pods com rótulo SELinux diferente. É a única mudança da lista que falha na hora de iniciar, e ela tem escape documentado por mais uma versão. Depois disso, vale olhar se algum controller seu trata HTTP 429 como erro qualquer.
- Anotar 26 de fevereiro de 2027 no calendário de quem tem transcrição em produção. Os quatro modelos de áudio da OpenAI saem nessa data. Migração de modelo de transcrição não é troca de string: muda formato de saída, muda qualidade em português e muda o que o seu pós-processamento espera receber.
Radar é a newsletter semanal deste blog: o que aconteceu na semana em tecnologia, com comentário sobre o que muda para quem constrói e opera software.
- Next.js
- Gitea
- Kubernetes
- segurança
- Node.js