12 Best Practices to Prevent Software Supply Chain Attacks

Software supply chain attacks have surged, with tools like Axios, LiteLLM, and Trivy all compromised in early 2026 alone. This guide covers 12 actionable best practices every engineering team should implement, from dependency pinning and SBOMs to CI/CD hardening and compliance alignment.

16 min read·

TL;DR

Key Point Summary
The problem Supply chain attacks are accelerating, with global losses reaching $60 billion and major compromises (Axios, LiteLLM, Trivy) hitting in early 2026
Who's at risk Every team shipping software with third-party dependencies (which is everyone)
This guide 12 actionable best practices, each mapped to real-world attacks and compliance controls
Compliance tie-in SOC 2 CC9.2, ISO 27001 A.5.19-A.5.21 and A.8.28 all require supply chain security

Quick Answer: Lock your dependencies to exact versions and hashes, generate SBOMs, enforce MFA on all registry accounts, harden CI/CD pipelines with short-lived credentials, and treat open-source libraries as vendors in your compliance program. This post gives you the full playbook.


In September 2025, software developer Tane Piper published a meditation on npm supply chain attacks that quickly climbed to the top of Hacker News. His central argument was blunt: platform owners have done too little, and the ecosystem remains dangerously exposed.

Six months later, the data proves him right. The first quarter of 2026 alone brought the Axios npm compromise (100M+ weekly downloads, RAT deployed via maintainer account hijack), the LiteLLM PyPI attack (97M monthly downloads, credential-stealing malware that persisted across package removal), and a cascading breach that started with Trivy and spread to Checkmarx and LiteLLM through a single compromised CI pipeline.

These are not edge cases. They are the new baseline. If your team ships software with third-party dependencies, you need a systematic defense. This guide covers 12 concrete best practices you can implement today.

The Attack Vectors You're Defending Against

Before diving into defenses, it helps to understand what attackers actually do. Modern supply chain attacks cluster around five main vectors:

1. Compromised Maintainer Accounts

An attacker steals the credentials of a trusted package maintainer, then publishes malicious versions through official channels. This is how the Axios attack worked: the primary maintainer's npm account was hijacked, and two malicious versions were published within 39 minutes. Because the package name and publisher were legitimate, automated checks passed.

2. CI/CD Pipeline Exploitation

Attackers target the build and deployment infrastructure itself. The Trivy breach started with a misconfigured GitHub Actions workflow that leaked CI/CD secrets and signing credentials. From there, the attackers (tracked as TeamPCP) pivoted to compromise Checkmarx KICS and ultimately LiteLLM's PyPI publishing pipeline, a textbook cascading attack.

3. Typosquatting and Dependency Confusion

Attackers publish packages with names that are slight misspellings of popular libraries (axois instead of axios) or exploit the resolution order between private and public registries to inject malicious packages. The Shai-Hulud campaigns in 2025 combined stolen credentials with automated package injection to compromise over 796 packages.

4. Malicious Code Injection via Build Scripts

npm's postinstall scripts run arbitrary code during package installation, before your application even starts. As Piper demonstrated back in 2017, a single npx invocation can execute code without user interaction. Several commenters in the Hacker News discussion highlighted that switching to pnpm (which disables post-install scripts by default) is one of the simplest mitigations available.

5. Social Engineering of Open-Source Projects

The most sophisticated attacks invest time. The XZ Utils backdoor (CVE-2024-3094, CVSS 10.0) involved a threat actor who spent over two years contributing to the project under the alias "Jia Tan," building trust until they gained maintainer access. Only a lucky catch by a Microsoft engineer, Andres Freund, who noticed abnormal CPU usage during SSH logins, prevented a catastrophe.


12 Best Practices to Prevent Supply Chain Attacks

1. Pin Dependencies to Exact Versions and Hashes

The problem: Flexible version ranges like ^1.14.0 automatically pull new releases, including compromised ones. During the Axios attack, any project using caret ranges on the 1.x branch auto-installed the malicious 1.14.1.

What to do:

  • Use exact versions (1.14.0, not ^1.14.0) in your package manifests
  • Use lockfiles (package-lock.json, poetry.lock, Pipfile.lock) and commit them to version control
  • Install with lockfile-only commands in CI: npm ci (not npm install), pip install --require-hashes
  • For GitHub Actions, pin to full commit SHAs, not version tags (tags are mutable and can be force-pushed)
JSON5
// BAD: caret range auto-installs malicious 1.14.1
"axios": "^1.14.0"

