Segurança do Maven Central após o caso do sósia de Jackson

Os patches do php2shell (CVE-2026-109618 e CVE-2026-109619) para o PHP em fim de vida (EOL) já estão disponíveis. Como as respostas do atendimento de vendas estão mais demoradas do que o normal devido à alta demanda, a maneira mais rápida de obter os pacotes corrigidos é adquirir o ELS para Runtimes on-line (abre em uma nova aba). Leia as perguntas frequentes sobre os patches

Vá direto para um resumo gerado por IA desta postagem do blog

  • Resuma esta postagem com o Perplexity
  • Resuma esta postagem com o Gemini

Principais conclusões

  • Um pacote publicado em um segmento de namespace diferente do Jackson disponibilizou o Cobalt Strike a partir do Maven Central em dezembro de 2025; não houve nenhum CVE envolvido.
  • O Maven Central verifica o controle do domínio ou da conta de hospedagem de um namespace, e não qualquer relação com o projeto ao qual ele se assemelha.
  • Os artefatos publicados pelo Maven Central contêm assinaturas PGP, e o Maven não as verifica por padrão.
  • Um pacote npm comprometido chegou automaticamente ao Maven Central por meio do espelhamento do mvnpm em novembro de 2025.

A maior parte do debate sobre a cadeia de suprimentos do Java, desde o Log4Shell, tem girado em torno de um tipo específico de problema: uma vulnerabilidade presente em código legítimo. Então, em dezembro de 2025, surgiu algo diferente. Um ataque de falsificação de namespace colocou um carregador do Cobalt Strike no Maven Central, em coordenadas que substituíam um único segmento das coordenadas reais do Jackson.

Nada foi explorado. Nenhuma vulnerabilidade esteve envolvida. Alguém registrou um namespace, publicou um artefato e esperou que as coordenadas erradas fossem copiadas.

A segurança do Maven Central não se resume apenas à falha na verificação de assinaturas, como a maioria das pessoas imagina. Trata-se também de um problema de namespace, e a maioria das ferramentas Java não detecta nenhum dos dois.

O que realmente aconteceu com o pacote falso do Jackson

A mecânica é simples o suficiente para ser explicada em uma única frase, e é exatamente por isso que funcionou.

O Jackson 2.x é publicado sob com.fasterxml.jackson.core:jackson-databind. A Aikido Security, que identificou o pacote em 25 de dezembro, documentou o artefato malicioso como org.fasterxml.jackson.core com o mesmo jackson-databind artifactId, de modo que toda a sequência de coordenadas estava deslocada em três caracteres. A nomenclatura de domínio reverso deveria evitar isso e, em si, cumpriu o que prometia. O Maven Central confirmou que o editor controlava um domínio que correspondia ao namespace. Esse domínio era fasterxml.org, registrado pela GoDaddy em 17 de dezembro de 2025, oito dias antes da análise, e praticamente idêntico ao verdadeiro fasterxml.com. A verificação de propriedade funcionou corretamente. Só que verificou a coisa errada.

As coordenadas legítimas de `com.fasterxml.jackson.core` aparecem ao lado das coordenadas maliciosas de `org.fasterxml.jackson.core`, que se parecem com as primeiras

A carga útil não era um ataque rápido do tipo “invadir e roubar”. Após a desofuscação, verificou-se que a classe era uma configuração automática falsa do Spring Boot, e os pesquisadores que a examinaram descobriu um projeto em várias etapas: Strings de configuração criptografadas com AES, desbloqueadas por meio de uma chave codificada, um @Configuration classe anotada com @ConditionalOnClass(ApplicationRunner.class) para que o Spring o registrasse e executasse a carga útil assim que o contexto da aplicação fosse carregado, um marcador de persistência disfarçado como um arquivo do IntelliJ e a identificação da plataforma antes que qualquer tráfego de comando e controle fosse enviado. Os hosts do Windows baixaram svchosts.exe, um “typosquat” do site original svchost.exe processo. Os hosts com Linux e macOS receberam binários que praticamente todos os mecanismos de varredura do VirusTotal identificaram como beacons do Cobalt Strike, a estrutura comercial de red team cujas versões vazadas são amplamente utilizadas por operadores de ransomware e grupos APT.

