The Dependency Nobody Remembers Approving
Staff Writer · · 3 min read

# The Dependency Nobody Remembers Approving
A production service had a transitive dependency four levels deep maintained by a single unpaid volunteer, last published two years ago, with an open critical vulnerability nobody on the team knew existed until a scan surfaced it. Nobody had approved this package. Nobody had heard of it. It came in bundled inside a dependency of a dependency, the way most of a modern application's actual code arrives — not through a decision, through a transitive closure nobody reviews line by line.
## Direct dependencies get scrutiny; everything under them doesn't
Every team I've reviewed has some process, formal or not, for adding a new direct dependency — someone proposes it, someone else glances at its popularity and last-commit date, it gets added. That scrutiny essentially never extends past one level. A package with twenty direct dependencies might easily pull in three hundred packages once transitive dependencies resolve, and the review that happened for the top-level twenty does not happen, cannot reasonably happen by hand, for the other two hundred eighty.
That's not a process failure specific to any one team — it's close to structurally unavoidable given how package ecosystems are built. The problem isn't that nobody reviews transitive dependencies carefully enough. It's that "review" as a human activity doesn't scale to the actual size of a modern dependency tree, and treating it as a checklist item that gets done rather than a property that needs continuous automated checking is where the risk hides.
## What a real audit checks isn't "are dependencies pinned"
The reassuring-sounding answer — "yes, we use a lockfile, our dependencies are pinned" — describes reproducibility, not safety. A pinned dependency tree pins in whatever was already there, vulnerabilities included, and keeps it stable indefinitely unless something forces an update. Pinning solves "does this build the same way twice." It does nothing for "is anything in this tree currently known to be exploitable," which is a question that changes daily as new CVEs get published against packages that were perfectly clean when they were pinned.
Answering the actual question requires running the dependency tree against a live vulnerability database — not once, as a one-time audit checkbox, but as a standing check, because a tree that's clean today can have a critical CVE published against one of its members next week with zero code changes on the project's own side. The finding in this review wasn't that the team had done something wrong when they added the vulnerable package's ancestor. It's that nothing in their process would ever tell them when a previously-clean dependency became a currently-risky one.
## The maintenance-health question due diligence usually skips
Beyond known vulnerabilities, the harder question to answer is dependency health going forward: is this package still maintained, and if the single maintainer disappears, does anything break. The volunteer-maintained package four levels deep had no CI, no recent commits, and a bus factor of one — meaning even a clean current scan wasn't durable information, because "clean today" for an unmaintained package is a snapshot with a short shelf life, not a stable property.
None of this shows up by reading the top-level package.json. It shows up by walking the full resolved tree, checking it against a current vulnerability feed, and separately checking maintenance signal on anything the tree depends on heavily — three checks that have almost nothing to do with reading the application's own code, and that most teams don't run until an audit forces the question.


