Padrões de Segurança na Cadeia de Suprimentos
Aplica-se a todos os projetos. Regras revisadas em 2026-11-11 (pós Shai-Hulud / Mini Shai-Hulud).
Padrões de nível de máquina (~/.npmrc)
minimum-release-age=1440 # apenas pnpm — MINUTOS (1440 = 24h)
min-release-age=1 # apenas npm 12+ — DIAS (1 = 24h)
Os dois gerenciadores de pacotes usam nomes de chave diferentes E unidades diferentes. Verificado em 2026-08-21 lendo o código-fonte de cada ferramenta: pnpm computa Date.now() - minimumReleaseAge * 60 * 1e3 (minutos); a definição de configuração do npm para min-release-age carrega hint: '<days>'. Ambas as linhas são necessárias — uma não cobre a outra, e copiar 1440 na chave do npm significaria 1440 dias e bloquearia essencialmente todas as instalações.
O npm exibe Unknown user config "minimum-release-age" na instalação e avisa que deixará de funcionar em uma versão futura. Isso é inevitável enquanto a chave existir em ~/.npmrc: pnpm 11 removeu a escrita de configuração global (pnpm config set --global agora redireciona para um pnpm-workspace.yaml por projeto), então ~/.npmrc é o único lugar onde uma trava global do pnpm pode viver. Aceite o aviso; não delete a chave.
Não confie nestes — verificados como inertes
-
block-exotic-subdependencies— não aparece nem no código-fonte do npm nem do pnpm. Nunca fez nada. Dependências exóticas devem ser detectadas por revisão, não por esta chave. -
ignore-scripts=true— esta skill anteriormente afirmava que estava definido globalmente. Não está definido, enpm config get ignore-scriptsretornafalse, portanto scripts de ciclo de vida são executados na instalação.Decidido em 2026-08-21: deixe desligado. Não o ative. Postinstall é o vetor primário de comprometimento do npm, então esta é uma lacuna conhecida e aceita — não uma omissão para corrigir. Ativá-lo globalmente quebra builds nativos (esbuild, swc, sharp, node-gyp) em todos os projetos e a quebra aparece longe da causa. A trava de idade mínima de release de 24h acima carrega esse risco. Se um projeto específico precisar de isolamento de script, escopo ele lá — nunca global.
Verifique tais afirmações contra a ferramenta e não contra este arquivo — todas as três entradas aqui estavam erradas quando auditadas.
Taxonomia de ataques na cadeia de suprimentos (referência antes de auditar)
1. Typosquatting / Confusão de Dependência
Nome do pacote quase idêntico a um popular, ou um pacote público correspondendo a um nome com escopo interno. 454.648 pacotes npm maliciosos publicados apenas em 2025.
Detectar: npm info <pkg> | grep -E 'created|repository' em pacotes desconhecidos. Cruze referências com nomes de registro internos.
2. Roubo de Conta de Mantenedor
Atacante aplica phishing em um mantenedor, publica uma nova versão com um payload pós-instalação. Shai-Hulud setembro de 2025 atingiu chalk, debug, ansi-styles (2,6 bilhões de downloads semanais). Axios (100M+/semana) foi atingido em março de 2026 via engenharia social da RPDC.
Detectar: npm diff <pkg>@<ultimo-conhecido-bom> <pkg>@latest -- package.json scripts — verifique novos scripts de ciclo de vida adicionados em versões de patch.
3. Sequestro de Repositório / Ocupação de Namespace
Atacante registra um nome de usuário do GitHub ou namespace npm abandonado, recria o repositório e serve código malicioso.
Detectar: Verifique o campo repository em package.json; sinalize contas do GitHub criadas após a data da primeira publicação npm do pacote.
4. Injeção em Pipeline CI/CD (pull_request_target / envenenamento de cache)
Atacante abre um PR contra um repositório com pull_request_target que compartilha cache com um job de publicação privilegiado. Envenenar o pnpm store; o próximo workflow de release vaza o token OIDC do npm. Vetor TanStack (novembro de 2025, Mini Shai-Hulud maio de 2026, 300+ pacotes, 16M downloads semanais).
Detectar:
grep -r "pull_request_target" .github/workflows/
grep -r "cache" .github/workflows/ | grep -i "pnpm\|npm\|store"
Regra rígida: Nunca use pull_request_target se o workflow checkout o código do PR ou compartilhar cache com um job privilegiado.
5. Envenenamento de Imagem Docker
Atacante compromete credenciais do Docker Hub e sobrescreve tags de imagem existentes (incluindo latest) com binários maliciosos. Tags 0.69.4–0.69.6 e latest do Trivy aquasec/trivy foram envenenadas em março de 2026. KICS abril de 2026 — cinco tags sobrescritas; escaneia configurações Terraform/K8s contendo segredos.
Detectar: docker inspect <image> --format '{{.Id}}' vs. um digest fixado na configuração.
Regra rígida: Fixe todas as imagens ao digest @sha256:. Nunca use latest para imagens de ferramentas de segurança.
6. Redirecionamento de Tag do GitHub Actions
Atacante compromete o token de um mantenedor de ação, move uma tag de versão existente para apontar para código malicioso. tj-actions/changed-files CVE-2025-30066 (março de 2025, 23.000+ repositórios) despejou todos os segredos de CI para logs. Maio de 2026: tags de ações populares redirecionadas para commits impostores. Detectar:
grep -r "uses:.*@v[0-9]" .github/workflows/ # sinaliza fixado por tag (ruim)
grep -r "uses:.*@[a-f0-9]\{40\}" .github/workflows/ # fixado por SHA (correto)
Regra rígida: Fixe cada ação de terceiros a um SHA de commit completo de 40 caracteres, não a uma tag de versão. actions/* (primeira parte) pode usar tags de versão principal.
7. Adulteração de Lockfile / Desvio de Integridade (Classe PackageGate)
Atacante modifica o lockfile para substituir uma versão de pacote maliciosa ou remove hashes de integridade para que a próxima instalação busque silenciosamente um tarball diferente. Seis vulnerabilidades de lockfile zero-day documentadas em janeiro de 2026 (Koi Security). Detectar:
grep -E '"resolved".*git\+|tarball' package-lock.json pnpm-lock.yaml
grep -v "integrity" pnpm-lock.yaml | grep "resolved"
Regra rígida: CI deve usar pnpm install --frozen-lockfile ou npm ci — nunca npm install simples.
8. Sombra de Subdependência
Atacante alveja uma dependência transitória de 3+ níveis de profundidade. @ctrl/tinycolor foi um nó de propagação do Shai-Hulud.
Detectar: npm ls --all 2>/dev/null | grep -E "postinstall|preinstall". Use socket scan em PRs.
9. Engenharia Social para Transferência de Mantenedor
Atacante se passa por recrutador ou parceiro de negócios para obter direitos de publicação npm. UNC1069 (RPDC) mirou o mantenedor do Axios em março de 2026, também tentou contra o CEO da Socket, criador do Lodash, líder do Fastify.
Detectar: npm owner ls <pkg> para dependências críticas; monitore novos colaboradores antes de um lançamento suspeito.
10. Protestware (Sabotagem Intencional de Mantenedor)
Mantenedor injeta intencionalmente código destrutivo. colors.js v1.4.44–1.4.2 (janeiro de 2022, loop infinito), node-ipc v10.1.1–10.1.3 (março de 2022, deletou arquivos em IPs russos). Três novas versões maliciosas de node-ipc em maio de 2026.
Detectar:
npm diff <pkg>@<anterior> <pkg>@<nova> -- lib/
grep -r "networkInterfaces\|geoip\|fs.rmdir\|fs.unlink" node_modules/<pkg>/
Fixe node-ipc, colors, faker em versões exatas conhecidas como boas.
11. Malware Autorreplicante de Tipo Verme
Payload rouba tokens npm/PATs e publica autonomamente versões maliciosas de outros pacotes que a vítima mantém. Primeiro observado Shai-Hulud setembro de 2025; Mini Shai-Hulud maio de 2026 (300+ pacotes, 16M downloads semanais, npm + PyPI simultaneamente). Detectar IOCs:
find .github/workflows -name "*.js" # bundle.js em workflows
grep -ri "shai-hulud" . # string do verme
find node_modules -name "data.json" -newer package.json # armazenamento de exfiltração
find node_modules -name "cloud.json"
12. Payloads Dormentes / Condicionais a Ambiente
Payload só ativa quando AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN ou CI=true está presente — evade scanners em sandbox.
Detectar:
grep -r "process.env.AWS_SECRET\|process.env.GITHUB_TOKEN\|process.env.NPM_TOKEN" node_modules/
Sinalize qualquer pacote lendo essas variáveis que não tenha motivo legítimo para fazê-lo.
13. Ferramenta de Segurança como Vetor de Ataque
Atacantes miram especificamente ferramentas de escaneamento de segurança (Trivy, KICS, Semgrep) porque elas executam com acesso elevado a segredos e configuração de infra em CI. Trivy e KICS foram atingidos em março–abril de 2026. Regra rígida: Fixe todas as imagens Docker de ferramentas de segurança ao digest, não à tag. Verifique digests fora de banda contra as notas de lançamento do fornecedor.
14. Dependências Não-Registro / CDN
Pacotes resolvidos de URLs git, tarballs do GitHub ou CDNs personalizadas (ex.: cdn.sheetjs.com) ignoram os gates de segurança e proveniência do registro, e também não são cobertos pelo gate de idade de release — ele só se aplica a versões do registro. Alguns carecem completamente de hashes de integridade. Nada bloqueia estes automaticamente; eles devem ser detectados em revisão.
Detectar:
grep -E '"resolved".*github\.com|cdn\.' package-lock.json pnpm-lock.yaml
grep -E '"version":\s*"(git\+|https?:)' package.json
Higiene de npm/pnpm por projeto
- Faça commit dos lockfiles. CI deve usar
pnpm install --frozen-lockfile(ounpm ci). Nuncanpm installsimples em CI. - Fixe
packageManagerempackage.jsonpara travar a versão do pnpm/npm. - Fixe pacotes em namespaces comprometidos a versões exatas:
@tanstack/*,posthog-node,@mistralai/*,@langchain/mistralai,@ctrl/*,ngx-*,rxnt-*,@zapier/*,@postman/*,@uipath/*,agent-mcp,@semgrep/*,node-ipc,colors,faker. - Sem versões curinga
"*"empackage.json. - Sem URLs
pkg.pr.new— estes são builds de pré-visualização de PR efêmeros, não artefatos imutáveis. - Para projetos npm/yarn, espelhe os mesmos gates de npmrc no
.npmrclocal. - Prefira pnpm para novos projetos. Não migre projetos funcionais apenas por segurança.
Fortalecimento do GitHub Actions
Regras rígidas
- Nunca use
pull_request_targetse o workflow checkout o código do PR, executar install/build/test a partir do código do PR, ou compartilhar cache com um workflow privilegiado. pull_request_targetsó é aceitável para ler metadados do PR (labels, comentários, título) sem checkout.- Não compartilhe caches entre jobs acionados por PR e jobs de publicação/release.
- Nunca use
curl | bashouwget | shcontra um branch mutável (@main,@master) em CI. Sempre fixe scripts de instalação a um release específico e verifique um checksum.
Proteções workflow_run
Ao usar workflow_run para encadear um job privilegiado após um workflow pai, o if: DEVE afirmar tudo isso:
if: >
github.event_name == 'workflow_dispatch' ||
(github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'main' &&
github.event.workflow_run.head_repository.full_name == github.repository &&
github.event.workflow_run.event == 'push')
Fixação de ação
- Fixe cada ação de terceiros a um SHA de commit completo de 40 caracteres, não
@v1/@v6. - Adicione um comentário com a tag legível para auditabilidade:
docker/login-action@65d0a9e # v3 - Ações de primeira parte
actions/*podem usar tags de versão principal. - Obter SHAs atuais:
gh api repos/<owner>/<action>/git/ref/tags/<tag> - Automatize com:
npx pin-github-action .github/workflows/*.yml - Minimize
permissions:por job. Padrão paracontents: read. Adicioneid-token: writeapenas no passo de publicação.
Workflows de publicação npm
- Exija 2FA na conta npm:
npm profile enable-2fa auth-and-writes. - Use publicação confiável (OIDC) em vez de segredos
NPM_TOKENde longa duração. - Adicione
--provenance(ouprovenance: true) para que consumidores possam verificar a origem. - Publique apenas a partir de um
release.ymlacionado por push de tag emmain. Nunca a partir de workflows acionados por PR.
Higiene de Docker/contêiner
- Fixe cada
FROMa um digest:FROM node:22-slim@sha256:<hash> - Nunca use
latestou imagens sem tag em Dockerfiles de produção ou CI. - Imagens de ferramentas de segurança (Trivy, KICS, Semgrep, Snyk, Grype, Hadolint) são de maior risco — fixe estas primeiro.
- Obter digests atuais:
docker buildx imagetools inspect node:22-slim --format '{{json .Manifest.Digest}}' - Para imagens de registro privado: publique com tags imutáveis + digests.
Ferramentas de desenvolvedor e arquivos de configuração
- Nunca armazene tokens de API ou segredos em texto simples em
~/.cursor/mcp.json,~/.claude/settings.jsonou arquivos de configuração similares. Use variáveis de ambiente ou um chaveiro. - Fixe pacotes de servidor MCP a versões exatas (
[email protected], nãomcp-remote@latest). - Verifique
~/.vscode/tasks.jsone~/.cursor/para hooks inesperados de execução automática após qualquer incidente na cadeia de suprimentos.
Detecção / monitoramento
- Instale zizmor ou
snyk-labs/github-actions-scannerem CI para qualquer repositório com workflows. - Adicione o socket.dev GitHub App em qualquer repositório que publique pacotes (qualquer biblioteca publicável).
- Inscreva-se nos feeds RSS de avisos de segurança npm e feeds de malware PyPI.
Checklist de varredura rápida de IOC
# Shai-Hulud / IOCs de verme
grep -ri "shai-hulud" .
find .github/workflows -name "*.js"
find node_modules -name "cloud.json"
# Padrões de workflow comprometidos
grep -r "pull_request_target" .github/workflows/
grep -r "curl.*|.*sh\|wget.*|.*sh\|base64.*eval" .github/workflows/
# Ações não fixadas
grep -r "uses:.*@v[0-9]" .github/workflows/
# Dependências exóticas de lockfile
grep -E '"resolved".*git\+|cdn\.' package-lock.json pnpm-lock.yaml
grep -v integrity pnpm-lock.yaml | grep resolved
# Docker
grep -r "FROM.*:latest\|FROM.*[^@]$" Dockerfile* docker-compose*.yml