Skip to main content

“Um Mini Shai-Hulud surgiu”: ladrão baseado em Bun atinge pacotes npm @cap-js e mbt da SAP

Escrito por

29 de abril de 2026

0 minutos de leitura

Em 29 de abril de 2026, invasores publicaram versões maliciosas de quatro pacotes npm do ecossistema de desenvolvimento da SAP: mbt, @cap-js/db-service, @cap-js/sqlite e @cap-js/postgres. Cada versão comprometida inclui um hook preinstall que baixa o runtime JavaScript Bun do GitHub Releases e o usa para executar um ladrão de credenciais ofuscado de aproximadamente 11,6 MB.

O payload se identifica com uma descrição fixa, “A Mini Shai-Hulud has Appeared”, que está aparecendo em tempo real nos resultados públicos de busca do GitHub, à medida que máquinas de desenvolvedores comprometidas criam repositórios de descarte em suas próprias contas. A campanha reutiliza o nome Shai-Hulud (os repositórios de descarte são identificados com ele) e inclui código funcional de autopropagação pelo npm, segundo a desofuscação completa da StepSecurity. Até a publicação deste artigo, apenas os quatro pacotes originalmente comprometidos haviam sido observados em circulação. A análise técnica e os detalhes sobre a conta npm comprometida que permitiu as publicações iniciais estão abaixo.

A Snyk publicou alertas para as quatro versões comprometidas, e as versões afetadas são sinalizadas por snyk test e exibidas na página Banco de Dados de Segurança da Snyk de cada pacote.

Pacotes afetados e alertas da Snyk

Pacote

Versão comprometida

Alerta da Snyk

Downloads semanais aprox.

mbt

1.2.48

~52.000

@cap-js/db-service

2.10.1

~260.000

@cap-js/sqlite

2.2.2

~250.000

@cap-js/postgres

2.2.2

~10.000

