SBOMVault.ai
← Back to blog
Engineering

Transitive dependencies: the 80% of your SBOM you never wrote

May 12, 2025·6 min read·SBOMVault Team

Ask an engineer how many dependencies their application has and they will usually name the handful in their package manifest. Ask their SBOM and you will get a number ten or twenty times larger. The gap between those two numbers is the most underappreciated risk in modern software, and it has a name: transitive dependencies.

Direct versus transitive

A direct dependency is one you chose — a library you deliberately added to your project. A transitive dependency is one your dependencies brought along: the libraries they depend on, and the libraries those depend on, all the way down.

You wrote, or at least selected, the direct ones. The transitive ones arrived without a decision. And in a typical project, transitive dependencies outnumber direct ones by a wide margin — frequently making up 80 percent or more of the total component count.

Why this is where the risk lives

Three reasons transitive dependencies punch above their weight:

  1. You did not vet them. You evaluated the framework you adopted. You almost certainly did not evaluate the forty libraries it pulled in.
  2. You may not know they are there. Without an SBOM, transitive dependencies are effectively invisible — they do not appear in your manifest or your mental model.
  3. Vulnerabilities do not care how a component arrived. A critical flaw in a package three levels deep is exactly as exploitable as one you imported directly. Log4Shell was, for most victims, a transitive dependency.

The Log4Shell lesson

When Log4Shell broke in December 2021, the hardest question for most organizations was not "how do we patch Log4j?" It was "do we even use Log4j, and where?" For countless teams, Log4j was not something they had chosen — it was buried deep in the dependency trees of other software. The teams that suffered longest were the ones who could not answer the "where" question quickly.

What an SBOM does about it

This is precisely the problem a Software Bill of Materials exists to solve. A complete SBOM captures the full dependency graph, not just the top layer — every transitive component, its version, and its relationship to the things above it. That turns "do we use this, and where?" from a multi-day investigation into a single query.

But note the word complete. An SBOM that only records direct dependencies gives you a comforting, misleading picture. Depth is not a nice-to-have; it is the entire point. When you evaluate SBOM tooling, the first thing to check is whether it resolves the full transitive graph or stops at the manifest.

Reachability: the next layer of nuance

Knowing a vulnerable transitive dependency exists is step one. The harder question is whether it actually matters. A critical CVE in a transitive package you never actually call is a much smaller risk than one on a hot code path.

This is where reachability analysis comes in — determining whether vulnerable code is actually used by your application, not merely present in the tree. It is what separates "you have 847 critical vulnerabilities" from "you have 12 that are reachable and worth fixing this week." Transitive visibility tells you what you have; reachability tells you what to do about it.

The takeaway

The code you write is the small, visible tip of what you ship. The bulk of your attack surface is inherited, transitive, and invisible until you inventory it. You cannot secure what you cannot see — and for most applications, most of what you ship is exactly what you cannot see without an SBOM.