// GOOD: exact version, only updates when you choose
"axios": "1.14.0"
YAML
# BAD: tag can be force-pushed to malicious commit
- uses: aquasecurity/trivy-action@v1

# GOOD: pinned to specific, immutable commit SHA
- uses: aquasecurity/trivy-action@a1b2c3d4e5f6...

Compliance mapping: SOC 2 CC8.1 (change management), ISO 27001 A.8.28 (secure coding)


2. Enforce MFA on All Package Registry Accounts

The problem: Most major compromises in 2025-2026 (Axios, Shai-Hulud) started with stolen maintainer credentials. But attack vectors vary: the NX Singularity attack exploited a GitHub Actions injection vulnerability, not stolen credentials. Where credential theft is the vector, MFA is the most effective defense. If the Axios maintainer's npm account had required a hardware security key, the attack would not have succeeded.

What to do:

  • Require MFA for all team members with npm, PyPI, or any package registry access
  • Prefer hardware security keys (FIDO2/WebAuthn) over TOTP
  • Use organization-level registry accounts with role-based access rather than personal accounts
  • Audit registry access quarterly and remove stale accounts

Compliance mapping: SOC 2 CC6.1 (logical access), ISO 27001 A.8.5 (secure authentication)


3. Generate and Maintain SBOMs

The problem: You cannot defend what you cannot see. When a compromised package is announced, teams without a Software Bill of Materials (SBOM) scramble to figure out whether they are affected. During the Trivy-to-LiteLLM cascade, organizations with SBOMs identified their exposure in minutes; others took days.

What to do:

  • Generate SBOMs as part of your CI/CD pipeline using tools like Syft, CycloneDX, or SPDX
  • Store SBOMs alongside release artifacts
  • Use SBOMs to automate vulnerability matching when new advisories drop
  • Track transitive (indirect) dependencies, not just direct ones
Bash
# Generate an SBOM for a Node.js project
syft dir:. -o cyclonedx-json > sbom.json

# Generate for a Docker image
syft myapp:latest -o spdx-json > sbom.spdx.json

CISA's 2025 Minimum Elements for SBOMs provides the authoritative guidance on what your SBOM should contain.

Compliance mapping: SOC 2 CC3.2 (risk assessment), ISO 27001 A.5.21 (ICT supply chain), A.8.28 (secure coding)


4. Harden CI/CD Pipelines

The problem: CI/CD systems are high-value targets because they hold publishing credentials, cloud access keys, and deployment secrets. The Trivy breach gave attackers access to signing credentials that they used to publish infected binaries through official channels. The NX Singularity attack exploited a GitHub Actions injection vulnerability to compromise the build pipeline, proving that CI/CD exploitation goes beyond credential theft.

If your repository is public, CI/CD hardening is critical. Public repos expose your workflow definitions to anyone. Attackers can study your pipelines, identify misconfigurations, and craft targeted exploits. Treat every public workflow as an attack surface and harden it to the maximum level.

What to do:

  • Use short-lived tokens (OIDC) instead of long-lived Personal Access Tokens for CI authentication
  • Restrict secret access to only the workflow steps that need them
  • Implement allow-lists for network egress in CI environments to prevent data exfiltration
  • Audit pull_request_target triggers in GitHub Actions workflows (these run with elevated privileges and were the initial vector in the Trivy attack)
  • Review all third-party GitHub Actions for security posture before adoption
YAML
# Use OIDC for short-lived credentials instead of stored secrets
permissions:
  id-token: write
  contents: read

steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/deploy
      aws-region: us-east-1

Compliance mapping: SOC 2 CC6.1 (logical access), CC8.1 (change management), ISO 27001 A.8.9 (configuration management)


5. Disable or Sandbox Post-Install Scripts

The problem: Package managers like npm execute arbitrary code during installation through lifecycle scripts (preinstall, postinstall). This is the most direct path from "install a package" to "run attacker code."

What to do:

  • Switch to pnpm, which disables post-install scripts by default and lets you whitelist trusted packages
  • If you must use npm, set ignore-scripts=true in .npmrc and explicitly whitelist packages that need scripts
  • On Linux, use bubblewrap to sandbox package installations, blocking access to SSH keys, cloud credentials, and sensitive files
  • For high-security environments, isolate builds in ephemeral VMs or containers
INI
# .npmrc - disable scripts by default
ignore-scripts=true
Bash
# Sandbox npm install with bubblewrap (Linux)
bwrap --unshare-all --ro-bind / / \
  --dev /dev --tmpfs /tmp \
  --bind $(pwd) $(pwd) \
  npm install