Assim que o pacote foi denunciado, o Maven Central o retirou em cerca de noventa minutos, o que é uma resposta rápida para um registro público. Essa velocidade não ajuda os projetos que o utilizaram enquanto ele estava ativo, e não diz nada sobre como uma versão mais discreta do mesmo truque se sairia. Um beacon do Cobalt Strike que chama muita atenção acaba sendo descoberto. Algo criado para permanecer inativo e extrair dados lentamente poderia permanecer no sistema por muito mais tempo.

Como funciona a suplantação de namespace no Maven Central

O Maven identifica as dependências por meio de três coordenadas: groupId, artifactId e version.

A prática comum é que o `groupId` seja um domínio invertido controlado pelo editor, e o Maven Central garante isso no momento do registro, exigindo comprovação de controle sobre o domínio ou sobre a conta de hospedagem de código vinculada a ele. Essa verificação é real e funciona exatamente como foi projetada.

Simplesmente não funciona da maneira que as pessoas imaginam. Comprovar o controle de um domínio não indica, de forma alguma, se o proprietário tem alguma relação com o projeto ao qual o nome de domínio se assemelha. Isso apenas confirma o controle do domínio, e um domínio com nome semelhante custa apenas alguns dólares.

O namespace real de Jackson ao lado de três padrões que qualquer pessoa poderia registrar, nenhum deles sendo o utilizado aqui.

Padrão de coordenadas Parece legítimo porque O que, na verdade, é verificado
com.fasterxml.jackson.core É o namespace real Controle de domínios pela FasterXML
io.fasterxml.jackson O domínio inverso, .io, é comum para software de código aberto (OSS) O controle do domínio pertence a quem o comprou
com.fasterxml-jackson.core Um hífen; à primeira vista, a leitura é idêntica O controle do domínio pertence a quem o comprou
org.jackson.databind Corresponde ao nome do projeto O controle do domínio pertence a quem o comprou

O io.fasterxml.jackson, com.fasterxml-jackson.core, e org.jackson.databind Todas as variantes são acessíveis de forma legítima, sem que nada seja comprometido em nenhum ponto. O incidente envolvendo Jackson utilizou uma versão mais restrita da mesma ideia: não um hífen nem um TLD diferente, mas a troca de um único segmento de nível superior, de “com” para “org”, combinada com um domínio registrado especificamente para que essa troca fosse aprovada na verificação.

As coordenadas tendem a ser copiadas de respostas do Stack Overflow, posts de blogs e trechos gerados por IA, em vez de serem digitadas de memória, o que é uma das razões pelas quais isso é mais difícil de detectar em Java do que seria com pacotes npm. Um desenvolvedor que já instalou o axios cinquenta vezes percebe “axois” imediatamente. Quase ninguém tem o `groupId` do Jackson memorizado, e menos ainda perceberiam um segmento trocado em uma sequência de quarenta caracteres que estão colando, em vez de lendo.

Copiar coordenadas de uma página de resultados de pesquisa, em vez de da própria documentação do projeto, cria mais uma possibilidade de confusão com os namespaces. Vale a pena abandonar esse hábito, independentemente de como esse incidente específico tenha se desenrolado.

A falha de segurança no Maven Central que ninguém verifica

Essa é a parte que surpreende os desenvolvedores Java que não analisaram a questão com atenção, e trata-se de um problema distinto daquele mencionado acima.

O Maven Central não aceita uma versão sem uma assinatura PGP. Todo artefato publicado por meio do Central é acompanhado de uma .asc arquivo ao lado dele, além das somas de verificação, e os requisitos de publicação são mais rigorosos do que os do npm ou do PyPI. Esse é um verdadeiro ponto forte.

Por padrão, o Maven não verifica essas assinaturas.

