Safeguard
Open Source Security

What is Dependency Management

Dependency management means tracking, scanning, and patching the open source packages your app relies on -- here's how it works and why it matters.

Priya Mehta
DevSecOps Engineer
7 min read

Dependency management is the practice of tracking, updating, and securing the third-party code — libraries, frameworks, and packages — that a software project pulls in to avoid writing everything from scratch. A typical modern application isn't mostly original code: research from Synopsys' 2024 OSSRA report found open source components make up 77% of the average codebase, and a single Node.js project can easily resolve 800-1,200 transitive dependencies from a handful of direct package.json entries. Each of those packages is maintained on someone else's schedule, with its own release cadence, its own maintainers (or lack thereof), and its own vulnerability history. Dependency management covers four jobs: knowing what you have (inventory), knowing what's wrong with it (vulnerability and license scanning), deciding what to fix first (prioritization), and actually updating it (remediation) — ideally before an attacker finds the gap first, as happened with Log4Shell in December 2021.

How Does Dependency Management Actually Work?

Dependency management works by resolving a project's declared requirements into a full graph of installed packages, then continuously checking that graph against vulnerability, license, and maintenance data. When you run npm install, pip install -r requirements.txt, or mvn install, the package manager reads a manifest (package.json, requirements.txt, pom.xml) and a lockfile (package-lock.json, poetry.lock) to pin exact versions, then downloads not just your listed packages but everything those packages themselves depend on. A project that lists 40 direct dependencies commonly ends up with several hundred total packages once transitive dependencies are resolved — GitHub's own dependency graph data across public repos shows the average ratio of transitive-to-direct dependencies running well above 5:1 for JavaScript projects. Effective dependency management layers software composition analysis (SCA) tooling on top of this resolution step, cross-referencing every resolved package version against sources like the National Vulnerability Database (NVD), GitHub Security Advisories, and OSV.dev, then feeding results into a workflow that opens tickets, blocks CI builds, or generates pull requests automatically.

Why Do Vulnerable Dependencies Cause So Much Damage?

Vulnerable dependencies cause outsized damage because one flawed package can sit inside thousands of downstream applications simultaneously, turning a single CVE into a mass-exploitation event. Log4Shell (CVE-2021-44228), disclosed on December 9, 2021, affected Apache Log4j 2.0-beta9 through 2.14.1 — a logging library embedded in an estimated 35,000+ Java packages on Maven Central alone, per Google's Open Source Insights team. Within four days, Check Point reported over 800,000 exploitation attempts. The 2017 Equifax breach, which exposed the personal data of 147 million people, traced back to an unpatched Apache Struts CVE (CVE-2017-5638) that had a fix available for over two months before attackers used it. More recently, the xz-utils backdoor (CVE-2024-3094), discovered in March 2024, showed the risk runs deeper than unpatched code — a maintainer account compromised over roughly two years inserted a backdoor directly into a compression library used by OpenSSH on major Linux distributions. In all three cases, the vulnerable code wasn't written in-house; it arrived through a dependency tree the affected teams didn't fully see.

What's the Difference Between Direct and Transitive Dependencies?

Direct dependencies are the packages you explicitly declare in your manifest file; transitive dependencies are everything those packages pull in behind the scenes, and most of a project's actual risk lives in the latter. If your application lists express as a direct dependency, npm resolves it alongside roughly 60 transitive packages it needs internally — you never typed their names, but your production build ships them. Security research consistently finds transitive packages carry a disproportionate share of vulnerabilities: a 2023 Endor Labs study of open source Java and JavaScript projects found that over 95% of known vulnerabilities in a typical dependency tree originated in transitive, not direct, dependencies. This matters for remediation because you often can't simply "update" a transitive vulnerability — you have to update the direct dependency that pulls in the vulnerable version, wait for that maintainer to bump their own dependency, or use manifest-level overrides (overrides in npm, resolutions in Yarn) to force a patched version into the tree.

How Do SBOMs Fit Into Dependency Management?

A Software Bill of Materials (SBOM) fits in as the inventory layer that makes dependency management auditable and portable across tools and teams. An SBOM is a structured, machine-readable list of every component in a piece of software — typically in CycloneDX or SPDX format — including package names, exact versions, licenses, and cryptographic hashes. U.S. Executive Order 14028, issued in May 2021, pushed SBOMs from a niche practice into a procurement requirement for vendors selling software to federal agencies, with CISA publishing minimum elements guidance in July 2021. Practically, an SBOM lets a security team answer "are we affected by CVE-2024-3094" in minutes by searching a generated document instead of re-scanning every repository, and it lets downstream consumers of your software verify what's inside it without access to your source code. Without an SBOM, incident response after a disclosure like the xz backdoor often means grepping build logs across dozens of repos under time pressure.

Do Automated Dependency Updates Actually Reduce Risk?

Automated dependency updates reduce risk only when they're paired with testing and prioritization — applied blindly, they just move the risk from "vulnerable" to "broken." Tools like Dependabot (built into GitHub since 2019) and Renovate open pull requests automatically when a newer package version is available, and GitHub's own data shows repos with Dependabot enabled merge security PRs in a median of under 20 days versus much longer for manually tracked updates. But version bumps carry their own failure mode: semantic versioning is a convention, not a guarantee, and a "minor" update can still break a build — the 2022 node-ipc incident, where a maintainer added destructive code targeting users in specific countries, shipped through a routine-looking version bump. Effective automation filters updates by actual exploitability rather than raising every available bump as equally urgent, since most organizations can't realistically review and merge hundreds of dependency PRs a month.

How Often Should Teams Audit Their Dependency Tree?

Teams should audit their dependency tree continuously in CI on every build, not on a fixed calendar schedule, because new CVEs get disclosed against existing, unchanged code daily — the NVD published over 40,000 new CVE records in 2024 alone, many against packages already sitting in production dependency trees. A quarterly or annual audit means a team can carry a critical, actively-exploited vulnerability for months without knowing it, as many organizations did between Struts' patch release and the Equifax breach. Continuous scanning, gated at the pull-request and build stage, catches new dependencies and newly disclosed CVEs against existing ones the same day advisory data updates, and pairing that scan with a defined SLA (for example, remediate critical severity within 7 days, high within 30) turns "we should look at this eventually" into a tracked, enforceable process.

How Safeguard Helps

Safeguard turns dependency management from a spreadsheet exercise into a continuously enforced pipeline. It generates and ingests SBOMs across your repos so you have a queryable, up-to-date inventory the moment a new CVE like a future Log4Shell or xz-style backdoor drops, instead of scrambling to figure out what's affected. Reachability analysis then cuts through alert noise by determining whether a vulnerable function in a dependency is actually called by your code — filtering out the roughly 85-95% of flagged CVEs that sit in unreached code paths and pose no practical risk. Griffin, Safeguard's AI analysis engine, correlates that reachability data with exploit maturity and package maintenance signals to rank findings by real-world exploitability rather than raw CVSS score. Where a fix exists, Safeguard opens auto-fix pull requests with the minimal version bump needed to resolve the issue, tested against your build, so security teams spend their time reviewing prioritized fixes instead of triaging thousands of low-signal alerts.

Never miss an update

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