Safeguard
DevSecOps

Dependency Management Best Practices for Secure Software

Your app is mostly other people's code. A 2026 guide to managing dependencies securely — lockfiles, provenance, SBOMs, update strategy, and reachability — so a bad package doesn't become your breach.

Priya Mehta
DevSecOps Lead
5 min read

The uncomfortable truth of modern software is that you wrote very little of it. A typical application is 80-plus percent third-party code by volume — direct dependencies you chose, and a much larger cloud of transitive dependencies you never evaluated and often don't know exist. Every one of them runs with your application's privileges. When event-stream was handed to a malicious maintainer in 2018, when the XZ Utils backdoor (CVE-2024-3094) was caught by luck in 2024, and when the chalk/debug npm accounts were phished in September 2025 to push wallet-stealing code across packages with billions of weekly downloads — the victims weren't careless. They just had no systematic way to know what was in their supply chain or to react when part of it turned hostile. Dependency management is the discipline of getting that control back.

Know exactly what you depend on

You cannot secure what you cannot enumerate, and "look at package.json" doesn't cut it — that shows direct dependencies, not the transitive graph where most risk hides. The foundation is a generated, versioned software bill of materials for every build. An SBOM is a complete, machine-readable inventory of every component and version in an artifact, and when a new disclosure lands, it turns "are we affected by this?" from a multi-day investigation into a query you run in seconds. Generate it as a build step, store it, and keep it current — a stale SBOM is worse than none because it lies with confidence.

Pin everything and build reproducibly

A build that resolves "latest compatible" at install time is a build an attacker can influence after you've reviewed the code. Commit lockfiles and enforce reproducible installs so every build is byte-for-byte identical and a compromised registry can't silently swap a tarball:

# Enforce clean, locked installs in CI — never resolve fresh
steps:
  - run: npm ci                       # fails if lockfile is out of sync
  # Python: pip install --require-hashes -r requirements.txt
  # Go:     GOFLAGS=-mod=readonly go build ./...

Pin exact versions, not ranges, and require hash verification where the ecosystem supports it. The npm ci command (versus npm install) is the difference between "install what the lockfile says" and "resolve whatever satisfies the range today."

Verify provenance and defend against confusion attacks

Two supply-chain attack classes exploit naming rather than code. Typosquatting relies on a mistyped package name (crossenv for cross-env) resolving to attacker-controlled code. Dependency confusion, demonstrated against PayPal, Microsoft, and Apple in 2021, exploits build tools that resolve an unscoped internal package name from the public registry instead of your private one. Defenses:

  • Scope internal packages (@yourco/utils) and configure per-scope registry mappings so resolution is never ambiguous.
  • Treat brand-new packages and single-maintainer packages with low commit velocity as elevated risk before adopting them.
  • Where available, verify package provenance attestations (npm and PyPI now support cryptographic provenance linking a package to the source repo and build that produced it).

Prioritize by reachability, not by raw CVE count

Once you can enumerate dependencies, a scanner will report a lot of CVEs — and treating them as equally urgent is how alert fatigue kills the whole effort. Version-based scanning flags a vulnerability if a package version contains it, regardless of whether your code ever calls the affected function. Reachability analysis traces whether the vulnerable symbol is actually invoked from your call graph, and it typically shrinks the "fix now" list dramatically. Combine reachability with exploit signals (EPSS probability, CISA KEV status) so the top of your queue is reachable, exploitable findings and everything else is honest backlog. This is the single highest-leverage practice in dependency security: it's the difference between a scanner developers trust and one they mute.

Automate safe updates on a cadence

Manual dependency updates don't happen — they slip until a patch is a painful, multi-version leap. Automated update tooling (Dependabot, Renovate, or a platform's auto-fix) opens pull requests for new versions continuously, with your test suite as the safety net. The nuance for security: auto-merge patch updates for well-tested dependencies to stay current with zero friction, but require human review for major-version bumps and for any package with a single maintainer or a recent ownership change, since a hijacked package's malicious release will also present as "a new version."

Dependency hygiene checklist

  • SBOM generated and stored for every build
  • Lockfiles committed; npm ci / --require-hashes in CI
  • Exact version pins, no floating ranges in production
  • Internal packages scoped; per-scope registry mappings set
  • New/single-maintainer packages reviewed before adoption
  • Findings prioritized by reachability + EPSS/KEV
  • Patch updates automated; major bumps gated on review
  • Unmaintained dependencies flagged for replacement

How Safeguard Helps

Safeguard treats the dependency graph as a first-class object. SBOM Studio generates and continuously updates a queryable bill of materials for every project, so a new disclosure is a lookup. Our SCA engine computes reachability against your call graph and enriches findings with EPSS and KEV, so you patch the exploitable few and defer the theoretical many. When a safe upgrade exists, auto-fix opens a tested pull request and keeps you current without the friction that makes updates pile up. If you're evaluating reachability-based SCA against alternatives, our Safeguard vs Snyk comparison breaks down the differences.

Map your dependency risk free at app.safeguard.sh/register, or read the SCA and SBOM guides at docs.safeguard.sh.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.