Correr mvn install em um projeto com duzentas dependências transitivas, o Maven baixa duzentos JARs e compara as somas de verificação associadas a eles. Por padrão, uma discrepância gera apenas um aviso; para que a compilação seja interrompida devido a uma delas, é necessário -C, ou um checksumPolicy de falha no repositório. De qualquer forma, o .asc Os arquivos que estão ao lado desses JARs nunca são alterados, a menos que um plug-in os solicite.

A validação da soma de verificação e a verificação da assinatura são tratadas como se fossem intercambiáveis, mas não são. Uma soma de verificação confirma que o arquivo recebido corresponde ao arquivo que o repositório está disponibilizando. Uma assinatura válida comprova que o artefato foi assinado com uma chave privada específica, e é necessário um mapeamento de chaves confiável para associar essa chave a um editor digno de confiança. O Maven realiza a primeira verificação por padrão e ignora completamente a segunda.

O Maven verifica as somas de verificação por padrão, mas mantém a verificação da assinatura PGP desativada

Isso é importante para determinar o que teria ou não ajudado neste caso. O invasor controlava o site fasterxml.org e podia assinar com sua própria chave; portanto, a verificação da assinatura também teria sido aprovada no pacote malicioso. A verificação da assinatura comprova que um artefato não sofreu alterações desde que foi assinado pelo detentor daquela chave. Ela não indica se o editor é realmente quem o namespace sugere. Dois problemas, duas soluções.

O Gradle está à frente do Maven nesse aspecto, e a maioria das equipes ainda não o adotou.

./gradlew --write-verification-metadata sha256,pgp help

Isso inicializa um verification-metadata.xml arquivo a partir do que quer que o Gradle resolva, e o bootstrap é a parte pela qual vale a pena reduzir a velocidade. Ele é deliberadamente otimista. Chaves que passam na verificação são adicionadas automaticamente à lista de confiáveis; artefatos sem assinatura utilizável recorrem às somas de verificação; e qualquer item já comprometido em sua árvore de arquivos é aprovado durante o processo. Leia as somas de verificação e as chaves confiáveis geradas antes de fazer o commit do arquivo. Uma vez que essa linha de base tenha sido revisada, o Gradle reprova a compilação em qualquer item que deixe de corresponder, o que constitui um controle rigoroso e não representa um grande esforço em um projeto simples.

O Maven não possui equivalente no núcleo. A verificação requer um plug-in.

mvn org.simplify4u.plugins:pgpverify-maven-plugin:1.19.1:check

Isso verifica as assinaturas de dependência e pode aceitar um mapa de chaves explícito, de modo que apenas as chaves de assinatura que você indicar serão consideradas confiáveis. Funciona, e não é o que vem por padrão.

O problema “artefato versus código-fonte” está na base desses dois controles, pois um JAR é um produto da compilação e nada o obriga a corresponder ao repositório de código-fonte ao qual um projeto está vinculado. Um scanner que lê o binário publicado vê exatamente o que o editor decidiu colocar ali, seja ele assinado ou não. Recompilar a partir do código-fonte verificado é o que oferece uma garantia independente do que foi incluído em um artefato, em vez de confiar no binário do editor, e o SecureChain para Java foi desenvolvido exatamente com base nessa premissa.

O MavenGate e o problema das coordenadas abandonadas

O MavenGate, publicado por pesquisadores da Oversecured em janeiro de 2024, descreveu um caminho diferente para um resultado semelhante, e pode-se argumentar que esse é o mais preocupante, pois não requer nenhuma suplantação de identidade.

A técnica tem como alvo dependências abandonadas. Uma biblioteca publicada há anos sob com.oldcompany.util está presente em milhares de árvores de dependências. A empresa fecha as portas, o domínio expira e ninguém percebe, porque o artefato ainda é resolvido perfeitamente a partir do Maven Central.

