The XZ Utils backdoor in 2024 demonstrated how a sophisticated attacker can compromise a widely-used open source library through a long-term social engineering campaign. Your application depends on hundreds of packages — each one is a potential attack vector.
Know what you're running
Generate a Software Bill of Materials (SBOM) for every build. An SBOM lists every dependency, transitive dependency, their versions, and known vulnerabilities. Tools like Syft (for containers) and CycloneDX generate SBOMs automatically. Attach the SBOM to your release artifacts. Use Grype to scan SBOMs for known CVEs.
Dependency pinning and verification
Use lockfiles (package-lock.json, yarn.lock, Cargo.lock) and never ignore them. Pin to exact versions in production. Enable npm ci instead of npm install in CI — it installs exactly what's in the lockfile. Verify package integrity with checksums. Use --ignore-scripts where possible to prevent postinstall scripts from running arbitrary code.
Dependency confusion attacks
An attacker publishes a public npm package with the same name as your private internal package — at a higher version number. npm's resolution prefers the higher public version. Mitigation: use scoped packages for all internal packages (@yourorg/internal-lib). Configure your package manager to always use your private registry for your scope. Verify all published package names.
Secure your CI/CD pipeline
Your CI pipeline has elevated access to secrets, deployment environments, and code repositories. Treat it as a privileged target. Use short-lived OIDC credentials instead of long-lived API keys. Limit each pipeline job's permissions to the minimum needed. Pin GitHub Actions to a specific commit SHA, not a branch or tag (actions/checkout@a81bbbf8, not actions/checkout@v4). Audit and review third-party Actions before use.
Code signing
Sign your build artifacts with Sigstore's Cosign. Anyone consuming your artifacts can verify they were produced by your pipeline and haven't been tampered with. Configure your Kubernetes admission controller to reject unsigned images. This closes the gap between "built by our pipeline" and "deployed to production."
Automated dependency updates
Enable Dependabot or Renovate for automated dependency updates. Outdated dependencies with known CVEs are the most common supply chain vulnerability — and the most preventable. Configure auto-merge for patch updates with passing tests. Review minor and major updates manually. Never let dependencies go stale.