Principais conclusões
- As dependências multiplicam sua superfície de vulnerabilidade: o Express.js inclui cerca de 30 dependências diretas, cada uma com suas próprias cadeias transitivas, o que significa que a exposição ao fim do ciclo de vida (EOL) do Express.js vai muito além do próprio framework
- Migrações motivadas pelo pânico levam à quebra de cadeias de middleware, regressões no roteamento, instabilidade do sistema e estouros orçamentários que excedem em muito o custo do suporte estendido
- As opções de suporte estendido oferecem cobertura de segurança contínua para as versões do Express.js que chegaram ao fim da vida útil (EOL), enquanto você planeja as atualizações de acordo com seu próprio cronograma, e não com base no calendário.
Se você está executando o Express.js em produção — e, estatisticamente, há uma grande chance de que esteja —, provavelmente já passou por esse momento. Talvez tenha sido durante uma auditoria de dependências. Talvez tenha sido um comentário escondido em um tópico de issue no GitHub. Talvez tenha sido um colega que encaminhou um artigo com um assunto que começa com “Atenção…”
O Express.js sustenta uma parte enorme da infraestrutura de back-end da internet. É o framework que ensinou uma geração de desenvolvedores a criar APIs REST e ainda hoje, discretamente, mantém serviços essenciais em funcionamento em empresas de todos os tamanhos. Quando os alertas sobre o fim do ciclo de vida do Express.js começam a aparecer em seus relatórios de segurança, é fácil sentir como se o chão estivesse se movendo sob seus pés.
A questão é a seguinte: isso não precisa ser uma crise. Você tem mais opções do que imagina. Vamos analisar o que o fim do ciclo de vida do Express.js realmente significa para o seu ambiente de produção e, mais importante ainda, o que você pode fazer de forma realista a respeito disso sem comprometer seu plano de desenvolvimento.
Como funcionam, na verdade, os lançamentos do Express.js
Antes de entrarmos na parte do tipo “tudo bem, o que a gente faz de fato?”, é bom entender como o Express.js lida com o ciclo de vida de suas versões. Pois, ao contrário de alguns projetos com cronogramas rígidos e previsíveis, o Express sempre foi um pouco… mais flexível nesse aspecto.
O Express segue o que se poderia chamar de modelo de suporte a versões principais. A premissa básica é simples: quando uma nova versão principal é lançada, a versão principal anterior passa a ter o status de “suportada, mas sem todas as funcionalidades”, recebendo atualizações de segurança e correções de bugs críticos até que seja, eventualmente, descontinuada.
Veja a seguir como isso funciona nas diferentes versões do Express:
- Express v3.x chegou ao fim de vida útil em julho de 2015, após ser substituída pela v4. Não recebeu atualizações desde então.
- Express v4.x foi lançado em abril de 2014 e ainda conta com suporte oficial até hoje, o que o torna uma das versões principais mais duradouras no ecossistema JavaScript.
- Express v5.x foi lançado oficialmente em outubro de 2024, deixando de oferecer suporte às versões do Node.js anteriores à v18 e introduzindo mudanças significativas no roteamento, no tratamento de promessas e nas APIs obsoletas.
O desafio aqui não é a política de ciclo de vida em si; é o fato de que o Express avançou lentamente durante anos. A versão 5 ficou em desenvolvimento por mais de uma década antes de seu lançamento oficial. Esse longo período de gestação fez com que as equipes se baseassem profundamente na v4, e agora essas equipes enfrentam uma migração nada trivial para se manterem atualizadas.
E se você estiver usando uma versão mais antiga? O fim do ciclo de vida do Express.js já é um problema no presente, não no futuro.
O que o fim do ciclo de vida do Express.js realmente significa para sua API em produção
Tudo bem, então uma versão chega ao fim da vida útil (EOL). Sua API ainda está funcionando. Os endpoints estão respondendo. Tudo parece estar bem. Então, qual é, na verdade, o problema?
Eis a verdade incômoda sobre o fim do ciclo de vida do Express.js: as vulnerabilidades não deixam de ser descobertas só porque o suporte é encerrado. Os invasores não consultam o calendário de fim de vida antes de procurar por exploits. E a comunidade de pesquisa continua, sem dúvida, encontrando falhas em softwares amplamente implantados que chegaram ao fim do ciclo de vida, pois é lá que estão os alvos mais atraentes.
O Express possui um histórico bem documentado de vulnerabilidades (CVE) que ilustra exatamente por que isso é importante. Aqui estão alguns exemplos recentes que chamaram bastante atenção:
- CVE-2024-29041 (CVSS 6.1): Uma vulnerabilidade de redirecionamento aberto que afeta o Express 4.x anterior à versão 4.19.0. Os invasores poderiam criar URLs maliciosas que contornariam listas de permissão de redirecionamento implementadas corretamente, utilizando o método res.location() e res.redirect() , redirecionando usuários para sites externos arbitrários. Essa vulnerabilidade motivou a publicação de boletins de segurança pela IBM para vários produtos corporativos, incluindo o IBM Watson Assistant e o IBM MQ Appliance.
- CVE-2024-45296 (CVSS 7,5, Alta): Uma vulnerabilidade de negação de serviço por expressão regular (ReDoS) no `path-to-regexp`, uma dependência central de roteamento utilizada pelo Express. Um agente mal-intencionado pode explorar o backtracking em expressões regulares de correspondência de rotas para bloquear totalmente o loop de eventos do Node.js, derrubando o servidor. O ataque não requer autenticação nem interação do usuário; basta uma única solicitação HTTP maliciosa. Essa vulnerabilidade afetou todas as instalações do Express 4.x que utilizavam versões vulneráveis do path-to-regexp e motivou a emissão de boletins de segurança pela IBM para diversos produtos corporativos, incluindo o IBM Safer Payments.
Mas eis o ponto crucial: em uma versão do Express.js que chegou ao fim do ciclo de vida, essas vulnerabilidades não recebem correções. A equipe do Express não lançará correções para problemas da v3.x. Ponto final. Para as equipes que ainda utilizam a v3 — e não são poucas —, cada vulnerabilidade recém-descoberta representa uma exposição permanente até que elas migrem.
Para as equipes que utilizam a v4, a situação hoje é diferente (a v4 ainda recebe atualizações), mas a tendência é clara. O Express v5 já existe, e a v4 acabará seguindo os passos da v3 até o fim de sua vida útil. Acostumar-se com a mentalidade de “se está funcionando, não mexa nisso” é exatamente o que leva a migrações de emergência no futuro.
Além do risco imediato à segurança, as estruturas de conformidade estão cada vez mais explícitas em relação ao software em fim de vida útil. O PCI DSS exige a correção de vulnerabilidades críticas no prazo de 30 dias. Os auditores do SOC 2 fazem perguntas diretas sobre softwares sem suporte em ambiente de produção. Utilizar versões do Express.js em fim de vida útil não é mais apenas um risco técnico; é um problema de documentação.
O risco oculto: toda a sua cadeia de dependências
Quando a maioria das equipes pensa na segurança do Express.js, pensa no próprio Express. As rotas, o middleware, o tratamento de req/res. Essa é a camada óbvia.
Mas o Express não funciona sozinho. Ele depende de um conjunto de dependências diretas, pacotes como body-parser, cookie-parser, serve-static, send, path-to-regexp, qs e outros que lidam com funcionalidades essenciais nos bastidores. Cada um desses pacotes possui sua própria árvore de dependências, e cada dependência representa uma superfície de vulnerabilidade em potencial.
Uma instalação típica do Express 4.x inclui cerca de 30 dependências diretas e, quando você executa o comando `npm list` para ter uma visão completa, o número total de pacotes aumenta significativamente. Cada um desses pacotes precisa receber correções quando vulnerabilidades são divulgadas e, no caso de uma versão do Express.js que chegou ao fim da vida útil, muitos deles não receberão essas correções.
O histórico do CVE deixa isso bem claro: o CVE-2024-43799 afetou o pacote `send` (uma dependência do Express), e o CVE-2024-43800 afetou o `serve-static`, ambos divulgados na mesma atualização de segurança de setembro de 2024. Você não estava lidando apenas com uma vulnerabilidade em um único pacote. Estava lidando simultaneamente com um conjunto de vulnerabilidades relacionadas em toda a árvore de dependências.
É isso que torna o fim do ciclo de vida do Express.js realmente complicado. Mesmo que você tenha o código da sua aplicação bem protegido, sua cadeia de dependências pode estar sujeita a explorações ativas de maneiras que o npm audit não detectará no caso de pacotes em fim de vida, pois não há patches para recomendar.
Suas opções quando o Express.js chegar ao fim de sua vida útil
Tudo bem, então a sua versão do Express.js está no fim do ciclo de vida (EOL) ou está prestes a chegar a esse ponto. Quais são as opções realistas que você tem daqui para frente?
Duas delas envolvem complexidade, custo e risco significativos. A terceira, o suporte estendido, é a opção que realmente resolve o problema sem causar interrupções, e é aquela que a maioria das equipes gostaria de ter descoberto mais cedo.
Opção 1: Atualizar para o Express 5
Essa é a resposta “oficial”. Faça a migração para o Express v5, instale os patches de segurança mais recentes, aproveite as melhorias e todos ficarão satisfeitos.
E, para deixar claro: o Express 5 é realmente melhor. Os erros de async/await agora são encaminhados automaticamente para o middleware de tratamento de erros, não sendo mais necessário envolver manualmente cada rota assíncrona em try/catch. A biblioteca path-to-regexp foi atualizada para a versão 8.x, corrigindo uma classe de vulnerabilidades ReDoS que afetavam o roteamento nas versões anteriores. O suporte à compactação Brotli está integrado. A qualidade geral da base de código melhorou significativamente após uma década de trabalho incremental.
Mas eis o que “atualizar para o Express 5” realmente significa para um aplicativo de produção desenvolvido na v4:
- Node.js 18 (mínimo): Se você estiver usando versões mais antigas do Node.js, precisará primeiro atualizar o ambiente de execução, o que traz suas próprias implicações de compatibilidade.
- Alterações na sintaxe das rotas: As rotas com caracteres curinga foram alteradas de app.get(‘*’) para padrões nomeados explicitamente. Se você tiver dezenas de rotas genéricas, todas elas precisam ser atualizadas.
- Métodos obsoletos removidos: app.del() foi removido (use app.delete()). req.param() não existe mais. res.send(body, status) A assinatura foi removida. Nenhuma dessas alterações é catastrófica por si só, mas todas precisam ser identificadas e corrigidas.
- Alterações no comportamento do body-parser: O opção “extended” agora tem como padrão false na análise de dados codificados por URL. Aplicativos que dependem da análise de objetos aninhados por meio de req.body podem apresentar um comportamento diferente.
- Comportamento do middleware assíncrono: Os manipuladores de rota que antes retornavam valores sem aviso prévio agora participam do tratamento de erros do Express. Isso pode alterar o comportamento do middleware existente de maneiras sutis.
A equipe do Express publicou codemods que automatizam algumas dessas alterações, o que é realmente útil. Para um projeto pequeno com boa cobertura de testes, isso pode ser feito rapidamente. Mas e para uma API grande, com centenas de rotas, cadeias complexas de middleware e anos de padrões acumulados? É preciso um planejamento cuidadoso, testes abrangentes e há um risco real de regressões sutis que só vêm à tona sob carga de produção.
Opção 2: Migração para estruturas alternativas
Algumas equipes, ao se depararem com a situação do fim do ciclo de vida (EOL) do Express.js, pensam: “Sabe de uma coisa? Talvez essa seja a nossa chance.”
Fastify, Koa, Hapi, NestJS para aplicativos maiores, ou até mesmo optar por não usar nenhuma estrutura, utilizando apenas o HTTP nativo do Node.js: há alternativas reais, cada uma com argumentos convincentes. O Fastify, em particular, tem atraído bastante atenção por seu desempenho e pela validação de esquema integrada. Vale a pena considerar o NestJS se você estiver migrando para um desenvolvimento que prioriza o TypeScript, com uma estrutura bem definida.
Mas não vamos nos iludir sobre o que uma migração de framework realmente envolve. Você não está apenas trocando uma dependência. Você está reescrevendo todas as rotas e middlewares usando a API do novo framework, refatorando o tratamento de erros — que varia significativamente entre os frameworks —, treinar novamente sua equipe em convenções e documentação diferentes, atualizando sua pilha de testes — que provavelmente contém helpers específicos do Express — e verificando se todos os middlewares de terceiros dos quais você depende têm equivalentes ou funcionam com o seu novo framework.
A flexibilidade e os benefícios a longo prazo podem, sem dúvida, justificar esse trabalho na situação certa. No entanto, o prazo e o custo tendem a ficar bem acima das estimativas iniciais, e manter o sistema existente enquanto se desenvolve o substituto gera uma sobrecarga administrativa própria.
Você também pode ler nosso guia completo sobre o fim da vida útil (EOL) do Fastify para entender as datas do ciclo de vida e os riscos, caso esteja pensando em migrar para o Fastify.
Opção 3: Suporte estendido de terceiros
Aqui está a opção que muitas equipes nem sabem que existe: suporte de segurança estendido oferecido por empresas especializadas exatamente nesse problema.
A TuxCare oferece suporte contínuo ao ciclo de vida para versões do Express.js que chegaram ao fim da vida útil (EOL). Em vez de forçar uma migração para a qual você ainda não está preparado ou deixar suas APIs expostas enquanto planeja essa migração, você continua utilizando sua versão atual do Express.js, mas com cobertura contínua de patches de segurança.
A ideia é simples: você ganha tempo e controle. Tempo para planejar uma migração adequada nos seus próprios termos. Controle sobre seu cronograma de atualizações, em vez de ficar à mercê do prazo de uma auditoria de segurança ou da divulgação de uma vulnerabilidade CVE que o obrigue a agir.
O verdadeiro custo de apressar uma atualização de fim de vida útil (EOL) do Express.js
Vamos falar sobre o que realmente acontece quando as equipes migram às pressas uma API de produção porque os alertas de fim de vida útil (EOL) do Express.js finalmente atingiram um nível crítico no painel de segurança.
Quando essa atualização é encaixotada em um prazo irrealista porque a conformidade está pressionando, coisas previsíveis dão errado:
- Aumento da carga de suporte: Os pequenos bugs que não apareceram nos testes começam a surgir na produção. Mudanças no comportamento do middleware causam falhas intermitentes. Sua equipe de suporte fica sobrecarregada com tickets, metade dos quais está relacionada à migração.
- Instabilidade do sistema: Talvez uma alteração no comportamento de correspondência de rotas comprometa a integração com um serviço posterior. Talvez uma alteração no padrão do analisador de corpo faça com que um endpoint específico rejeite silenciosamente cargas úteis que antes eram válidas. Esses são os problemas que geram alertas às 3 da manhã e SLAs muito insatisfatórios.
- Acúmulo de dívida técnica: Na pressa para garantir a conformidade, as equipes começam a tomar atalhos. “Vamos refatorar isso direito mais tarde” se torna uma solução provisória permanente. Seis meses após a migração, você se depara com uma base de código que, tecnicamente, está no Express 5, mas repleta de shims de compatibilidade e limpezas adiadas.
- Excedentes orçamentários: A estimativa original era de três semanas. Oito semanas depois, você ainda está lidando com regressões. E aquele prestador de serviços que você contratou para a migração? Continua cobrando horas. Os recursos foram adiados. O custo de oportunidade é real e substancial.
Não estou dizendo para não fazer a atualização. A atualização é, sem dúvida, a solução certa a longo prazo. O que estou dizendo é que atualizações apressadas, motivadas pela pressão de conformidade, são uma forma específica e previsível de fracasso, e que a afirmação “temos que fazer isso agora” raramente é verdadeira quando há outras opções disponíveis.
A solução fácil: suporte contínuo ao longo do ciclo de vida para versões do Express.js que chegaram ao fim da vida útil
A TuxCare vem fazendo isso há mais de uma década, fornecendo patches de segurança para sistemas operacionais, ambientes de execução, bibliotecas e, agora, frameworks de aplicativos que chegaram ao fim de vida útil. A empresa já distribuiu mais de 220.000 patches de segurança em todo o ecossistema de código aberto. Quando afirmam que sabem como manter o software em fim de vida útil seguro em escala empresarial, não estão falando de uma capacidade teórica. Eles já fizeram isso.
O que diferencia a abordagem da TuxCare
Cobertura completa da árvore de dependências: A TuxCare não se limita a aplicar patches apenas ao Express; ela cobre suas dependências diretas e as dependências transitivas abaixo delas, tudo sem custo adicional. Lembra daquela extensa cadeia de body-parser, serve-static, send, path-to-regexp e tudo o mais? A TuxCare cuida disso. Você não está apenas protegendo a estrutura; está protegendo toda a superfície de dependências do Express.js.
Processo refinado e automatizado de aplicação de patches: O processo da TuxCare combina automação avançada com validação especializada. Eles monitoram o NVD, os alertas de segurança dos fornecedores, os feeds de segurança do GitHub e todos os locais onde vulnerabilidades de fim de vida útil (EOL) do Express.js são divulgadas. Quando um CVE é publicado, eles utilizam ferramentas algorítmicas e automação assistida por IA para aplicar correções de segurança retroativas; em seguida, especialistas em segurança validam cada patch antes de sua distribuição. Cada atualização passa por testes de integridade, funcionalidade e regressão antes de chegar aos seus repositórios. Quer ver exatamente como isso funciona? Confira o white paper técnico da TuxCare sobre seu Processo de Correção de Código Aberto.
Integração perfeita: Os patches da TuxCare se integram diretamente ao seu fluxo de trabalho npm existente. Se você estiver usando o npm ou o Yarn, os pacotes ELS simplesmente funcionam. Você não precisa reformular seu pipeline de CI/CD nem treinar novamente sua equipe. Você continua usando exatamente o que já tem configurado.
Resposta rápida garantida por SLA: Quando novas vulnerabilidades do Express.js em fim de vida útil (EOL) são divulgadas, a TuxCare fornece patches dentro de um prazo garantido, respaldado por acordos de nível de serviço (SLA) efetivos. Você não precisa ficar torcendo para que alguém, eventualmente, faça o backport de uma correção. Você recebe atualizações de segurança prontas para produção, com as quais pode se planejar.
Custo-benefício: Eis o que mais surpreende a maioria das equipes em relação ao suporte estendido: ele costuma ser significativamente mais barato do que as alternativas. Quando você soma honestamente o tempo de engenharia com base nas taxas horárias reais, os ciclos de teste, os honorários dos prestadores de serviços, o possível tempo de inatividade, o atraso no lançamento de recursos e o custo de oportunidade, o ELS normalmente custa apenas uma fração desse total. Além disso, você não está sobrecarregando sua equipe com uma migração sob alta pressão.
Conformidade e transparência: Cada versão do TuxCare oferece visibilidade completa sobre o que foi corrigido, quais CVEs foram resolvidos, quais componentes foram modificados e como verificar tudo isso na sua lista de materiais de software (SBOM). É exatamente isso que você precisa para auditorias PCI DSS, revisões SOC 2 e qualquer outra estrutura de conformidade que faça perguntas específicas sobre software em fim de vida (EOL).
Como começar
Se você estiver utilizando versões do Express.js que chegaram ao fim da vida útil (EOL) e quiser saber quais correções estão disponíveis, a TuxCare mantém um rastreador de CVEs em tempo real, onde é possível ver exatamente quais vulnerabilidades foram corrigidas. Verifique vulnerabilidades e correções em tempo real para o Express.
Quer saber tudo sobre as versões compatíveis, preços e implementação? Acesse Suporte de Ciclo de Vida Ilimitado da TuxCare para o Express para obter mais detalhes.
Não deixe que o Express.jscolocar suas APIs em risco
O Express.js teve uma trajetória extraordinária. Ele democratizou o desenvolvimento de JavaScript no backend, está por trás de uma parcela enorme das APIs do mundo e ainda é mantido ativamente, com melhorias na versão 5. Isso não é pouca coisa.
Mas se você estiver executando versões do Express.js cujo ciclo de vida útil (EOL) já chegou ao fim em ambiente de produção — seja a v3, cujo ciclo de vida útil terminou em 2015, ou uma instalação da v4 que está caminhando para a descontinuação —, “ainda está funcionando” não é o mesmo que “ainda é seguro”.
Eis o que você realmente precisa saber: o fim do suporte (EOL) do Express.js não precisa significar pânico. Você tem opções. Você pode planejar uma atualização bem pensada para o Express 5 quando isso realmente fizer sentido para sua equipe e sua base de código. Você pode avaliar frameworks alternativos se houver um motivo arquitetônico concreto para a mudança. Ou você pode utilizar o suporte estendido para manter a segurança e a conformidade enquanto toma essas decisões de acordo com seu próprio cronograma, em vez de seguir o cronograma de uma auditoria de segurança.
As equipes que lidam bem com situações de fim de vida útil (EOL) do Express.js não são necessariamente aquelas com os maiores orçamentos ou as bases de código mais recentes. São aquelas que reconhecem os riscos desde o início, entendem o que realmente têm à disposição e tomam decisões deliberadas, em vez de reativas.
Se o fim do suporte (EOL) do Express.js está em sua agenda no momento, vale a pena conhecer o que a TuxCare oferece. Você pode descobrir que o melhor próximo passo não é se apressar em uma migração para a qual não está preparado, mas sim proteger o que já construiu enquanto planeja a atualização que realmente deseja realizar.
Conheça o Suporte de Ciclo de Vida Ilimitado da TuxCare para software de código aberto para saber como o suporte estendido pode proteger toda a sua pilha de código aberto pelo tempo que você precisar.

