Safeguard
General•

An SBOM Tells You What Was Built, Not What Is Executed

Software Bill of Materials formats list every dependency in a package, but they completely miss whether that code path ever runs in production.

Safeguard
3 min read

The Static Inventory Trap

A Software Bill of Materials lists every library, package, and transitive dependency present in a build artifact. Security teams collect these inventories to satisfy compliance mandates and regulatory frameworks. When a critical vulnerability appears in a widely used logging library, the first instinct is to query the SBOM database across every repository.

The search returns fifty matches. Every single one of those repositories includes the vulnerable package. The incident response playbook kicks off emergency patching cycles across dozens of engineering teams. Hours later, code reviews reveal a quiet detail: the vulnerable function sits inside a parsing module that is never imported, never compiled into the binary, and completely absent from runtime memory.

The SBOM told you what was shipped in the bundle. It told you nothing about what executed.

How Build Pipelines Package Ghost Code

Modern dependency graphs are enormous. Package managers pull in massive trees of utility functions, formatters, and protocol handlers to satisfy a single explicit requirement in a manifest file. Build tools like Webpack, Maven, Go modules, and cargo include these packages because they are referenced in import statements, even if those specific files are dead branches.

Tree shaking and dead code elimination help reduce binary sizes, but they are imperfect. Conditional compilation flags, environment-specific build tags, and dynamic module loaders often force compilers to retain code paths that are logically unreachable during standard execution.

Consider a typical Node.js microservice that includes a multi-format document parser because it shares a common utility library with an offline document conversion tool. The microservice only handles JSON payloads over HTTP. The XML and PDF parsing libraries sit silently in node_modules, consuming disk space and appearing prominently in every generated CycloneDX or SPDX document.

When a remote code execution vulnerability is discovered in the XML parsing library, your vulnerability scanner flags the repository with high severity. The finding is technically accurate regarding the presence of the file on disk. It is functionally irrelevant to the running process.

The Cost of False Positives in Prioritisation

Treating every SBOM match as an active exposure breaks developer trust. When security teams demand immediate patches for vulnerabilities in dead code paths, engineers spend valuable sprints upgrading packages that process zero production traffic.

This volume of noise creates alert fatigue. When a genuine vulnerability strikes an active code path, it blends into the background roar of hundreds of unexploitable findings.

Compliance frameworks mandate SBOM generation because visibility is better than blindness. But visibility without context is just an expanded attack surface for anxiety. Knowing that a package exists in a tarball is a prerequisite for security. Knowing whether user input can reach that package is the actual job.

Moving From Static Manifests to Runtime Verification

Fixing this requires connecting static dependency analysis with dynamic execution tracing. Instead of asking what is inside the container image, ask what symbols are loaded into memory during startup and runtime.

Language runtimes and binary loaders know which functions are actually invoked. Instrumenting your deployment pipeline to record symbol resolution or tracing function calls during integration test suites reveals the true execution graph.

If a vulnerability scanner flags a package, query your runtime reachability data before opening an emergency ticket. If the call stack cannot reach the vulnerable function under any valid configuration, deprioritise the finding.

Focus engineering remediation effort on components that actually process untrusted data. Leave the dead code for the next routine dependency refresh cycle. An accurate inventory accounts for code that runs, not just code that exists.

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.