Em resumo: Quem quer atualizar dependências precisa de um processo para três mundos de pacotes: pacotes Composer no código PHP, módulos npm no build do frontend e plugins ou temas no CMS. Fazem parte um ritmo fixo, uma pessoa responsável, testes antes da implementação e um plano para pacotes sem atualização. Contra o PHP2Shell isto não ajuda, pois essa falha está no próprio PHP, mas ajuda contra as muitas falhas em código alheio.
Três mundos de pacotes, um ponto cego
Na semana após 21 de outubro de 2026, tudo girou em torno do interpretador PHP. Muitas equipas aperceberam-se então de que não conhecem exatamente as versões dos seus próprios componentes. O site funciona, a agência trata do assunto, o plugin avisa quando há novidades: assim, ou de forma semelhante, são as suposições, até alguém ir verificar.
Um projeto PHP típico é hoje constituído por muito mais código alheio do que próprio. O OWASP Top 10 inclui os componentes vulneráveis e desatualizados como categoria de risco própria. O problema raramente é a falta de ferramenta, mas a falta de rotina: as atualizações acontecem quando alguém tem tempo, e os avisos de segurança vão parar a uma caixa de correio que ninguém lê.
Que dependências atualiza e onde?
Cada mundo de pacotes tem ferramentas próprias e armadilhas próprias. A visão geral seguinte ajuda a não deixar nada de fora.
| Mundo de pacotes | Mostrar o inventário | Verificar falhas | Armadilha típica |
|---|---|---|---|
| Composer (bibliotecas PHP) | composer show |
composer audit |
pacotes indiretos que ninguém conhece |
| npm (build do frontend) | npm ls |
npm audit |
uma atualização sem nova construção nunca chega ao servidor |
| Plugins e temas de CMS | interface de administração ou CLI | avisos do fabricante, serviços de segurança | plugins abandonados, plugins pagos sem canal de atualização |
| PHP e extensões | gestão de pacotes | security tracker da distribuição | a versão apresentada diz pouco sobre backports |
A última linha não faz, a rigor, parte das dependências da aplicação, mas é muitas vezes esquecida no mesmo fôlego. O mesmo vale para scripts integrados diretamente a partir de servidores alheios, por exemplo bibliotecas de uma CDN, widgets de chat ou código de rastreio. Não aparecem em nenhum ficheiro lock, mas correm no navegador dos seus visitantes. Inclua-os na lista e verifique se estão integradas versões fixas em vez de “sempre a mais recente”. Os pormenores sobre composer audit, ficheiro lock e integração no build estão no guia composer audit: verificar vulnerabilidades nas dependências. Como o Composer funciona em geral é explicado em Composer: o gestor de pacotes do PHP.
O ciclo de manutenção em seis passos
Um processo sólido não tem de ser complicado. Esta ordem provou ser útil:
- Registar o inventário: para cada projeto, uma lista das dependências diretas com versão, origem e finalidade. Os ficheiros lock (
composer.lock,package-lock.json) pertencem ao repositório. - Recolher avisos: as ferramentas de verificação correm em cada build e, além disso, regularmente sobre o estado entregue, mesmo sem alteração de código.
- Avaliar: o pacote afetado é usado em produção, a função afetada é acessível, existe uma versão corrigida?
- Atualizar e testar em staging: primeiro as atualizações de segurança dentro da mesma versão principal; saltos para novas versões principais planeiam-se como projeto próprio.
- Implementar com via de retorno: o estado anterior permanece disponível como pacote ou release, backup da base de dados antes da atualização.
- Documentar: o que foi atualizado e quando, o que não foi e porquê.
Atenção às indicações de versão em composer.json e package.json. Restrições demasiado estreitas impedem que as correções de segurança possam sequer ser instaladas. Restrições demasiado largas trazem, pelo contrário, novas versões principais para o projeto sem verificação. Provou ser útil permitir atualizações dentro da versão principal e planear conscientemente o salto para a seguinte.
Para plugins no CMS, as atualizações disponíveis podem muitas vezes ser mostradas também na linha de comandos, no WordPress por exemplo com o WP-CLI:
# Mostrar atualizações disponíveis, sem alterar nada
wp plugin list --update=available
wp theme list --update=available
# Pacotes de frontend: versões desatualizadas e falhas conhecidas
npm outdated
npm audit --omit=dev
As atualizações automáticas de plugins diretamente no sistema de produção são cómodas, mas arriscadas se ninguém verificar depois. Ative-as apenas se um backup antes de cada execução e um controlo depois estiverem garantidos.
Quando não há atualização
Nem todo o aviso se resolve com um clique. O Cheat Sheet da OWASP sobre o tratamento de dependências vulneráveis distingue vários casos, que se aplicam bem ao dia a dia:
- Patch disponível: aplicar em staging, testar, implementar. Se algo quebrar, adaptar o código próprio em vez de deixar a atualização parada.
- Patch anunciado, mas ainda não disponível: aplicar a solução alternativa do fabricante, desativar ou isolar a função afetada, se possível, e registar a decisão.
- Não se espera patch: procurar um pacote de substituição ou fazer o backport da correção por si, com um teste que distinga a falha antes e depois do patch.
Nos plugins de CMS há com frequência um quarto caso: o plugin está abandonado. Então só ajudam a substituição ou a remoção. O mesmo vale para plugins de fontes pouco claras, por exemplo cópias “gratuitas” de plugins pagos. Não recebem atualizações pelo canal oficial e contêm, não raramente, código malicioso. As indicações para operadores de WordPress estão reunidas em Vulnerabilidade PHP2Shell no WordPress: o que os operadores têm de fazer.
Esclarecer a responsabilidade antes do próximo aviso
A razão mais frequente para pacotes desatualizados não é um obstáculo técnico, mas uma pergunta em aberto: quem o faz? Em projetos construídos por uma agência e operados internamente, ninguém se sente muitas vezes responsável. Defina para cada projeto quem recebe os avisos, quem avalia e quem aprova, e escreva-o.
Planeie também tempo. Uma data fixa de manutenção por mês, em que as dependências são verificadas e atualizadas, evita que as atualizações se acumulem durante anos. Quanto mais tempo um projeto não é atualizado, maior e mais arriscado se torna o salto seguinte. Como as atualizações do PHP e dos pacotes se integram num processo abrangente é descrito em Gestão de patches como processo, e não como corpo de bombeiros.
Como ajuda concretamente a PHP SOS?
- Registamos todas as dependências dos seus projetos a partir de Composer, npm e CMS e assinalamos os pacotes desatualizados, vulneráveis e abandonados.
- Configuramos verificações automáticas e definimos quem avalia cada aviso.
- Atualizamos em staging, testamos os fluxos mais importantes e implementamos com via de retorno.
- No âmbito de um contrato de manutenção de segurança, assumimos o ciclo mensal de forma duradoura, incluindo as atualizações do PHP.
Conclusão: Dependências atualizadas não são um projeto, são rotina. Quem regular uma vez, com rigor, inventário, ritmo e responsabilidade só terá de verificar, e não de procurar, no próximo grande aviso.
Perguntas frequentes
Com que frequência se devem atualizar as dependências?
As atualizações de segurança o mais depressa possível após avaliação, as atualizações de rotina num ritmo fixo, por exemplo mensal. Mais importante do que a frequência exata é que a data esteja fixada e que alguém seja responsável por ela.
Um plugin atualizado protege contra o PHP2Shell?
Não. O PHP2Shell está no próprio interpretador PHP. Contra isso só ajuda uma atualização do PHP com reinício de todos os processos PHP. Plugins e pacotes atualizados são, mesmo assim, importantes, porque fecham falhas próprias.
O que faço com um plugin que já não é mantido?
Substituir ou remover. Um plugin abandonado já não recebe correções, mesmo que ainda hoje funcione. Até à substituição, deve verificar se a função é mesmo necessária e documentar a decisão.
O frontend com npm também tem de ser atualizado no servidor?
Muitas vezes os pacotes npm só existem no build e chegam ao servidor como ficheiros já prontos. Uma falha num pacote pode, mesmo assim, estar no JavaScript entregue. Depois de uma atualização, é por isso necessário voltar a construir e a entregar.