O que acontece a seguir não é tão automático quanto parece. Quando nenhuma conta gerencia esse groupId em um determinado repositório, quem quer que seja o atual proprietário do domínio pode reivindicá-lo por meio de um registro TXT no DNS. Quando o groupId já está registrado, assumir o controle significa convencer a equipe de suporte desse repositório a transferir o acesso, e a Oversecured afirmou claramente que não possuía informações sobre como essas transferências funcionam. Grande parte do risco também vem de projetos que se estendem por vários repositórios, nos quais uma versão maliciosa introduzida em outro ponto da lista ainda chega sob coordenadas nas quais a compilação já confia. Projetos que utilizam intervalos de versão, ou que atualizam para a versão do invasor, acabam adotando-a sem nunca perceber um nome desconhecido.

As quatro etapas de uma apropriação de namespace abandonado no MavenGate

É mais fácil determinar a magnitude do problema do que a mecânica por trás dele. A Oversecured converteu os groupIds do Maven Central em domínios e verificou quais deles podiam ser simplesmente comprados; 3.710 dos 26.163 domínios (14,18%) estavam disponíveis para compra. Ampliando essa análise para os namespaces apoiados pelo GitHub e os repositórios privados que os pesquisadores conseguiram encontrar, 18,18% de um conjunto de dados com 33.938 identificadores pareciam estar expostos.

A Sonatype questionou a viabilidade do ataque, considerando a automação existente; em seguida, desativou contas vinculadas a domínios vencidos, reforçou a verificação de namespaces e corrigiu uma regressão na validação de chaves públicas que havia permitido a passagem de artefatos assinados com chaves que nunca foram publicadas em lugar algum. A resposta da Oversecured foi que nenhum registro isoladamente pode resolver isso, pois o ataque atinge projetos que fazem resolução a partir de vários repositórios públicos ao mesmo tempo, e que o máximo que qualquer proprietário de repositório pode fazer é recusar reivindicações automáticas sobre namespaces já sinalizados como vulneráveis.

A política padrão do Maven Central mantém as versões publicadas imutáveis; portanto, uma versão não pode ser modificada ou retirada discretamente por seu editor, e retiradas por motivos de segurança, como a do Jackson, constituem uma exceção restrita. Isso é útil para a reprodutibilidade. Significa também que dependências abandonadas permanecem resolvíveis e continuam localizadas nas camadas mais profundas das árvores de dependências muito tempo depois que o domínio ou a conta por trás do namespace deixou de ser mantido, parecendo idênticas às dependências ativas quando vistas de dentro de um pom.xml.

O que acontece com essas bibliotecas quando surge um CVE é uma questão para a qual não há uma resposta satisfatória. Não há uma versão corrigida para a qual se possa atualizar, e incluir uma biblioteca Java relevante para a segurança em seu próprio repositório significa que sua equipe agora é responsável por seus CVEs, independentemente de haver ou não pessoal designado para isso.

Como um pacote npm comprometido chegou ao Maven Central

O que a maioria das equipes de Java não percebe é que isso pode acontecer sem que ninguém da equipe precise se envolver com o npm.

Em novembro de 2025, a segunda onda da O worm Shai-Hulud do npm chegou ao Maven Central por meio do espelhamento automatizado do mvnpm. O mvnpm republica pacotes do npm como artefatos do Maven para que projetos web em Java possam baixar bibliotecas de front-end por meio de sua compilação normal, sem a necessidade de uma cadeia de ferramentas separada para JavaScript. O espelhamento é automatizado, e novas versões do npm são sincronizadas assim que são publicadas — esse é exatamente o objetivo da ferramenta e também a maneira pela qual o pacote comprometido conseguiu passar. Uma versão maliciosa do npm posthog-node O pacote foi recompilado no Maven Central como org.mvnpm:posthog-node:4.18.1, com o mesmo setup_bun.js carregador e bun_environment.js carga útil como o Campanha Shai-Hulud no npm.

A Socket relatou o artefato, e o Maven Central confirmou que a versão comprometida havia sido gerada pelo processo automatizado do mvnpm e removeu todas as cópias espelhadas ainda no mesmo dia. O PostHog não publica nada no Maven. Não há evidências de que o comportamento de autopropagação do worm tenha se espalhado dentro do ecossistema do Maven; há apenas aquele único artefato espelhado. Essa distinção é importante para avaliar até que ponto devemos levar isso a sério como um padrão real na cadeia de suprimentos do Maven, em vez de um caso isolado. Foi real e automático, e nenhum mantenedor de Java precisou republicar nada para que uma versão comprometida do npm ficasse disponível para compilações em Java, mas ela não se comportou como um worm depois que chegou lá.

