Samuel Arendt

Laravel 12.72.0 e 13.41.0 corrigem URLs assinadas temporárias que podiam não expirar

Em 11 de novembro de 2026, o Laravel publicou dois avisos de segurança sobre URLs assinadas temporárias, as geradas por temporarySignedRoute() e validadas pelo middleware signed. Nos dois casos, uma URL criada para valer por um tempo limitado podia ser aceita depois do prazo, como se não tivesse expiração. Estão afetadas as versões anteriores à 12.72.0 e as versões 13.x anteriores à 13.41.0. As duas correções saíram em 10 de novembro, nas versões 12.72.0 e 13.41.0 do pacote laravel/framework.

Os dois avisos têm severidade moderada (CVSS 4.8), sem CVE atribuído até agora. A nota é moderada porque cada falha depende de uma condição específica, descrita abaixo. Para quem usa esse tipo de link para liberar download, aceitar convite ou confirmar uma ação sem login, a consequência prática é a mesma: o prazo de validade deixa de ser garantido.

As duas falhas

A primeira (GHSA-v5ch-g375-82r6) envolve o limite max_input_vars do PHP. Quando a URL traz parâmetros suficientes para passar desse limite, o PHP descarta o expires da query já interpretada. A assinatura, porém, continua sendo conferida contra a query string bruta, que ainda contém o campo. Resultado: a assinatura confere, e a checagem de prazo entende que a URL não expira. O próprio aviso diz que a exploração exige uma linha de requisição longa e que as configurações padrão do nginx e do Apache já rejeitam uma URL desse tamanho.

A segunda (GHSA-6rv8-qj5v-p8ch) depende do código da aplicação. Se ela passa para temporarySignedRoute() ou signedRoute() parâmetros com chave numérica que vêm do usuário, como o array da query da requisição, o Laravel acrescentava esses valores à URL sem codificá-los. Com isso, quem controla a entrada consegue inserir um segundo campo expires, que entra na assinatura e passa a ser o valor lido na validação.

Quem precisa olhar agora

Qualquer aplicação Laravel 12 ou 13 que emita URLs assinadas temporárias deve atualizar. O risco maior está em dois perfis: quem gera esses links repassando arrays vindos da requisição, e quem roda atrás de um servidor ou proxy configurado para aceitar URLs muito mais longas que o padrão.

O caso mais delicado é o das aplicações em Laravel 11 ou anterior. A faixa afetada nos avisos é "abaixo de 12.72.0", e a política de suporte do Laravel encerrou as correções de segurança do Laravel 11 em 12 de março de 2026 (as do Laravel 10 terminaram em fevereiro de 2025). Não haverá patch para essas linhas. Para elas, o aviso vira mais um item na conta de uma migração adiada, o mesmo problema que discuti em uma versão suportada ainda exige uma decisão de migração: a data de fim de suporte já passou e não há correção a esperar do projeto.

O que fazer

Atualizar laravel/framework para 12.72.0 ou 13.41.0 (ou posterior) e fazer o deploy. Vale também procurar no código as chamadas a temporarySignedRoute() e signedRoute() que recebem algo como $request->query() ou $request->all(). O aviso recomenda passar apenas parâmetros escolhidos explicitamente, com chave em texto, mesmo depois da atualização.

Quem não consegue atualizar já tem dois paliativos documentados no aviso da primeira falha: limitar o tamanho da URL no servidor web ou, sem acesso a essa configuração, colocar antes do signed um middleware que recuse a requisição quando a query bruta tiver mais pares que o max_input_vars ou quando o expires aparecer na query bruta e sumir da interpretada. No Laravel 11, esse é o caminho até a migração.

Na linha 12.x, há um cuidado extra. A correção da segunda falha passou a codificar também valores EncodedParameter, que deveriam sair sem alteração. A issue #62416 relata que, no 12.72.0, q=000001 passou a ser gerado como q%3D000001. Se a aplicação usa EncodedParameter em redirecionamentos ou rotas, teste esses fluxos antes de publicar.

O que ainda não se sabe

A correção da regressão do EncodedParameter foi incorporada ao branch 12.x em 11 de novembro, junto com uma proteção adicional que recusa expires em formato de array, mas até 12 de novembro não havia versão 12.x publicada depois da 12.72.0 com essas mudanças. Os avisos também não dizem se houve exploração conhecida, nem se uma URL gerada antes da atualização com um expires duplicado passa a ser recusada depois dela. Por fim, o blog do Laravel ainda não publicou nota sobre o assunto; a informação oficial está nos avisos do repositório.

Se a sua empresa está avaliando algo parecido, me chama no LinkedIn ou no WhatsApp.

Referências

Porta entreaberta numa parede branca, com o vão escuro refletido no piso brilhante

Foto de Joe Green no Unsplash

#Operações, #Qualidade de Software, #Radar