Several participants in the HN discussion confirmed that switching to pnpm with script isolation is one of the highest-impact, lowest-effort mitigations available.

Compliance mapping: SOC 2 CC6.8 (system boundaries), ISO 27001 A.8.28 (secure coding)


6. Implement Dependency Update Delays

The problem: Most supply chain attacks are detected and removed within hours. If you auto-install the latest version the moment it is published, you are in the blast radius. If you delay by even 72 hours, you are likely safe.

What to do:

  • Configure tools like Renovate or Dependabot with a minimum release age (e.g., 3 days)
  • Fast-track updates only for published CVEs with known exploits
  • Review changelogs and diffs before merging dependency updates
  • Consider self-hosting a private registry mirror (Verdaccio for npm, devpi for PyPI) that buffers new releases
JSON5
// renovate.json - delay non-security updates by 3 days
{
  "extends": ["config:recommended"],
  "packageRules": [
    {
      "matchUpdateTypes": ["minor", "patch"],
      "minimumReleaseAge": "3 days"
    },
    {
      "matchUpdateTypes": ["major"],
      "minimumReleaseAge": "7 days"
    }
  ]
}

Compliance mapping: SOC 2 CC8.1 (change management), ISO 27001 A.8.8 (management of technical vulnerabilities)


7. Run Continuous Dependency Scanning

The problem: Vulnerability scanners catch known CVEs, but modern supply chain attacks often involve zero-day malicious code that traditional scanners miss. You need tools that analyze package behavior, not just known vulnerability signatures.

What to do:

  • Use behavioral analysis tools like Socket.dev that detect suspicious package behavior (network calls, file access, eval usage)
  • Complement with vulnerability scanners (Snyk, Dependabot, Trivy) for known CVE coverage
  • Pin your scanning tools themselves by version or SHA (the Trivy compromise proved that even security tools can be weaponized)
  • Integrate scanning into CI as a blocking check, not just a notification

Compliance mapping: SOC 2 CC7.1 (monitoring), ISO 27001 A.8.8 (management of technical vulnerabilities)


8. Minimize Your Dependency Surface

The problem: Every dependency is an attack surface. The npm ecosystem averages hundreds of transitive dependencies per project, and each one is a potential entry point. The LiteLLM attack spread because one project's CI pipeline had an unpinned dependency on Trivy, which itself had been compromised.

What to do:

  • Audit your dependency tree regularly with npm ls, pip list, or cargo tree
  • Remove unused dependencies (use tools like depcheck for Node.js)
  • Prefer well-maintained packages with multiple maintainers, provenance support, and security policies
  • Consider vendoring critical dependencies (copying source into your repo) for maximum control
  • Before adding a new dependency, ask: can we write this in 50 lines of code instead?
Bash
# Audit your dependency tree for unused packages
npx depcheck

# Check total dependency count
npm ls --all | wc -l

Compliance mapping: SOC 2 CC3.2 (risk assessment), ISO 27001 A.5.21 (ICT supply chain)


9. Adopt Build Provenance and Code Signing

The problem: Without provenance, you have no way to verify that a published package was actually built from the source code in its repository. An attacker who compromises a registry account can publish anything.

What to do:

  • Adopt SLSA (Supply Chain Levels for Software Artifacts) at Build Level 2 or higher
  • Use npm's built-in provenance support (--provenance flag) when publishing
  • Verify provenance of packages you consume using npm audit signatures
  • For internal packages, implement code signing with Sigstore for keyless, verifiable signatures
Bash
# Publish with provenance (npm)
npm publish --provenance

# Verify installed package signatures
npm audit signatures

Compliance mapping: SOC 2 CC8.1 (change management), ISO 27001 A.8.28 (secure coding), A.8.24 (use of cryptography)


10. Monitor for Anomalous Package Updates

The problem: Compromised packages often exhibit detectable anomalies: unexpected new dependencies, tag force-pushes, unusual version jumps, or changes in maintainer accounts. The Axios attack added a previously unknown dependency (plain-crypto-js@4.2.1), which was a purpose-built RAT dropper.

What to do:

  • Subscribe to security advisories for your critical dependencies (GitHub Security Advisories, npm audit, PyPI Safety DB)
  • Set up alerts for new dependencies added to packages you consume
  • Monitor for version tag force-pushes on GitHub Actions you use
  • Tools like Socket.dev provide automated anomaly detection for dependency changes