O que isso mostra é que o espelhamento automático altera um limite de confiança sem que ninguém tenha decidido alterá-lo. Uma equipe de Java que nunca tenha trabalhado com o npm pode acabar executando um pacote npm comprometido porque um serviço de ponte o converteu em um JAR em seu nome.

Caminho para uma compilação Java Exige que a equipe utilize o npm Visível no pom.xml
Dependência direta do npm por meio de uma cadeia de ferramentas JS Sim Não
Artefato npm espelhado a partir de um serviço de ponte Não Sim, como um JAR comum
Dependência transitiva em Java que obtém um artefato espelhado Não Somente sob dependency:tree

Verifique diretamente o caminho transitivo, em vez de tentar deduzir o que deveria estar lá. Descubra o que realmente está na sua árvore.

mvn dependency:tree -DoutputFile=deps.txt

Então leia isso. Um serviço Spring de médio porte pode resolver facilmente várias centenas de artefatos a partir de algumas dezenas de dependências declaradas. Os pacotes espelhados aparecem nessa saída, sob org.mvnpm coordenadas, o que é uma pista válida, desde que alguém da equipe saiba que “namespace” se refere ao código do npm reempacotado para o Maven.

O que alterar na sua compilação neste mês

Comece com a ferramenta de compilação que você já estiver usando, pois os dois métodos exigem esforços diferentes. O Gradle pode iniciar rapidamente a verificação de dependências com --write-verification-metadata sha256,pgp, então basta revisar os hashes e as chaves gerados antes que o arquivo seja confirmado. O Maven não possui um equivalente nativo, o que significa que é preciso adicionar um plug-in e definir versões fixas em pluginManagement, o que exige mais preparação, mas ainda assim é uma tarefa de uma semana, e não de um trimestre.

Então, analise o hábito que, na verdade, permitiu que o pacote Jackson fosse aceito. As coordenadas são copiadas de onde quer que sejam encontradas, em vez de serem verificadas em relação à documentação do próprio projeto, e isso é mais fácil de corrigir com uma regra do que com uma ferramenta. Verifique qualquer groupId que sua equipe ainda não tenha usado antes, comparando-o com as coordenadas no repositório oficial ou na documentação do projeto, antes que ele chegue nem perto de um pom.xml, especialmente qualquer coisa extraída de um resultado de pesquisa ou de um trecho gerado por IA.

Dependências abandonadas exigem um tipo diferente de avaliação, e o MavenGate é o motivo disso. Um artefato sem versões recentes e sem mantenedor ativo é um candidato à aquisição, independentemente de ter ou não um CVE aberto no momento, pois o risco não está no código, mas sim no fato de ainda haver alguém controlando o domínio ou a conta por trás desse namespace.

Um projeto Gradle iniciado nos últimos dois anos pode adotar a verificação em um dia. Uma compilação Maven multimódulo com dez anos de idade, com um POM pai personalizado e quarenta plug-ins, é um assunto mais complexo, e o esforço de implementação realmente difere bastante entre os dois.

Onde o SecureChain se encaixa

O Maven Central verifica a propriedade do namespace na entrada, e o Maven compara as somas de verificação do repositório na saída. Nada no caminho padrão confirma que o binário que você resolve corresponde ao que o projeto realmente compilou. O SecureChain para Java substitui esse caminho de resolução, recompilando cada pacote a partir de código-fonte verificado, filtrando comportamentos maliciosos antes que eles cheguem à sua compilação e aplicando correções continuamente, inclusive após o término do suporte do desenvolvedor original. Seu fluxo de trabalho existente do Maven ou Gradle permanece como está — basta direcioná-lo para a TuxCare e continuar compilando.

Veja o que o SecureChain for OSS abrange ou inscreva-se no boletim informativo para receber análises detalhadas de incidentes como esta assim que elas ocorrerem.