Contagem de downloads semanais da API pública de downloads do registro npm na semana anterior ao comprometimento (22 a 28 de abril de 2026). Os quatro pacotes fazem parte da cadeia de ferramentas do SAP Cloud Application Programming Model. O mbt é o Cloud MTA Build Tool distribuído pelo npm, usado para criar arquivos de implantação para aplicativos em nuvem da SAP. Já os pacotes @cap-js/* fornecem serviços de banco de dados para aplicativos CAP.

As versões maliciosas foram publicadas em um curto intervalo em 29 de abril de 2026, todos os horários em UTC, conforme verificado diretamente no registry.npmjs.org e na API do GitHub:

  • 09:55:25: mbt@1.2.48 publicado pela conta npm cloudmtabot.

  • 10:01:07: o primeiro repositório usado como ponto de entrega da vítima aparece no GitHub (gruposbftechrecruiter/siridar-navigator-935, segundo os registros de data e hora da API do GitHub).

  • 11:25:47: @cap-js/sqlite@2.2.2 publicado.

  • 12:03 to 12:04: a StepSecurity abre chamados de divulgação em cap-js/cds-dbs#1588 e SAP/cloud-mta-build-tool#1224. Uma terceira divulgação independente, SAP/open-ux-tools#4616, é registrada por longieirl às 14:02.

  • 12:14:00: @cap-js/postgres@2.2.2 e @cap-js/db-service@2.10.1 publicados.

  • 13:31: o mantenedor do cap-js chgeo responde: “Obrigado por nos avisar. Vamos limpar os pacotes com a máxima prioridade e investigar as causas raiz.”

  • 13:46: a SAP publica versões limpas após o incidente por meio do publicador confiável OIDC do GitHub Actions cap-npm: @cap-js/db-service@2.11.0, @cap-js/sqlite@2.4.0, @cap-js/postgres@2.3.0 (com a atualização coordenada de @cap-js/hana@2.8.0).

  • 14:02:50: o engenheiro da SAP patricebender abre o PR cap-js/cds-dbs #1592, condicionando a publicação no npm à aprovação manual em um ambiente e incluindo a declaração literal sobre a causa raiz citada acima.

  • 14:24: o colaborador de cloud-mta-build-tool kbarnold responde: “Obrigado pelo relato. Estamos trabalhando nisso com alta prioridade.”

@cap-js/sqlite@2.2.2 foi removido do npm pouco depois da detecção. As demais versões maliciosas têm avisos de descontinuação no npm: mbt@1.2.48 está sinalizado com “SEGURANÇA: esta versão contém código malicioso. Não use.”, enquanto as versões maliciosas de @cap-js/* exibem “NÃO USE. Esta versão contém conteúdo desconhecido.” É importante destacar que mbt@1.2.48 ainda era a versão marcada como latest para mbt no momento da publicação deste artigo, sem nenhuma versão corrigida de mbt publicada. Isso significa que um simples npm install mbt ainda instala o pacote malicioso. Até a publicação, nenhum registro CVE, GHSA ou OSV havia sido atribuído a qualquer um dos quatro pacotes. As únicas fontes públicas oficiais são os quatro blogs dos fornecedores citados ao longo deste artigo e as três notificações de divulgação no GitHub.

Por que o nome “Mini” Shai-Hulud (e o que realmente mudou)

O nome Shai-Hulud já apareceu duas vezes em incidentes envolvendo a cadeia de suprimentos do npm. A campanha original Shai-Hulud, em setembro de 2025, atingiu @ctrl/tinycolor, ngx-bootstrap, ng2-file-upload e muitos outros pacotes dependentes (o relatório da Snyk sobre a vulnerabilidade de dia zero acompanhou o caso enquanto acontecia). A onda seguinte, SHA1-Hulud, em novembro de 2025, se espalhou para mais de 600 pacotes diferentes, incluindo versões publicadas pela Zapier, PostHog e Postman. A equipe Securelist da Kaspersky publicou análises técnicas independentes das duas ondas anteriores (nome de detecção HEUR:Worm.Script.Shulud.gen) em securelist.com/shai-hulud-worm-infects-500-npm-packages e securelist.com/shai-hulud-2-0.

A Mini Shai-Hulud Has Appeared": Bun-Based Stealer Hits SAP @cap-js and mbt npm Packages

Ataque Shai-Hulud ao npm: como remediar com a Snyk (guia rápido para identificar e corrigir dependências afetadas por Shai-Hulud nos seus projetos usando a CLI e as páginas de consultoria da Snyk).

As duas campanhas anteriores apresentaram comportamento de worm: o payload roubava o token npm da vítima e o usava para se publicar em todos os outros pacotes aos quais o token tinha acesso de gravação. A atenção do público acompanhou esse fenômeno: o artigo da Wikipédia sobre o verme da areia de Duna chegou a 2.772 visualizações durante a divulgação do SHA1-Hulud, em novembro de 2025 — o maior número em um único dia em um conjunto de dados de 16 meses, cerca de quatro vezes a média do artigo. Já o artigo mais amplo da Wikipédia sobre “ataques à cadeia de suprimentos” registrou em abril de 2026, mês do Mini Shai-Hulud, sua maior média mensal até então: 310 visualizações por dia (segundo a API REST da Wikimedia).

A campanha de 29 de abril reutiliza a marca Shai-Hulud (os repositórios usados como pontos de entrega recebem nomes com a descrição), mas as evidências públicas disponíveis até agora apontam para um conjunto mais restrito de comportamentos:

  • Roubo de credenciais: observado e detalhado por vários pesquisadores.

  • Injeção de persistência nas configurações de ferramentas de desenvolvimento: inédita e detalhada abaixo.

  • Autopublicação autônoma no npm: o código está presente e é funcional, segundo a desofuscação estática da StepSecurity. O payload coleta tokens npm usando a expressão regular /npm_[A-Za-z0-9]{36,}/g, valida cada um em registry.npmjs.org/-/npm/v1/tokens (filtrando por bypass_2fa: true e permissão de gravação no nível da organização), lista os pacotes acessíveis, injeta setup.mjs e execution.js em uma cópia do arquivo tarball e publica por meio de um PUT direto no registro npm, sem chamar a CLI do npm. Até a publicação deste artigo, nenhum quinto pacote além dos quatro originais havia sido encontrado em circulação com o payload malicioso. Ainda assim, a capacidade de propagação do worm é um fato comprovado, não uma suposição.

  • Sequestro do pipeline de CI como vetor de acesso: a declaração oficial da própria SAP no PR #1592 de patricebender em cap-js/cds-dbs (aberto às 14:02 UTC do mesmo dia) diz: “Em 29 de abril de 2026, um ataque à cadeia de suprimentos comprometeu o repositório: um agente não autorizado enviou commits maliciosos que sequestraram o fluxo de lançamento e acionaram publicações não autorizadas no npm. O invasor conseguiu publicar pacotes comprometidos porque o fluxo de trabalho tinha permissão para publicar, sem exigir nenhuma aprovação manual.” A correção é exigir uma revisão do ambiente antes de publicar no npm. Segundo os dados do registro npm, as quatro versões maliciosas foram publicadas pela conta cloudmtabot (mantenedor legítimo do mbt). Já as versões limpas da SAP, publicadas após o incidente às 13:46 UTC, foram publicadas pelo publicador confiável OIDC do GitHub Actions cap-npm, e não por cloudmtabot. Desde então, a conta cloudmtabot foi suspensa no npm. O comprometimento das credenciais de mantenedores é um ponto de entrada recorrente nesse tipo de incidente, mas a declaração da SAP aponta especificamente a falta de uma etapa de aprovação no fluxo de trabalho como causa raiz estrutural.

O roubo de credenciais possibilita a autorreplicação no npm, mas a atividade observada imediatamente foi a exfiltração de dados e o uso de um novo mecanismo de persistência. As prioridades de defesa — auditoria do lockfile, rotação de credenciais e políticas para scripts de ciclo de vida — são as mesmas nos dois casos.

Como o ataque funciona

O padrão de comprometimento é o mesmo nos quatro pacotes: o tarball malicioso mantém intactos os arquivos legítimos do pacote (para que a CLI continue funcionando após a instalação) e adiciona dois novos arquivos: setup.mjs (um carregador Bun em texto simples, de 4,5 KB, idêntico byte a byte nos quatro pacotes) e execution.js (um payload ofuscado com exatamente 11.678.349 bytes, cujos hashes diferem entre o mbt e os pacotes @cap-js/*). Somente no caso do mbt, o package.json malicioso também adiciona três dependências (axios, tar e unzip-stream) que não aparecem na versão limpa anterior. Os três pacotes cap-js adicionaram apenas o hook preinstall ao package.json existente.

Baixar um carregador pequeno durante a instalação e usá-lo para obter um runtime e um payload muito maiores é um padrão que a Snyk também observou em outros casos neste ano, incluindo o axios incidente de RAT multiplataforma, em que o hook de instalação buscava um binário nativo distribuído por uma dependência separada.

No caso do mbt, a diferença entre 1.2.47 (limpa) e 1.2.48 (maliciosa) é a seguinte:

// 1.2.47: no scripts block
// 1.2.48:
{
  "scripts": {
    "preinstall": "node setup.mjs"
  },
  "dependencies": {
    "axios": "^1.13.5",
    "tar": "^7.5.7",
    "unzip-stream": "^0.3.4"
  }
}

O preinstall é executado antes que o npm mostre qualquer saída ao usuário e antes que uma política condicional --ignore-scripts possa agir, caso a opção não esteja definida. O hook executa setup.mjs, que:

  1. Detecta a plataforma e a arquitetura (incluindo a detecção de Alpine/musl no Linux).

  2. Verifica se bun já está no PATH usando hasCommand("bun"). Se estiver, ignora o download e usa o binário existente. Caso contrário, baixa o Bun 1.3.13 do GitHub Releases (seguindo redirecionamentos HTTP sem validar o destino, segundo a análise da Socket).

  3. Se o binário do Bun tiver sido baixado, extrai-o para um diretório temporário.

  4. Executa bun execution.js para rodar o payload ofuscado.

Depois que bun execution.js é executado, o payload passa por duas camadas de ofuscação: uma rotação de tabela de strings no estilo obfuscator.io (48.370 entradas decodificadas com um alfabeto base64 não convencional e verificadas por uma soma de verificação na inicialização) e uma cifra personalizada que a StepSecurity chamou de “ctf-scramble-v2”, com uma chave mestra derivada por PBKDF2. As duas camadas foram totalmente recuperadas por análise estática. O runtime desofuscado é JavaScript executado no Bun (sem WASM incorporado nem código nativo; o payload usa APIs nativas do Bun, como Bun.gunzipSync() e Bun.main).

A desofuscação estática da StepSecurity descreve os seguintes comportamentos do payload:

  • Coleta credenciais locais, tokens do GitHub e npm, segredos do GitHub Actions, segredos de serviços de nuvem da AWS, Azure, GCP e Kubernetes, tokens de CLI de gerenciadores de senhas (1Password, Bitwarden e LastPass), ~/.claude.json e configurações de servidores MCP, variáveis de ambiente que correspondem aos padrões KEY/TOKEN/SECRET/PASSWORD e chaves de carteiras de criptomoedas presentes na máquina. Quando disponível, o payload também consulta o serviço de metadados de instância da AWS (169.254.169.254).

  • Em executores de CI Linux, ele inicia um processo filho do Python que lê /proc/{pid}/mem do processo Runner.Worker do GitHub Actions para extrair segredos em texto simples diretamente da memória do executor.

  • No Windows, invoca o PowerShell com -ExecutionPolicy Bypass.

  • Serializa os dados roubados em JSON, compacta-os com gzip, criptografa-os com AES-256-GCM (chave de 32 bytes, IV de 12 bytes) e protege a chave AES usando RSA-OAEP-SHA256 com uma chave pública RSA-4096 incorporada (armazenada como PEM em gzip+base64 no deslocamento de arquivo 9,429,992 em execution.js, descompactada em tempo de execução por meio de Bun.gunzipSync()). Isso significa que os defensores que encontrarem o repositório de descarte podem ver que algo foi roubado, mas não conseguem determinar o que. Na prática, toda credencial que o processo podia acessar deve ser considerada exposta.

  • Cria uma repositório público na conta GitHub da vítima, com um nome formado por caracteres aleatórios e a descrição "A Mini Shai-Hulud has Appeared", e registra o texto cifrado como descarte.

  • Verifica a localidade do sistema por meio da API JavaScript Intl e de variáveis de ambiente POSIX (LC_ALL, LC_MESSAGES, LANGUAGE, LANG). Se detectar uma localidade russa (ru), o payload registra "Exiting as russian language detected!" e é encerrado. As verificações de isenção para países da CEI estão de acordo com o comportamento documentado de operações de cibercriminosos nessas regiões.

O mecanismo de persistência

Independentemente de a campanha ser classificada como um worm, o mecanismo de persistência é o elemento mais inovador documentado em relatos públicos.

Segundo a StepSecurity, o payload usa três mecanismos de persistência e reexecução:

  • Injeção em configurações de ferramentas de desenvolvimento. Em cada repositório GitHub no qual o token roubado pode gravar, o payload faz commit de um arquivo .claude/settings.json que usa o hook do Claude Code SessionStart para reexecutar o payload sempre que um desenvolvedor inicia uma sessão do Claude Code, além de um arquivo .vscode/tasks.json com "runOn": "folderOpen", que é acionado quando o projeto é aberto no VS Code. Esses arquivos injetados são commitados com a identidade claude@users.noreply.github.com e a mensagem "chore: update dependencies", o que pode fazê-los parecer commits de automação rotineiros durante a revisão de PRs.

  • Injeção em workflows do GitHub Actions. Quando o token roubado tem escopo workflow, o payload cria uma branch com nome parecido por typosquatting, dependabout/github_actions/format/setup-formatter (observe a ausência do t), e faz commit do arquivo .github/workflows/format-check.yml, se passando pela conta de serviço do Dependabot (dependabot[bot]@users.noreply.github.com, mensagem de commit "Add formatter workflow"). O workflow injetado usa ${{ toJSON(secrets) }} para despejar todos os segredos do repositório em um artefato de build chamado format-results.txt.

  • Execução como daemon nas máquinas de desenvolvedores. Em hosts que não são de CI, o payload se bifurca como um processo em segundo plano independente, identificado pela variável de ambiente __DAEMONIZED=1. Em seguida, o processo pai é encerrado normalmente, fazendo com que npm install retorne ao usuário sem exibir erros. O processo filho continua em execução sem uma relação clara com o processo de origem.

Isso amplia o conjunto de vetores de persistência na instalação observados em campanhas contra a cadeia de suprimentos do npm, incluindo arquivos de configuração de agentes de programação com IA, além de hooks de ciclo de vida em package.json, workflows de CI e manifestos de plugins de IDE.

Os ataques à superfície de configuração de agentes de IA já têm precedentes documentados; não são uma novidade. O relato VSCode #309406, da Microsoft, sobre o vetor tasks.json runOn: folderOpen foi aberto dezesseis dias antes e encerrado como By Design (a confiança no workspace é considerada uma mitigação suficiente, embora essa verificação não cubra commits feitos em repositórios já confiáveis). O relato claude-code #49778, da Anthropic, sobre o hook SessionStart foi aberto doze dias antes e segue em aberto, sem resposta da Anthropic, citando um precedente real na auditoria da cadeia de suprimentos da Cozempic. O comprometimento do agente de IA Trivy (CVE-2026-28353), em março de 2026, foi ainda mais longe: usou tokens roubados para publicar uma extensão maliciosa do VS Code que tinha como alvo cinco agentes de programação com IA diferentes. A Snyk abordou esse mesmo cruzamento separadamente no artigo sobre Clinejection. Mini Shai-Hulud é mais um caso desse padrão, não o primeiro.

Indicadores de comprometimento

Esta lista resume informações públicas divulgadas por StepSecurity, Aikido, Socket e SafeDep. Consulte esses relatos para ver a lista completa de IOCs e os detalhes forenses. Cada versão maliciosa continua disponível para consulta como registro imutável no registro do npm: registry.npmjs.org/mbt/1.2.48, registry.npmjs.org/@cap-js/sqlite/2.2.2, registry.npmjs.org/@cap-js/postgres/2.2.2 e registry.npmjs.org/@cap-js/db-service/2.10.1. O horário de publicação e a assinatura "preinstall": "node setup.mjs" foram preservados em cada registro.

Compromised npm artifacts
  mbt@1.2.48                       shasum 0af7415d65753f6aede8c9c0f39be478666b9c12
  @cap-js/db-service@2.10.1        shasum 4b04304f6d51392e3f43856c94ca95800518a694
  @cap-js/sqlite@2.2.2             shasum 7b6a28e92149637e5d7c7f4a2d3e54acd507c929
  @cap-js/postgres@2.2.2           shasum e80824a19f48d778a746571bb15279b5679fd61c

Compromised npm publisher account
  cloudmtabot (used to publish all four malicious versions)

Files added to the compromised tarballs
  setup.mjs       ~4.5 KB plaintext Bun loader, byte-identical
                   across all four packages
  execution.js    11,678,349 bytes obfuscated payload, hash
                   differs per package

File hashes (SHA-256, per StepSecurity)
  setup.mjs (all packages)
    4066781fa830224c8bbcc3aa005a396657f9c8f9016f9a64ad44a9d7f5f45e34
  execution.js (mbt@1.2.48)
    80a3d2877813968ef847ae73b5eeeb70b9435254e74d7f07d8cf4057f0a710ac
  execution.js (@cap-js/sqlite@2.2.2)
    6f933d00b7d05678eb43c90963a80b8947c4ae6830182f89df31da9f568fea95
  Embedded /proc/mem dumper
    29ac906c8bd801dfe1cb39596197df49f80fff2270b3e7fbab52278c24e4f1a7

In-payload indicators (recovered by StepSecurity static analysis)
  Custom cipher salt              ctf-scramble-v2
  PBKDF2 input key                5012caa5847ae9261dfa16f91417042f367d6bed149c3b8af7a50b203a093007
  Derived master key              fd4b0f07b27e8f41bc70b8e2b79d168fb3fe80d7e0b37f43c506136a3418b44d
  CIS evasion log string          Exiting as russian language detected!
  Daemonization env var           __DAEMONIZED
  GitHub PAT regex                /gh[op]_[A-Za-z0-9]{36}/g
  npm token regex                 /npm_[A-Za-z0-9]{36,}/g

Network and runtime indicators
  - Outbound request to github.com/oven-sh/bun/releases/download/bun-v1.3.13/{asset}.zip
    where {asset} is one of:
      bun-linux-aarch64
      bun-linux-x64-baseline
      bun-linux-x64-musl-baseline
      bun-darwin-aarch64
      bun-darwin-x64
      bun-windows-aarch64
      bun-windows-x64-baseline
    (skipped if `bun` is already on PATH)
  - Process chain during install:
    node setup.mjs -> bun execution.js
  - Linux CI runners: child Python process reading
    /proc/{pid}/mem of Runner.Worker
  - Windows: powershell -ExecutionPolicy Bypass
  - api.github.com calls:
    POST /user/repos               (dead-drop repo creation)
    GET  /search/commits?q=OhNoWhatsGoingOnWithGitHub
                                   (P2P token dead-drop search)
  - Direct PUT to registry.npmjs.org during self-propagation
    (no npm CLI involvement)
  - Cloud metadata reads:
    http://169.254.169.254          (AWS/Azure IMDS)
    http://169.254.170.2            (ECS task metadata)
    http://[fd00:ec2::254]          (AWS IMDSv2 IPv6)

GitHub-side indicators
  - New public repositories on developer accounts with the
    description string "A Mini Shai-Hulud has Appeared"
  - Repository names follow a Dune-themed pattern, regex:
    (sardaukar|mentat|fremen|atreides|harkonnen|gesserit|
     prescient|fedaykin|tleilaxu|siridar|kanly|sayyadina|
     ghola|powindah|prana|kralizec)-(sandworm|ornithopter|
     heighliner|stillsuit|lasgun|sietch|melange|thumper|
     navigator|fedaykin|futar|slig|phibian|laza|cogitor|
     ghola)-\d{1,3}
  - Commits authored by claude@users.noreply.github.com
    with the message "chore: update dependencies"
  - New or modified .claude/settings.json files containing
    a SessionStart hook
  - New or modified .vscode/tasks.json with a task using
    "runOn": "folderOpen"
  - P2P token dead-drop commits referencing the string
    "OhNoWhatsGoingOnWithGitHub" (used by the malware to
    locate base64-encoded tokens left by other victims)
  - Typosquatted Dependabot branch:
    dependabout/github_actions/format/setup-formatter
  - Injected workflow file .github/workflows/format-check.yml
    using the expression toJSON(secrets), authored by
    dependabot[bot]@users.noreply.github.com with commit
    message "Add formatter workflow", uploading artifact
    "format-results.txt"

Pesquisas ao vivo no GitHub pelas duas strings mais específicas:

Cada repositório de descarte contém um único arquivo README.md e um ou mais arquivos em results/results-<unix-ms>-<counter>.json. A inspeção direta de um repositório ativo de uma vítima, feita por pesquisadores externos, confirmou o formato do arquivo:

{"envelope": "<base64 AES-256-GCM ciphertext>", "key": "<base64 RSA-4096 wrapped session key>"}

Como a chave de encapsulamento é a chave pública RSA-4096 do invasor, os defensores não conseguem ler o conteúdo nem mesmo com acesso total à conta GitHub da vítima.

O que fazer

O alcance do incidente depende de os pipelines de build ou as máquinas de desenvolvedores terem executado npm install com alguma das quatro versões afetadas durante o período de exposição (aproximadamente das 10h às 14h UTC de 29 de abril de 2026, além de qualquer período em que as versões descontinuadas continuem podendo ser resolvidas).

Verifique as instalações. Procure as versões afetadas nos arquivos de lock e confira também as dependências transitivas: @cap-js/sqlite@2.2.2 declara @cap-js/db-service@^2.10.0 como dependência. Assim, uma instalação limpa de @cap-js/sqlite usando um intervalo de versões disponível pode incluir @cap-js/db-service@2.10.1 (a versão maliciosa) como dependência transitiva, mesmo que ninguém a tenha listado diretamente.

# in any project root
rg -n '"mbt"|"@cap-js/db-service"|"@cap-js/sqlite"|"@cap-js/postgres"' \
   package-lock.json npm-shrinkwrap.json yarn.lock pnpm-lock.yaml 2>/dev/null

Para clientes da Snyk, snyk test e snyk monitor identificam as versões maliciosas com base nos quatro avisos listados acima. As páginas do Snyk Security Database para mbt, @cap-js/db-service, @cap-js/sqlite e @cap-js/postgres também registram o incidente de segurança.

Se uma versão comprometida foi instalada:

  • Considere exposta toda credencial acessível a partir dessa máquina ou pipeline. Como a criptografia usa a chave RSA controlada pelo invasor, os defensores não conseguem ler o conteúdo do repositório de descarte para confirmar o alcance do ataque; por isso, a rotação de credenciais deve ser abrangente. Entre os 134 padrões de caminhos de arquivos recuperados pela StepSecurity do payload, estão, no mínimo: tokens de publicação do npm (prioridade máxima, pois permitem propagação semelhante à de um worm para outros pacotes mantidos pelo desenvolvedor); PATs do GitHub e concessões OAuth; credenciais da AWS/Azure/GCP e funções que possam ser assumidas pela máquina afetada; kubeconfigs do Kubernetes (~/.kube/config, YAML do k3s, tokens de conta de serviço dentro de pods); configurações do Docker (~/.docker/config.json); credenciais do Terraform Cloud (~/.terraform.d/credentials.tfrc.json); configuração do Helm; chaves SSH (~/.ssh/id*, config, known_hosts, chaves de host em /etc/ssh/); tokens de CLI de gerenciadores de senhas (op do 1Password, bw do Bitwarden, LastPass); .npmrc / .pypirc / .yarnrc; .gitconfig e .git-credentials; arquivos de histórico do shell; variáveis de ambiente e arquivos .env* que correspondam aos padrões *_TOKEN, *_KEY, *_SECRET ou *_PASSWORD; ~/.claude.json e configurações de servidores MCP, incluindo as configurações MCP do Kiro em ~/.kiro/settings/mcp.json; dados de sessão de aplicativos de mensagens (Signal, cookies do Slack, Discord, Telegram, Element, Pidgin); configurações de VPN (NordVPN, ProtonVPN, OpenVPN etc.); listas de servidores do FileZilla; configurações do Ansible; e chaves de carteiras de criptomoedas de Bitcoin, Ethereum, Monero, Dash, Zcash, Dogecoin, Litecoin, Electrum, Exodus, Ledger Live e Atomic. O payload também lê metadados de instâncias da AWS (169.254.169.254, 169.254.170.2, fd00:ec2::254) e metadados de tarefas do ECS. Portanto, considere expostas quaisquer funções IAM acessíveis por esses endpoints.

  • Audite a exposição de segredos do GitHub Actions. A técnica de extração de /proc/{pid}/mem lê todo o espaço de endereçamento legível de Runner.Worker. Portanto, qualquer segredo usado no workflow até aquele momento está em risco, mesmo que não seja referenciado diretamente pela etapa de instalação. Os executores hospedados pelo GitHub não bloqueiam esse acesso por padrão; para detectá-lo, é necessário um agente de segurança no executor, como o StepSecurity Harden-Runner.

  • Faça uma varredura na sua organização do GitHub em busca dos IOCs no bloco de código acima: repositórios de descarte com nomes inspirados em Dune e a descrição "Mini Shai-Hulud"; a assinatura de autor claude@users.noreply.github.com; a falsificação de identidade de dependabot[bot]@users.noreply.github.com em uma branch dependabout/...; o workflow injetado .github/workflows/format-check.yml, que exfiltra toJSON(secrets) para um artefato format-results.txt; a string de commit de descarte de tokens P2P OhNoWhatsGoingOnWithGitHub; e adições inesperadas aos arquivos .claude/settings.json ou .vscode/tasks.json.

  • Fixe versões seguras. Para os três pacotes @cap-js, prefira as versões lançadas pela SAP após o incidente (@cap-js/db-service@2.11.0, @cap-js/sqlite@2.4.0, @cap-js/postgres@2.3.0) como versões de destino e use as versões anteriores ao incidente (2.10.0, 2.2.1 e 2.2.1, respectivamente) como versões mínimas. Para mbt, nenhuma versão corrigida havia sido publicada até a data de redação deste artigo; fixe em mbt@1.2.47 até a SAP lançar uma versão substituta.

Reforço geral da segurança:

Comece a proteger seus aplicativos Python

Encontre e corrija vulnerabilidades em Python gratuitamente com o Snyk.

Não é necessário informar cartão de crédito.

Ou cadastre-se com Azure AD Docker ID Bitbucket

Ao usar o Snyk, você concorda em cumprir nossas políticas, incluindo os Termos de Serviço e a Política de Privacidade.