Safeguard
SBOM

Why 'We Have an SBOM' Isn't the Same as 'We Are Secure'

An SBOM tells you what's in your software, not whether it's safe. Here's why inventory alone can't stop supply chain attacks like XZ Utils or SolarWinds.

Vikram Iyer
Security Researcher
7 min read

In March 2024, a Microsoft engineer named Andres Freund noticed SSH logins on a Debian testing box taking about 500 milliseconds longer than they should have. That small anomaly led him to CVE-2024-3094 — a backdoor deliberately planted inside XZ Utils, a compression library that ships in nearly every Linux distribution on Earth. Here's the uncomfortable part: a software bill of materials would have told you that xz-utils 5.6.1 was present in your environment. It would not have told you that the maintainer account behind it had been groomed for over two years, that the malicious payload was hidden in binary test files excluded from the public diff, or that it specifically targeted OpenSSH through a liblzma hook. Safeguard sees this pattern constantly: teams generate an SBOM, satisfy the procurement checkbox required by Executive Order 14028, and assume the hard part is finished. It isn't. An SBOM is an inventory. It is not a security posture.

Does an SBOM Tell You Which Vulnerabilities Actually Matter?

No — an SBOM lists what's present, not what's reachable, and that gap is where security teams drown in false urgency. When Log4Shell (CVE-2021-44228) broke on December 10, 2021, security teams everywhere ran SBOM-driven searches for log4j-core and found it in thousands of applications. But research from dependency-analysis vendors in the aftermath showed that a large share of those instances never actually invoked the vulnerable JndiLookup class at all — many applications imported log4j-core as a transitive dependency of a transitive dependency and used none of the logging paths that triggered the JNDI lookup. An SBOM can't distinguish "this library is on disk" from "this library's vulnerable function is on the call path of a request handler exposed to the internet." Without reachability and call-graph analysis layered on top, every CVE in every listed component reads as equally urgent, which is functionally the same as having no prioritization at all. Teams end up patching low-risk dependencies while genuinely exploitable ones sit in the same unsorted queue.

Can an SBOM Catch a Compromised Build Pipeline or a Malicious Maintainer?

No — SBOMs describe components, not the integrity of the process that produced them. The SolarWinds breach, disclosed in December 2020, is the canonical example: the Orion Platform's SBOM would have accurately listed the signed SolarWinds.Orion.Core.BusinessLayer.dll, because the SUNBURST backdoor was injected during the build process itself and shipped with a legitimate code-signing certificate. Nothing in a component inventory flags "this build server was compromised between February and June 2020." The same blind spot showed up in the 3CX incident in March 2023, where attackers compromised a legitimate desktop application through a cascading supply chain attack that started with a trojanized trading application — one supply chain compromise feeding another. An SBOM generated after the fact would have shown a clean-looking list of signed binaries with valid version numbers. Catching this class of attack requires build provenance and attestation (frameworks like SLSA), not a components list.

Does an SBOM Stay Accurate After the Day You Generate It?

No — most SBOMs are point-in-time snapshots that go stale within days, and modern applications don't stand still. Sonatype's State of the Software Supply Chain research has repeatedly found that the average application pulls in several hundred open source components, and popular ecosystems like npm and PyPI see new package versions published continuously — npm alone processes well over a thousand new package versions every hour across the registry. If your SBOM was generated at the last release cut and your CI pipeline auto-updates minor and patch versions between releases (as most npm install and Dependabot-style workflows do), the document in your compliance folder is describing a dependency tree that no longer exists in production. A static SBOM tells you what shipped on release day. It says nothing about the dependency that got silently bumped three sprints later, or the container base image that was rebuilt last Tuesday and now pulls a different version of OpenSSL.

Does an SBOM Prove the Code You Received Matches What Was Actually Published?

No — an SBOM records a name and a version string, not a cryptographic guarantee that the artifact you consumed is what the legitimate maintainer published. The event-stream npm incident in November 2018 is the textbook case: a malicious actor gained publish rights to a popular package through a routine maintainer handoff, then added a dependency that targeted a specific cryptocurrency wallet application with credential-stealing code. Anyone's SBOM would have listed event-stream@3.3.6 as present — accurately, and uselessly. A similar pattern hit ua-parser-js in October 2021, when compromised versions containing a cryptominer and password stealer were published directly to the npm registry. In both cases the package name and version in an SBOM looked completely normal; the compromise lived in the delta between the source repository and what actually got published to the registry. Detecting this requires artifact signing and provenance verification (Sigstore, in-toto, SLSA attestations), not a bill of materials.

Is a Complete, Accurate SBOM Even Achievable With Today's Tooling?

Rarely, and the format fragmentation is a big reason why. The two dominant standards, CycloneDX and SPDX, don't map cleanly onto each other, and the NTIA's July 2021 "minimum elements" guidance leaves significant room for tools to generate technically-compliant SBOMs that vary wildly in depth. Container images compound the problem: a base image pulled from a public registry often bundles OS packages, language runtimes, and pre-installed libraries that many SBOM generators simply don't unpack layer by layer, meaning transitive and nested dependencies get missed or flattened. In our own work reviewing customer environments, it's common to find SBOMs that faithfully list direct dependencies but miss two or three levels of transitive depth — precisely where components like the XZ Utils backdoor or the Log4j JndiLookup class tend to live. A checkbox SBOM that's 70% complete gives you false confidence that's arguably worse than knowing you have no visibility at all.

Does Generating an SBOM Satisfy Your Actual Security Obligations?

No — it satisfies a procurement and compliance requirement, which is a different thing entirely. Executive Order 14028 (May 2021) and the follow-on OMB memoranda require federal software vendors to produce SBOMs, and frameworks like FedRAMP and increasingly SOC 2 audits now expect them as evidence of supply chain hygiene. But "produced an SBOM" and "am secure against supply chain attacks" are not the same claim, and auditors, customers, and boards increasingly know the difference. Treating the SBOM as the finish line — generate it, file it, move on — leaves the actual attack surface (exploitability, build integrity, artifact provenance, and drift over time) completely unaddressed. The organizations that got burned by XZ Utils, SolarWinds, and ua-parser-js all had passable component inventories. None of that inventory stopped the incident.

How Safeguard Helps

Safeguard treats the SBOM as a starting input, not an end product. We ingest SBOMs (CycloneDX and SPDX alike) and immediately layer reachability analysis on top, so instead of a flat list of every CVE touching every listed component, your team sees which vulnerabilities sit on an actual, exercised code path — cutting through the noise that made Log4Shell remediation so exhausting in the weeks after December 2021. We continuously re-scan build pipelines and dependency trees rather than treating the SBOM as a one-time artifact, catching the drift that happens when a container gets rebuilt or a transitive dependency silently bumps between releases. We verify build provenance and artifact signatures against frameworks like SLSA and Sigstore, so a compromised build server or a maintainer-account takeover — the exact failure mode behind SolarWinds, event-stream, and ua-parser-js — gets flagged even when the version string looks completely normal. And we map that combined picture directly to the compliance evidence auditors actually ask for under SOC 2 and FedRAMP, so the SBOM stops being a document you file and starts being one input into a security program that can actually answer the question your customers are asking: not "do you have an SBOM," but "are you secure." If you want to see what your current SBOM is — and isn't — telling you, Safeguard can run that gap analysis against your existing inventory in a single session.

Never miss an update

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