Perguntas frequentes

O que é a suplantação de namespace no Maven Central?

Publicar um artefato com um `groupId` criado para se assemelhar ao namespace de um projeto legítimo. O Maven Central verifica se o editor controla o domínio ou a conta de hospedagem correspondente, o que confirma o controle sobre esse namespace, mas não indica nenhuma relação com o projeto que está sendo imitado.

O Maven verifica assinaturas PGP?

Não por padrão. O Maven Central exige assinaturas PGP nos artefatos publicados, e o Maven compara as somas de verificação do repositório, mas não verifica essas assinaturas nem suas correspondências com chaves confiáveis por padrão. A verificação requer um plug-in como o pgpverify-maven-plugin.

Como faço para habilitar a verificação de dependências no Gradle?

Correr ./gradlew --write-verification-metadata sha256,pgp help para inicializar um verification-metadata.xml arquivo, verifique as somas de verificação e as chaves confiáveis geradas e, em seguida, confirme essa linha de base. Depois disso, o Gradle interrompe a compilação de qualquer artefato cuja soma de verificação ou assinatura deixe de corresponder.

O que é o MavenGate?

Uma técnica de apropriação, divulgada por pesquisadores da Oversecured em janeiro de 2024, que tem como alvo dependências abandonadas. Quem adquirir o domínio ou a conta expirada associada a um groupId antigo poderá reivindicar esse namespace em um repositório onde não haja nenhum gerenciamento, ou tentar obter acesso a um registro existente; projetos que fazem resolução em vários repositórios podem, então, aceitar artefatos maliciosos sob coordenadas familiares.

Um pacote npm comprometido pode afetar um projeto Java?

Sim. Serviços de ponte que republicam automaticamente pacotes do npm como artefatos do Maven podem levar uma versão comprometida do npm para o Maven Central, onde ela é convertida em uma compilação Java como um JAR comum em org.mvnpm coordenadas. Essas coordenadas identificam a ponte, mas uma equipe que não reconheça o namespace tratará o artefato como qualquer outra dependência. Foi exatamente isso que aconteceu quando o Shai-Hulud 2.0 chegou ao Maven Central por meio do mvnpm, em novembro de 2025.

Como posso saber se minha compilação Java incluiu uma biblioteca Java maliciosa?

Correr mvn dependency:tree ou ./gradlew dependencies e verifique cada `groupId` desconhecido consultando a própria documentação do projeto de origem, em vez de se basear em resultados de pesquisa. Para qualquer projeto abandonado, considere o risco de aquisição como independente do status do CVE. Ainda assim, tudo se resume a esse tipo de análise manual, pois a verificação de namespace do Maven Central confirma o controle de um domínio ou conta de hospedagem, e não a afiliação a um projeto com nome semelhante; além disso, o Maven não autentica assinaturas de dependências por padrão.

O Java possui algum equivalente aos scripts de pós-instalação do npm?

Não se trata da instalação de dependências, embora as compilações Java ainda executem código não confiável. Os plug-ins do Maven são executados no ciclo de vida da compilação, os processadores de anotações são executados dentro do compilador e os scripts de compilação do Gradle são programas executáveis, e não meras configurações. O pacote Jackson falso utilizou um truque semelhante em tempo de execução, permitindo que o Spring descobrisse sua classe de configuração e iniciasse a carga maliciosa em seu nome.

Resumo
Segurança do Maven Central após o caso do sósia de Jackson
Nome do artigo
Segurança do Maven Central após o caso do sósia de Jackson
Descrição
Um pacote falso do Jackson passou pelas verificações no Maven Central e executou o Cobalt Strike. Veja a seguir como isso funcionou e como detectá-lo.
Autor
Nome da editora
TuxCare
Logotipo da editora

Junte-se a mais de 4.500 profissionais de Linux e código aberto!

2 vezes por mês. Sem spam.

Índice
Obtenha as respostas sobre segurança de código aberto de que você precisa

Junte-se a mais de 4.500 profissionais de Linux e código aberto!

2 vezes por mês. Sem spam.