Novo: Eficify One em beta aberto. Crie seu primeiro ambiente sem cartão.Conhecer a plataforma →

Cadeia de dependências como vetor de ataque: um guia de decisão para blindar sua pipeline

Ilustração abstrata de uma corrente de elos representando dependências de software, com códigos e símbolos de segurança ao fundo, em tons de azul e cinza
CompartilharSeguir

O ataque à SolarWinds em 2020 não foi um incidente isolado, foi um divisor de águas. Desde então, a cadeia de suprimentos de software se tornou o terreno mais fértil para atacantes sophistication. O problema não está em escrever código malicioso do zero, está em injetar vulnerabilidades em bibliotecas que milhões de projetos importam automaticamente. E a maioria das equipes de engenharia ainda trata isso como opcional.

O problema real não é o que você escreve, é o que você importa

A cada npm install, pip install ou go get, você está confiando no maintainer de um pacote que provavelmente não conhece. Esse pacote traz consigo uma árvore de transitivos que pode ter dezenas ou centenas de outros pacotes. Em projetos maduros, é comum ter 500+ dependências diretas e mais de 2000 quando você conta os transitivos.

O dado que costuma chocar engenheiros: o código que você escreve representa tipicamente menos de 5% do código que executa em produção. Os outros 95% são dependências. Se você não audita esses 95%, está deixando a porta aberta.

Árvore de decisão: quando cada abordagem se justifica

Nem toda equipe precisa do mesmo nível de rigor. A decisão depende de três variáveis: exposição pública (é um produto SaaS? uma lib publicada no npm? um app interno?), compliance requirement (PCI-DSS, SOC 2, LGPD com DPO ativo?) e frequência de mudança (você deploya 50 vezes por dia ou uma vez por sprint?).

Caminho 1: Mínimo viável para equipes com baixa exposição

Se você tem um app interno com deploys raros e sem compliance obrigatório, comece com basics que custam quase zero:

  • Lockfiles versionados: commite package-lock.json, yarn.lock, Pipfile.lock, go.sum. Nunca faça deploy sem lockfile commitado.
  • Auditoria antes do primeiro deploy: rode npm audit, pip check, govulncheck manualmente antes de cada release significativa.
  • Atualização agendada: defina um rituais mensal de npm outdated ou Dependabot configurado com updates semanais.

npm audit --audit-level=high
govulncheck ./...
pip-audit

Armadilha comum: configurar o Dependabot e ignorar os PRs que ele abre. Você criou a ilusão de segurança sem o benefício real.

Caminho 2: Standard para equipes com deploy frequente ou exposição moderada

Aqui entram as ferramentas de SCA (Software Composition Analysis) integradas ao CI. O investimento é um de configuração, o retorno é cobertura contínua.

Ferramentas consolidadas e:

Ferramenta Ecossistema Integração nativa Custo
Snyk npm, pip, Maven, Go, Docker GitHub Actions, GitLab CI, Jenkins Freemium, plano pago por_org
Dependabot (GitHub) npm, pip, Gem, Docker GitHub Actions (nativa) Gratuito para repos públicos e privados
Trivy Multi (SBOM, images, config) GitLab CI, GitHub Actions, ArgoCD Gratuito (Aqua Security)
Grype Multi GitHub Actions, ArgoCD, admission controllers Gratuito (Anchore)
Socket.dev npm, pip GitHub PR comments, CI webhook Pago

A escolha entre Snyk, Grype e Trivy depende do seu existing toolchain. Trivy tem a melhor integração com Kubernetes e admission controllers. Grype é mais leve e mais rápido em imagens Docker. Snyk tem o maior DB de vulnerabilidades e melhor DX para desenvolvedores.

Configuração essencial no GitHub Actions:

name: Dependency Security
on: [pull_request, push]
jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high --fail-on=all

Gates que realmente bloqueiam: o --fail-on=all no Snyk ou --exit-code=1 no Grype são obrigatórios. Sem isso, o scan roda e você ignora o resultado, porque não quebrou o build.

Caminho 3: Enterprise ou regulated environment (fintech, healthtech, SaaS B2B com SOC 2)

Aqui o SCA isolado não basta. Você precisa de:

SBOM (Software Bill of Materials) gerado automaticamente: a SBOM é um inventário estruturado das suas dependências no formato SPDX ou CycloneDX. A ordem executiva dos EUA de 2021 já exige SBOM para fornecedores federais, e isso está se espalhando para contratos B2B.

# Gerando SBOM CycloneDX com Syft
syft packages . -o cyclonedx-json=sbom.json

# Gerando SBOM SPDX
syft packages . -o spdx-json=sbom.json

