Safeguard
Supply Chain•

What manifest-only dependency scanning misses

Older composition analysis reads manifests and stops. Here is what that misses: resolved transitive versions, vendored code, images and reachability.

Safeguard Security Team
3 min read

Scanners that only read a manifest such as package.json or pom.xml see the version ranges you wrote, not the versions you actually ship. They miss resolved transitive packages, vendored copies, container layers and any sign of whether vulnerable code runs. Ask a vendor which of these gaps its tool closes.

Declared is not resolved

A manifest says "any version from 4.17 up". A lockfile says "4.17.21". Only the second tells you what is installed. A tool that matches ranges against advisories will either over-report, flagging versions you do not use, or under-report, missing the version the resolver actually picked.

Resolved trees also include transitive dependencies, the packages your packages depend on. In most ecosystems these outnumber direct dependencies by a wide margin, and many serious advisories land in them.

Five gaps to test

  1. Transitive depth. Ask to see the full path from your direct dependency to the vulnerable package. If the tool cannot show the chain, remediation turns into a guessing exercise.
  2. Lockfiles and build output. Does it read lockfiles, or resolve the build itself? Different approaches give different answers for dynamic or workspace-based builds.
  3. Vendored and copied code. Libraries copied into a source tree have no manifest entry. Matching them needs file or snippet fingerprints.
  4. Container and OS layers. The application manifest says nothing about the base image packages. A separate image scan, or a platform that does both, is needed.
  5. Reachability. Presence in the tree and execution in your code are different facts. Without call analysis, every finding looks equally urgent.

How to test your own tool in an hour

Pick one service you know well and run this sequence.

  • Count the direct dependencies in the manifest, then count the components the tool reports. If the numbers match, it is probably reading only the manifest.
  • Pin an old, known vulnerable version of a deep transitive package in a scratch branch and see whether the tool flags it and shows the path.
  • Copy a small open source file into the tree without a manifest entry. See whether it is noticed.
  • Scan the container image built from the same service and compare the result with the source scan.

Write down what each test returns. A gap is not a reason to throw the tool out, but it tells you what other controls you need.

When manifest scanning is fine

For a small library with a handful of direct dependencies, committed lockfiles and no containers, a simple scanner may be enough. The gaps matter as the dependency tree grows, as build systems get more dynamic and as you ship images.

Where Safeguard fits: its SBOM and dependency scanning covers resolved dependency inventories and reachability analysis, and the free scan shows the output on a public repository.

Try it yourself

Click through it at your own pace, or open it full screen.

Open a package and look for the dependency path, then compare it with what your current scanner shows.

Quick check

Is a lockfile always enough to get an accurate tree?

It is a good starting point, but it does not cover vendored code or image layers, and it can drift from what a build actually installs.

Do I need reachability if I fix everything anyway?

If your backlog is small, no. If it is not, reachability helps decide what to fix first.

Last reviewed: 19 October 2026.

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.