Compliance mapping: SOC 2 CC7.1 (monitoring), CC7.2 (incident response), ISO 27001 A.8.16 (monitoring activities)


11. Prepare a Supply Chain Incident Response Plan

The problem: When the Axios compromise was announced, teams without a pre-existing response plan spent hours figuring out how to assess impact. The Trivy incident showed what happens when incident response is incomplete: missed credentials led to a second breach within weeks.

What to do:

  • Document a specific runbook for "compromised dependency" scenarios
  • Include steps for: identifying affected systems (this is where SBOMs pay off), isolating compromised environments, rotating all credentials that may have been exposed, and notifying affected parties
  • Practice the runbook with tabletop exercises at least annually
  • After any incident, conduct root cause analysis and verify complete containment before declaring resolution

Example runbook outline:

  1. Identify: Query SBOM for affected package versions across all environments
  2. Contain: Pin to last known good version, block network egress from affected systems
  3. Eradicate: Remove compromised versions, scan for persistence mechanisms (the LiteLLM malware used .pth files that survived standard package removal)
  4. Recover: Rotate all credentials on affected machines, rebuild CI/CD pipelines from clean state
  5. Learn: Document root cause, update monitoring to detect similar patterns

Compliance mapping: SOC 2 CC7.3 (incident response), CC7.4 (incident recovery), ISO 27001 A.5.24-A.5.28 (incident management)


12. Treat Open-Source Dependencies as Vendors

The problem: Most compliance programs assess SaaS vendors but overlook open-source libraries that run in production with the same (or greater) access to data. An npm package running in your backend has the same blast radius as a SaaS integration.

What to do:

  • Include open-source dependencies in your vendor risk register
  • Categorize by risk tier based on access level and criticality (a UI icon library is not the same risk as an HTTP client or ORM)
  • Document risk acceptance decisions for high-risk dependencies
  • Review the security posture of critical packages: maintainer count, MFA status, provenance support, response time for past vulnerabilities

Compliance mapping:

Framework Control Requirement
SOC 2 CC9.2 Vendor risk management policies covering all third parties
ISO 27001 A.5.19 Information security in supplier relationships
ISO 27001 A.5.20 Security requirements in supplier agreements
ISO 27001 A.5.21 Managing security in the ICT supply chain
ISO 27001 A.8.28 Secure coding, including third-party library management

The Quick-Reference Checklist

Use this checklist as a starting point for your team's supply chain security program:

  • All dependencies pinned to exact versions with lockfiles committed
  • MFA enabled on all package registry accounts (npm, PyPI, RubyGems, etc.)
  • SBOMs generated and stored alongside every release
  • CI/CD pipelines use short-lived OIDC tokens, not long-lived PATs
  • Post-install scripts disabled by default (pnpm or .npmrc configuration)
  • Dependency updates delayed by 3+ days for non-security patches
  • Behavioral analysis tool (Socket.dev or similar) integrated into CI
  • Dependency tree audited quarterly, unused packages removed
  • Build provenance enabled for all published packages
  • Alerts configured for anomalous dependency changes
  • Supply chain incident response runbook documented and tested
  • Open-source dependencies included in vendor risk register

Why This Matters for Startups and SMBs

Large enterprises have dedicated security teams, procurement processes, and the leverage to demand SBOMs from vendors. Startups and SMBs typically do not, which makes them both more vulnerable and more likely to skip these controls.

But the math is straightforward:

  • Your attack surface is the same. A startup using Axios has the same exposure as a Fortune 500 company using Axios. The compromised version does not check your revenue before deploying a RAT.
  • Your blast radius may be larger. Small teams often have fewer environment boundaries, shared credentials, and less monitoring. A single compromised CI pipeline can give attackers access to everything.
  • Your compliance obligations require it. If you are pursuing or maintaining SOC 2 or ISO 27001, your auditor expects documented supply chain risk management. SOC 2 CC9.2 explicitly requires vendor management policies. ISO 27001 A.5.21 mandates ICT supply chain security. These are not optional.
  • Your customers expect it. Enterprise buyers increasingly include supply chain security questions in security questionnaires. Having a documented program with SBOMs and dependency monitoring is a competitive advantage.

The good news: most of these practices are free or low-cost. Lockfiles, exact version pinning, MFA, SBOM generation, and script sandboxing cost nothing but setup time. The return on that investment became very clear on March 31, 2026, when Axios was compromised.


Further Reading

Share this article

Other platforms check the box

We secure the box

Get in touch and learn why hundreds of companies trust Bastion to manage their security and fast-track their compliance.

Get Started