Principais conclusões
- O Commons Collections geralmente é incluído de forma transitiva, portanto, pode estar presente na sua compilação mesmo que ninguém o tenha adicionado.
- Seu pacote de funtores forneceu os elementos básicos para as cadeias de utilitários de desserialização mais conhecidas do Java.
- A migração da versão 3.x para a 4.x implica novas coordenadas, um novo namespace de pacotes e uma quebra deliberada da API.
- O ELS para o Apache Commons Collections aplica correções às versões em fim de vida (EOL) e às suas cadeias de dependências enquanto você planeja a migração.
Se o Apache Commons Collections estiver presente em algum ponto do seu gráfico de dependências Java — o que costuma acontecer no Java corporativo —, vale a pena esclarecer a questão do fim da vida útil antes que um verificador ou um auditor levante essa questão para você.
Essa é a biblioteca por trás de algumas das cadeias de gadgets de desserialização mais famosas do Java. Não porque o Apache tenha incluído um backdoor, mas porque algumas classes do pacote `functors` são serializáveis e utilizam reflexão, e alguém acabou percebendo o que seria possível construir a partir disso. As divulgações de 2015 transformaram um JAR utilitário rotineiro em um problema de dependência que as equipes de segurança tiveram que rastrear em servidores de aplicativos que não controlavam. Este post aborda essa história, o que isso significa para as equipes que ainda utilizam a linha de artefatos mais antiga e qual é o papel do suporte estendido quando a migração não ocorrerá neste trimestre.
Duas linhas de artefatos e por que isso é importante
O Commons Collections existe desde 2001. Ele amplia o Java Collections Framework com estruturas de dados, iteradores, comparadores e utilitários de transformação que o JDK nunca incluiu, e é exatamente por isso que acabou se tornando onipresente. Sua onipresença também é o que tornou seu histórico de segurança tão problemático.
Existem duas linhas de artefatos, e confundir uma com a outra é a principal causa de recomendações equivocadas sobre remediação.
A linha legada é commons-collections:commons-collections, que abrange toda a série 3.x e está disponível no org.apache.commons.collections espaço de nomes de pacotes. A Apache descreve as versões 3.2 e 3.2.1 como compatíveis com o Java 1.2, tendo a versão 3.2.1 sido lançada em 15 de abril de 2008. A versão final, a 3.2.2, foi lançada em novembro de 2015 como uma atualização de segurança e correção de bugs e migrou para o Java 1.3. Sua principal mudança foi desativar, por padrão, a desserialização das classes de funtores inseguras; assim, qualquer tentativa de desserialização gera uma UnsupportedOperationException a menos que alguém defina explicitamente o org.apache.commons.collections.enableUnsafeSerialization definir a propriedade do sistema como “true”. Desde então, nada mais foi lançado na linha 3.x.
A linha atual é org.apache.commons:commons-collections4, e o namespace do pacote foi movido para org.apache.commons.collections4 junto com ele. Ele recebeu um novo groupId e artifactId justamente porque a versão 4.0 nunca teve a intenção de ser compatível com versões anteriores, e essa mudança no namespace é o motivo pelo qual um JAR 3.x e um 4.x podem coexistir no mesmo classpath sem entrar em conflito. A versão 4.0 foi lançada em 27 de novembro de 2013, com genéricos em toda a estrutura e o Java 5 como requisito mínimo. A versão 4.1 veio em seguida, em 28 de novembro de 2015, e concluiu o trabalho iniciado pela 3.2.2, removendo completamente a interface `Serializable` das classes de funtores inseguras, em vez de apenas restringir seu uso. Depois disso, vieram a versão 4.2 em 11 de julho de 2018, a 4.3 em 21 de dezembro de 2018, a 4.4 em 5 de julho de 2019, a 4.5.0 em 19 de abril de 2025 e a versão atual, 4.6.0, em 6 de agosto de 2026. A versão mínima do Java subiu paralelamente, passando do Java 5 em 4,0 para o Java 6 em 4,1 e o Java 7 em 4,2; depois, do Java 8 a partir de 4,3, incluindo a versão 4.6.0.
O Apache não publica um aviso formal de fim de vida útil (EOL) para a versão 3.x; portanto, ninguém vai lhe fornecer um comunicado com data específica para você colar em um ticket. O que você pode afirmar claramente é o seguinte: não há lançamentos da versão 3.x desde novembro de 2015, todo o desenvolvimento ocorre na versão 4.x e, como a 3.2.2 foi a última dessa linha, ninguém deve contar com um backport da versão 3.x do upstream para um problema recém-descoberto.
O que “fim de vida” realmente significa neste contexto
Chega de correções na origem
Para qualquer coisa que seja executada no commons-collections:commons-collections, na prática, a situação é simples. Não houve nenhum novo lançamento da versão 3.x desde a 3.2.2, e a atenção do Apache tem se concentrado na linha 4.x há mais de uma década.
As versões mais antigas da série 4.x encontram-se em uma situação semelhante, embora menos grave. As correções publicadas pelo Apache são incorporadas às versões mais recentes da série 4.x; portanto, no caso de um problema que afete uma versão mais antiga da série 4.x, o caminho normal de correção pelo desenvolvedor original é migrar para a versão atual.
A história do CVE que muitas pessoas interpretam de forma um pouco equivocada
Vale a pena ser preciso nesse ponto, pois o conteúdo digitalizado e os títulos do CVE não coincidem, e essa discrepância já causou muitas reuniões desnecessárias.
O Apache afirma em sua própria página de segurança que nenhum ID CVE foi atribuído à biblioteca Commons Collections para o problema de desserialização de 2015. Os identificadores que todos citam pertencem a produtos derivados. O CVE-2015-7501 foi registrado para os produtos Red Hat JBoss e o CVE-2015-6420 para uma longa lista de produtos da Cisco; ambos receberam classificação de 9,8 (crítico) segundo o CVSS v3 e foram descritos como relacionados à biblioteca Apache Commons Collections, e não como falhas nela. A própria página do Apache aponta para um terceiro, o CVE-2015-4852, referente ao Oracle WebLogic Server.
O mecanismo por trás de todos eles é o mesmo. Várias classes do pacote `functors` são serializáveis e invocam métodos de forma reflexiva, com InvokerTransformer particularmente útil para um invasor, pois invocará um método especificado por meio de reflexão. Basta encadear os gadgets necessários, passar o objeto resultante para um aplicativo que deserialize entradas não confiáveis sem validá-las — desde que essas classes estejam no classpath — e o resultado pode ser a execução de comandos arbitrários com os privilégios do processo da JVM. O Apache indica que as versões afetadas vão da 3.0 à 4.0, com a correção disponível nas versões 3.2.2 e 4.1.
A linha do tempo explica por que o impacto foi tão grande. Gabriel Lawrence e Chris Frohoff apresentaram a técnica na AppSecCali em 28 de janeiro de 2015. Stephen Breen publicou cenários de ataque funcionais contra o WebSphere, o JBoss, o Jenkins, o WebLogic e o OpenNMS em 6 de novembro de 2015. A Apache afirma que sua equipe de segurança não foi informada antes da publicação; assim, as correções foram implementadas poucas semanas após a divulgação pública da exploração, e as equipes descobriram que a biblioteca estava localizada em vários níveis de profundidade nas árvores de dependências, onde não podiam ser alteradas diretamente.
Portanto, quando seu scanner sinaliza um JAR 3.2.1 associado a um CVE cujo título mencione a Cisco, o scanner não está apresentando um erro. Esses registros de alertas associam versões vulneráveis do Commons Collections aos produtos derivados que as incluíram, e o Banco de Dados de Alertas do GitHub registra o mesmo problema em relação ao artefato do Maven como GHSA-6hgm-866r-3cjv. A detecção é válida, mesmo que o CVE contenha o nome de um produto de outra empresa.
Riscos relacionados à conformidade e à auditoria
O Requisito 6.3.3 da norma PCI DSS v4.0.1 exige que as correções para vulnerabilidades classificadas como críticas pela sua organização sejam instaladas no prazo de um mês após o lançamento; todas as demais devem seguir um cronograma definido por você por meio do mesmo processo de classificação de risco descrito no Requisito 6.3.1. A norma PCI DSS não considera automaticamente todas as descobertas do CVSS 7.0 como críticas; portanto, o peso atribuído a uma descoberta do Commons Collections depende da sua classificação documentada e da sua exposição real. A Regra de Segurança da HIPAA funciona de maneira diferente, obrigando as entidades abrangidas e os parceiros comerciais a proteger as informações eletrônicas de saúde protegidas contra ameaças razoavelmente previsíveis — exatamente o tipo de obrigação aberta que um componente em fim de vida (EOL) sem patch torna difícil de defender.
Componentes sem suporte também podem levantar questões sobre os controles de gerenciamento de vulnerabilidades durante uma auditoria SOC 2 Tipo II, e a autorização do FedRAMP traz suas próprias expectativas em relação ao monitoramento contínuo e à correção de falhas. O suporte estendido, por si só, não garante a conformidade de uma organização, mas mantém um fluxo contínuo de patches, de modo que os compromissos de gerenciamento de vulnerabilidades continuem sendo cumpridos enquanto a migração ainda está sendo planejada.
O Problema da Árvore de Dependências
O Commons Collections, por si só, não é o Tangle. O artefato 4.6.0 ocupa muito pouco espaço, com commons-codec 1.22.1 como sua única dependência opcional de compilação e todo o restante restrito aos testes, de modo que sua própria contribuição para o gráfico de dependências de tempo de execução de um consumidor é mínima.
A confusão está do lado do consumidor. Os servidores de aplicativos incluem isso em seus pacotes, as ferramentas de desenvolvimento fornecem isso e as estruturas legadas exigem isso. Executar mvn dependency:tree ao analisar um aplicativo Java corporativo maduro, é bem provável que você encontre um JAR antigo do commons-collections 3.x na saída, incluído por algum projeto cujos mantenedores não atualizam suas declarações de dependências há muito tempo. Cada cópia vulnerável nesse gráfico pode se tornar uma descoberta, pois os scanners percorrem todo o sistema em vez de parar no que você declarou. Se uma determinada cópia conta ou não depende da versão, já que as versões 3.0 a 3.2.1 estão no intervalo afetado, enquanto a 3.2.2 já traz a correção da Apache.
É isso que torna o fim da vida útil (EOL) do Apache Commons Collections um pouco complicado. Trata-se menos de um problema de versão da biblioteca e mais de um problema de alcance e visibilidade; e, quando o próprio componente que utiliza o JAR antigo não recebe mais manutenção, aplicar o patch na biblioteca onde ela realmente está localizada evita o risco de incompatibilidade de forçar uma versão transitiva mais recente em uma cadeia de dependências que ninguém está mantendo.
Quais são suas opções (realistas)?
Migração para o commons-collections4 4.6.0
A solução sustentável a longo prazo é deixar de commons-collections:commons-collections para org.apache.commons:commons-collections4 na versão 4.6.0, o que significa que você está na linha de versão com manutenção ativa.
No entanto, não se trata de um aumento de versão. Trata-se de uma troca de dependências com alterações na API que exigem a revisão de todas as classes que utilizam a biblioteca. Os genéricos foram incorporados em toda a biblioteca, as classes obsoletas da versão 3.x foram removidas, o Buffer a interface foi substituída por java.util.Queue, e as assinaturas de utilitários foram transferidas. Todas as importações precisam ser transferidas para o namespace `collections4`, e qualquer coisa que dependa do comportamento da versão 3.x, especialmente no pacote `functors`, exigirá alterações reais no código para que possa ser compilada.
As equipes que já estão na versão 4.x têm menos trabalho, embora ainda seja necessário ler os registros de alterações de cada versão intermediária e testar o caminho de atualização, em vez de simplesmente avançar às cegas.
Quando o Commons Collections é incorporado de forma transitiva, em vez de diretamente, o caminho de migração passa por aquilo que o está incorporando. Se essas bibliotecas, por sua vez, não forem mantidas, você terá que substituir as versões transitivas e validar a compatibilidade por conta própria, o que é viável, mas não é gratuito nem sempre seguro.
Substituir completamente as coleções do Commons
Algumas equipes encaram a notícia do fim do ciclo de vida (EOL) como uma boa desculpa para questionar se ainda precisam mesmo da biblioteca. As alternativas são realmente boas atualmente, incluindo o Eclipse Collections, os utilitários de coleções do Guava e uma biblioteca padrão que incorporou grande parte do que levou as pessoas a adotarem o Commons Collections inicialmente.
Substituí-lo por completo é um trabalho mais complexo do que atualizá-lo. Cada local de uso precisa de um equivalente, as diferenças comportamentais precisam ser testadas e qualquer coisa construída com funtores ou pipelines de transformação requer atenção individual. Para uma base de código com anos de uso acumulado, esse é um projeto que se estende por vários sprints, não uma resposta a uma descoberta feita na última terça-feira.
Suporte contínuo ao longo do ciclo de vida da TuxCare
O ELS para o Apache Commons Collections garante o fornecimento contínuo de patches de segurança para versões em fim de vida (EOL) com suporte, sem exigir que você execute uma migração que sua equipe ainda não tenha planejado. Atualmente, a cobertura inclui as versões 3.2 e 3.2.1 — vale a pena consultar sobre outras versões. Se você estiver em uma versão com suporte, ela permanece como está, seus fluxos de trabalho existentes não são alterados e os patches continuam chegando à medida que novos problemas surgem.
Essa é a lacuna que o produto se propõe a preencher: o intervalo entre o momento em que uma versão em fim de vida útil (EOL) passa a ser um problema em um relatório e o momento em que uma migração planejada e testada é efetivamente concluída.
Por que a pressa na atualização acaba saindo pela culatra
A pressão é real. Os scanners a revelam, os auditores questionam o plano e os prazos de conformidade não mudam. As equipes que lidam bem com isso são aquelas que conseguem distinguir entre responder a um risco e criar um novo.
O que a migração realmente envolve
A migração da versão 3.x implica atualizar as coordenadas dos artefatos em todos os locais onde a dependência é declarada ou gerenciada centralmente, reescrever as importações para o novo namespace do pacote e, em seguida, revisar os usos das coleções quanto às alterações de segurança de tipos e da API que vieram com a API generificada da versão 4.x. As classes removidas precisam ser substituídas ou reescritas. O código que utiliza o pacote de funtores da versão 3.x deve ser avaliado caso a caso, já que parte dele se mapeia perfeitamente para as interfaces funcionais do Java 8, enquanto outra parte requer uma reescrita específica para o projeto.
Para qualquer código que processe dados Java serializados, é necessário compreender e testar a diferença entre o modelo 3.2.2 — no qual a deserialização por funtores não seguros está desativada, a menos que uma propriedade do sistema a ative — e o modelo 4.1 — no qual essas classes não são serializáveis de forma alguma — antes que o código entre em produção.
O que dá errado quando o arquivo é compactado
Erros de compilação são a parte mais fácil, pois as APIs que foram renomeadas ou removidas se revelam imediatamente. Os erros interessantes são mais sutis. Problemas de compatibilidade binária podem surgir como NoSuchMethodError em tempo de execução, enquanto consultas reflexivas malsucedidas podem gerar NoSuchMethodException em vez disso, e não há garantia de que qualquer uma delas seja detectada apenas durante a compilação.
As mudanças de comportamento são ainda piores. MultiValueMap foi descontinuado na versão 4.1 em favor do mais recente MultiValuedMap interface, BeanMap foi lançado na versão 4.0, com o equivalente transferido para o Commons BeanUtils, e na versão 4.6.0 todo o recurso foi considerado obsoleto Bag família a favor de MultiSet. Um código que dependa da semântica antiga pode ser aprovado em um conjunto de testes e, posteriormente, apresentar falhas ao lidar com um formato específico de dados em produção.
Depois, há os resquícios. Os shims de compatibilidade criados para cumprir um prazo acabam se tornando permanentes, e o “vamos resolver isso depois” vira um ticket para outra pessoa. Some-se a isso o tempo de engenharia de emergência, o atraso no trabalho do roadmap e os engenheiros seniores depurando em produção em vez de lançar o produto, e uma migração apressada pode facilmente custar mais do que o prazo que deveria cumprir. O problema não é resolvido dessa forma. Ele é adiado, com um custo adicional.
Como funciona o TuxCare ELS para o Apache Commons Collections
A TuxCare conta com quinze anos de experiência no desenvolvimento de patches para software de código aberto e já disponibilizou mais de 420.000 patches para sistemas operacionais, ambientes de execução, frameworks e bibliotecas. O ELS para o Apache Commons Collections segue esse mesmo processo.
Cobertura da cadeia de dependências incluída
A cobertura abrange tanto as dependências diretas quanto as transitivas, sem custo adicional. Os scanners não param no artefato de nível superior, e a aplicação de correções também não.
Como os remendos são feitos
O rastreamento de CVEs é realizado continuamente com base no NVD, em alertas de fornecedores, nos Alertas de Segurança do GitHub e em outras fontes. Quando algo é identificado, ferramentas algorítmicas e automação assistida por IA auxiliam os engenheiros no backport; os engenheiros de segurança validam o resultado; e cada compilação passa por testes de integridade, funcionalidade e regressão antes de chegar a um repositório. Os patches são enviados assinados a partir de repositórios hospedados pela TuxCare, e o white paper “Open Source Patching Process” traz todos os detalhes caso você queira conhecer o pipeline.
Como se adaptar ao seu tipo físico
Quer você utilize o Commons Collections via Maven ou Gradle, a principal mudança consiste em direcionar sua compilação para o repositório da TuxCare e confirmar que a resolução de dependências selecione o artefato corrigido. Seu pipeline, sua CI/CD e a forma como sua equipe trabalha permanecem inalterados.
Com que rapidez as atualizações chegam
As vulnerabilidades de alto risco e risco crítico que afetam versões em fim de vida útil (EOL) com suporte, ou seja, com pontuação CVSS 7,0 ou superior, têm um prazo de 14 dias a partir da divulgação pública; para as de risco médio, o prazo é de 60 dias, e para as de baixo risco, de 90 dias. O suporte para triagem de vulnerabilidades e solução de problemas está disponível 24 horas por dia, 7 dias por semana, 365 dias por ano.
Visibilidade para os auditores
O rastreador de CVEs da TuxCare mostra quais vulnerabilidades foram identificadas e corrigidas nos produtos suportados e em suas cadeias de dependências. Isso oferece às equipes de segurança e conformidade evidências mais claras do que realmente foi corrigido do que apenas o resultado de um scanner em um determinado momento.
Não deixe que uma constatação de fim de vida útil (EOL) se transforme em um incidente
Uma versão do EOL Commons Collections, por si só, não causa nenhum problema. O que ela faz é deixar você sem uma versão 3.x de origem com manutenção para recorrer quando surgir a próxima vulnerabilidade que afete essa versão, ou quando classes que ainda estão no seu classpath se tornarem úteis em uma cadeia de desserialização recém-divulgada.
Se o seu desafio atual é manter a segurança de uma versão mais antiga do Commons Collections enquanto planeja a migração, confira o que o Suporte de Ciclo de Vida Ilimitado da TuxCare para Software de Código Aberto oferece para o restante da sua pilha de sistemas.