# Integrando no GitHub Actions
- name: Generate SBOM
  uses: anchore/sbom-action@v0
  with:
    image: ${{ env.IMAGE_TAG }}
    format: spdx-json
    output-file: sbom.spdx.json

Verificação de integridade com SLSA (Supply-chain Levels for Software Artifacts): SLSA é um framework do Google que define 4 níveis de maturidade para a cadeia de suprimentos. O nível 1 exige que o build seja reproduzível e que você tenha um provenance document. O nível 3 exige que o build seja isolado e que os artefatos sejam criptograficamente assinados.

# Exemplo de Attestation com Sigstore (cosign)
cosign attest --predicate-type=vuln/scan result.json myimage:latest

# Verificação no deploy
cosign verify \
  --certificate-identity=https://github.com/myorg/myrepo/.github/workflows/release.yml@refs/tags/v1.0.0 \
  --certificate-oidc-issuer=https://token.actions.githubusercontent.com \
  myimage:latest

Gates que combinam SBOM com política: você não quer apenas saber que existe uma vulnerabilidade, quer saber se ela está em um artefato que vai para produção. O fluxo ideal é: build gera SBOM, SBOM é scaneado contra CVDB, resultado é comparado com a lista de artefatos que vão para produção.

Mitigação de ataques de supply chain: além do scanning

Vulnerabilidades conhecidas são o cenário simples. Ataques ativos na cadeia de suprimentos são mais sofisticados e exigem defesas específicas.

Dependency confusion: atacantes publicam um pacote público com o mesmo nome de um pacote interno. Se seu package manager procurar em registries públicos antes do privado, você instala a versão maliciosa. Mitigação: use scoped packages (@mycompany/internal-lib) e configure seu registry para nunca buscar versões mais altas em registries públicos.

Typosquatting: lodahs vs lodash, requests vs requasts. Mitigação: use dependências por hash SHA256, não por versão semver.

// package.json com integridade verificada (npm)
"dependencies": {
  "lodash": "4.17.21"
}
// E no lockfile, o npm automaticamente adicionaintegridade:
// "integrity": "sha512-LBSonN2hsMK7V8"

Maintainer account takeover: o mantenedor do pacote que você confia é comprometido. Isso aconteceu com event-stream em 2018. Mitigação: use npm audit + socket.dev que detecta comportamento suspeito (envio de dados,stallation de binários, novas versões com mudança de maintainer).

Checklist acionável: do básico ao enterprise

  • Commite e versione todos os lockfiles (não faça npm install no deploy)
  • Integre um SCA scanner no CI com gate que bloqueia merge
  • Configure alerta para CVEs novas em suas dependências críticas
  • Gere SBOM em formato CycloneDX ou SPDX a cada release
  • Audite seus registries privados vs públicos (evite dependency confusion)
  • Use npm audit / pip check / govulncheck no pre-commit
  • Para ambientes regulados: implemente provenance attestation com cosign e SLSA nível 2+

Conclusão: segurança de dependências é infraestrutura, não feature

A diferença entre equipes que realmente mitigam esse vetor e as que fazem theater de segurança está em duas práticas: gate que bloqueia merge de verdade (não apenas alerta) e atualização de dependências como rituais estruturado, não como reação a um breach.

Ferramentas são commodities. O processo é o diferenciador. Você pode ter Snyk, Trivy, Grype e Socket instalados, mas se ninguém age sobre os resultados, você gastou dinheiro com falsa sensação de segurança.

O investimento mínimo que realmente funciona: lockfiles versionados, SCA com gate no CI, e um rituais de update quinzenal com owners definidos. A partir daí, SBOM e provenance são upgrades naturais conforme sua exposição cresce.


Se você não sabe quantas dependências vulneráveis estão no seu codebase hoje, esse é o primeiro risco a mapear. Em 30 minutos, a gente identifica onde seus gates de segurança estão falhando e o que muda para dormir tranquilo.

Fale com um especialista da Eficify

CompartilharSeguir
Bruno Carrilhos

SOBRE O AUTOR

Bruno Carrilhos

CTO · Eficify

Executivo de tecnologia, cofundador da Eficify, com mais de 20 anos de experiência na criação, evolução e sustentação de soluções digitais. Atua nas áreas de desenvolvimento de software, dados, inteligência artificial, cloud computing, cibersegurança e operações de missão crítica. É bacharel em Ciência da Computação, com formação em Ciência de Dados e Inteligência Artificial e pós-graduação em Segurança da Informação.

VAMOS CONVERSAR

Entregar em produção não precisa dar medo.

Conte seu cenário e receba um diagnóstico do seu fluxo de deploy e operação, sem compromisso.

Falar com um especialista