
Campanha publicou 36 pacotes no npm com gancho de instalação malicioso, coleta de credenciais, exploração de bancos de dados e acesso remoto persistente em ambientes Strapi.
| Componente | 36 pacotes npm disfarçados como plugins comunitários do Strapi, com nomes iniciados por strapi-plugin- e estrutura mínima contendo package.json, index.js e postinstall.js. |
| Vetor | execução automática do gancho postinstall durante npm install, sem interação adicional do usuário, com os privilégios da conta que realiza a instalação. |
| Impacto | coleta de variáveis de ambiente, configurações do Strapi, segredos de Docker e Kubernetes, chaves criptográficas, arquivos de carteiras, acesso a PostgreSQL com credenciais embutidas, shells reversos e implante persistente voltado ao hostname prod-strapi. |
| Prioridade | ambientes que instalaram qualquer pacote correspondente devem assumir comprometimento, remover dependências maliciosas, revisar execução de scripts de instalação, rotacionar credenciais e examinar bancos Redis, PostgreSQL, pipelines e contêineres. |
| Versões | os pacotes usavam a versão 3.6.8 para aparentar maturidade e compatibilidade com plugins comunitários do Strapi v3. |
| Artefatos | contas publicadoras citadas: umarbek1233, kekylf12, tikeqemif26 e umar_bektembiev1; a publicação ocorreu ao longo de cerca de 13 horas. |
Uma campanha de cadeia de suprimentos no npm distribuiu 36 pacotes maliciosos que imitavam plugins do Strapi CMS. A escolha dos nomes seguiu um padrão feito para parecer familiar a desenvolvedores: todos começavam com strapi-plugin- e eram acompanhados de termos genéricos como cron, database ou server. Esse detalhe é relevante porque plugins oficiais do Strapi usam escopo próprio sob @strapi/, enquanto os pacotes maliciosos exploravam a aparência de extensões comunitárias. A estrutura também era deliberadamente simples, com apenas três arquivos principais e sem descrição, repositório ou página inicial, reduzindo sinais de legitimidade verificável e concentrando a execução no gancho de instalação.
O ponto crítico da campanha estava no arquivo postinstall.js. Em projetos Node.js, esse tipo de script é acionado automaticamente durante a instalação do pacote, o que transforma a inclusão de uma dependência em um evento de execução de código. O código malicioso rodava com os mesmos privilégios do usuário ou processo responsável pela instalação. Em estáções de desenvolvimento isso pode significar acesso a variáveis locais, arquivos de configuração e credenciais de ferramentas. Em CI/CD, imagens Docker e rotinas de build executadas com permissões elevadas, o mesmo mecanismo pode alcançar segredos de pipeline, tokens de integração, volumes montados e serviços internos acessíveis apenas a partir do ambiente de construção.
A sequência de cargas observada indica adaptação operacional. As primeiras variantes tentavam abusar de Redis para execução remota e até escapar de contêineres Docker. Em seguida, os pacotes passaram a coletar informações do ambiente, procurar strings de conexão do PostgreSQL, enumerar dados do Redis, mapear topologia de rede e buscar segredos de Docker, Kubernetes, chaves criptográficas e arquivos relacionados a carteiras de criptomoedas. As variantes posteriores incluíam acesso a banco PostgreSQL usando credenciais embutidas, consultas a tabelas específicas do Strapi, busca por padrões ligados a operações com criptoativos e um implante persistente voltado a um hostname específico, prod-strapi.
A cadeia começava no registro npm, onde os pacotes eram apresentados como plugins plausíveis do Strapi. Depois que um projeto instalava uma dessas dependências, o gancho postinstall iniciava a carga maliciosa. A partir desse ponto, a campanha não dependia de o aplicativo Strapi ser iniciado nem de uma chamada explícita ao pacote. Essa característica amplia o risco em pipelines automatizados, porque a execução pode ocorrer durante etapas de resolução de dependências, construção de imagem, teste ou preparação de artefatos. O abuso do ciclo de vida do npm é especialmente sensível porque muitas organizações permitem scripts de instalação por padrão para suportar pacotes legítimos que compilam binários, preparam artefatos ou ajustam dependências nativas.
As cargas voltadas a Redis exploravam a presença de uma instância acessível localmente. O objetivo era transformar o serviço em pivô de execução, incluindo a gravação de uma entrada de agendamento para acionar periodicamente um script remoto. O conteúdo descrito para esse fluxo incluía escrita de web shell PHP e shell reverso em Node.js na área pública de uploads do Strapi por meio de SSH, além de varredura de disco em busca de segredos como dados de Elasticsearch e frases-semente de carteiras. Em outra variação, a lógica combinava Redis com tentativa de escapar do contêiner Docker, gravando cargas fora do isolamento esperado e criando caminhos adicionais para shell reverso. Os comandos operacionais e payloads executáveis devem ser tratados como material de abuso; para defesa, o ponto importante é a alteração não autorizada de agendamentos, arquivos em uploads públicos, node_modules e limites entre contêiner e host.
A trilha de reconhecimento evoluiu para coleta mais ampla. As cargas procuravam variáveis de ambiente, strings de conexão PostgreSQL, configurações do Strapi, dados do Redis por meio de consultas administrativas, informações de rede, segredos de orquestração e materiais criptográficos. A etapa PostgreSQL usava credenciais embutidas para tentar conexão direta ao banco da vítima e consultar tabelas associadas ao Strapi em busca de segredos. O mesmo fluxo procurava padrões de texto relacionados a carteiras, transações, depósitos, saques e saldos, o que sustenta a hipótese de interesse em ativos digitais, mas não confirma por si só comprometimento de uma plataforma específica. A presença de tentativas contra seis bancos Guardarian e de dados embutidos sugere conhecimento prévio ou material obtido por outro caminho, mas a atribuição e a origem desse conhecimento permanecem condicionadas ao que foi observado na campanha.
A exposição principal recai sobre projetos Node.js que instalaram algum dos pacotes maliciosos, especialmente aplicações Strapi, ambientes de desenvolvimento com acesso a bancos locais e pipelines que executam instalação de dependências com segredos disponíveis no ambiente. Como os pacotes se apresentavam como plugins, o risco não se limita ao runtime do CMS. A execução ocorre no momento da instalação, antes de qualquer validação funcional do plugin dentro da aplicação. Isso significa que lockfiles, caches de pacotes, imagens intermediárias, artefatos de build e repositórios de infraestrutura podem conter rastros ou preservar versões já removidas do registro público.
Ambientes containerizados merecem atenção específica. A campanha tentou abusar de permissões e montagens para escrever fora do contêiner, além de procurar dados de Docker e Kubernetes. Mesmo que a tentativa de escape não tenha sucesso em todos os ambientes, a execução com privilégios excessivos dentro do contêiner pode ser suficiente para ler variáveis, tokens de registry, arquivos montados e credenciais usadas por jobs de CI/CD. Redis e PostgreSQL entram como superfícies internas: instâncias sem autenticação robusta, acessíveis por localhost ou rede de build, ampliam o impacto do pacote malicioso instalado.
- Projetos com dependências iniciadas por
strapi-plugin-que não sejam pacotes oficiais sob@strapi/devem ser revisados contra o histórico de instalação. - Servidores Strapi com diretórios públicos de upload graváveis devem ser verificados quanto a arquivos PHP, JavaScript ou Node.js inesperados.
- Ambientes com Redis local ou acessível a partir do processo de instalação devem ser examinados para alterações de configuração, chaves suspeitas e uso administrativo incomum.
- Bancos PostgreSQL usados pelo Strapi devem ter auditoria de conexões, consultas a tabelas de configuração e uso de credenciais que não pertençam ao fluxo normal da aplicação.
- Pipelines que executaram
npm installcom segredos disponíveis em variáveis de ambiente, volumes montados ou credenciais de nuvem devem ser tratados como potencialmente expostos.
A caça deve começar pelo inventário de dependências. Lockfiles, cache local do npm, registros de pipeline e imagens de contêiner podem indicar se algum dos pacotes foi resolvido ou instalado. Como a publicação ocorreu por contas específicas e em janela curta, metadados de pacote, data de resolução e origem do artefato ajudam a separar instalações reais de simples presença em listas de dependência. Também é importante verificar se scripts de instalação foram executados, pois a simples tentativa de build em um ambiente efêmero pode ter coletado segredos antes que o pacote fosse removido.
Nos endpoints e servidores, os sinais mais úteis envolvem criação de processos filhos a partir de npm, node, shells do sistema ou processos de build logo após a instalação. A defesa deve procurar conexões de saída inesperadas, arquivos criados em diretórios de upload do Strapi, alterações em node_modules, agendamentos recém-criados, artefatos de shell reverso e scripts de download com nomes não associados ao projeto. Em contêineres, a correlação deve incluir eventos de escrita fora dos caminhos esperados da aplicação, acesso a sockets Docker, leitura de segredos montados e tentativa de enumerar arquivos de Kubernetes.
Na camada de dados, Redis e PostgreSQL precisam ser tratados como fontes de evidência. Para Redis, procure comandos administrativos ou de enumeração incompatíveis com o comportamento normal do aplicativo, aumento anormal de leitura de chaves e gravações ligadas a persistência ou acionamento de arquivos. Para PostgreSQL, revise conexões originadas de hosts de build, consultas incomuns contra tabelas do Strapi, falhas de autenticação com credenciais antigas ou embutidas e padrões de consulta voltados a campos de segredo. A ausência de logs detalhados limita a reconstrução, portanto a resposta deve considerar rotação preventiva quando a telemetria não for suficiente.
- Execução de
postinstall.jsassociada a pacotes sem descrição, repositório ou página inicial. - Processos de shell, Python ou Node.js iniciados por
npmdurante instalação de dependências. - Arquivos inesperados em diretórios públicos do Strapi, especialmente uploads expostos pela aplicação.
- Consultas Redis de enumeração e leitura ampla, incluindo uso administrativo fora do padrão do serviço.
- Conexões PostgreSQL originadas de jobs de build, contêineres temporários ou hosts de desenvolvimento sem justificativa operacional.
- Leitura de variáveis de ambiente, arquivos de carteira, chaves criptográficas, segredos Docker e artefatos Kubernetes após instalação de pacote.
A resposta deve assumir que a execução ocorreu quando qualquer pacote correspondente foi instalado. A primeira etapa é interromper builds que ainda usem os pacotes, remover as dependências, invalidar caches de pacote e reconstruir imagens a partir de bases limpas. Em seguida, a organização deve comparar lockfiles e histórico de pipeline para identificar quais ambientes executaram a instalação, quais credenciais estavam presentes naquele momento e quais serviços internos eram alcançáveis a partir do processo. Essa análise define o escopo de rotação e evita limitar a resposta ao servidor Strapi visível em produção.
A rotação de credenciais deve abranger segredos de aplicação, tokens de CI/CD, chaves de registry, credenciais de banco, variáveis usadas por integrações, chaves criptográficas expostas em disco e credenciais de infraestrutura acessíveis por Docker ou Kubernetes. Para Redis, é necessário validar autenticação, segmentação de rede e ausência de exposição desnecessária a ambientes de build. Para PostgreSQL, revise usuários embutidos, permissões excessivas e histórico de consultas. Em Strapi, verifique configurações, diretórios de upload e tabelas que armazenem segredos ou parâmetros sensíveis.
Medidas preventivas incluem bloquear scripts de instalação quando possível, permitir exceções apenas para pacotes conhecidos, validar escopos oficiais de pacotes Strapi, exigir revisão para dependências recém-publicadas e monitorar pacotes com metadados mínimos. Pipelines devem reduzir privilégios durante instalação, separar segredos de etapas que não precisam deles e executar builds em ambientes descartáveis sem acesso lateral a bancos internos. A campanha demonstra que uma dependência de aparência comum pode atuar antes do runtime da aplicação, portanto o controle precisa estar no processo de desenvolvimento, no registro de pacotes e na execução automatizada.
- Remover os pacotes maliciosos, limpar caches npm e reconstruir artefatos sem reutilizar camadas ou imagens contaminadas.
- Rotacionar credenciais disponíveis durante
npm install, incluindo bancos, CI/CD, registros, nuvem, Docker, Kubernetes e segredos de aplicação. - Auditar diretórios públicos do Strapi,
node_modules, agendamentos, processos persistentes e conexões de saída após a janela de instalação. - Restringir Redis e PostgreSQL a redes necessárias, com autenticação forte, contas de menor privilégio e logs suficientes para investigação.
- Revisar políticas de dependência para diferenciar pacotes oficiais sob
@strapi/de pacotes comunitários não verificados. - Executar instalação de dependências sem segredos sensíveis disponíveis e com scripts de ciclo de vida desabilitados quando a base do projeto permitir.
0 Comentários