BSG Blog Berezha Security Group

Software Supply Chain Security: Beyond XZ Utils

In March 2024, the open-source world got the closest look it has ever had at a perfectly executed software supply chain attack — and it was found almost by accident. A Microsoft engineer named Andres Freund noticed that SSH logins on a Debian test machine were taking about half a second longer than they should. Chasing that latency led him to a backdoor planted in liblzma, a compression library bundled with XZ Utils, a package so unremarkable that almost nobody thinks about it. He disclosed it publicly on 29 March 2024. The vulnerability, CVE-2024-3094, carries a CVSS score of 10.0.

The technical payload was clever. The far more important detail is how it got there: a contributor operating under the persona Jia Tan spent roughly two years building trust in the XZ project, eventually becoming a co-maintainer, and then shipped the malicious code inside the 5.6.0 and 5.6.1 release tarballs. No firewall, no scanner, and no vulnerability-management program was ever going to catch that. The attack didn’t exploit a bug. It exploited trust.

Software supply chain security is the discipline of managing the trust your systems place in every external component, tool, and service they depend on — and verifying that trust instead of assuming it. XZ Utils is the hook for this article, but it is only one entry in a much longer story. This is a practitioner’s guide to the whole discipline: how these attacks actually work, the modern defenses that move the needle, and where a real team should start.

What is software supply chain security?

Every piece of software you run is assembled from code you did not write. Open-source libraries, language runtimes, base container images, CI/CD tooling, build servers, package registries, third-party APIs — each is a dependency, and each is a point of trust. A software supply chain attack compromises one of those trusted components so that the malicious code, or malicious behavior, flows downstream into everyone who depends on it.

The premise here is one we have argued for years: trust is inevitable. No organization outside of a handful of military and intelligence agencies can afford to verify every line of code and every chip it runs. You trust your hardware vendor because you cannot realistically audit a CPU. You trust your operating system because nothing runs without it. You trust the thousands of transitive dependencies your package-lock.json pulled in last week because reading them all is physically impossible.

That inevitability is exactly why the supply chain is such fertile ground for attackers. The whole model runs on trust that is rarely verified — and an attacker who compromises one well-placed, widely-trusted component inherits the reach of everyone who trusts it. Supply chain security is not about eliminating trust. It is about making trust deliberate, scoped, and checkable.

How software supply chain attacks work

“Supply chain attack” is an umbrella over a surprisingly diverse set of techniques. Here is the modern taxonomy, with the real incidents that defined each category.

Malicious and typosquatted packages

The lowest-effort, highest-volume attack: publish a malicious package to a public registry like npm or PyPI and wait. Typosquatting relies on a fat-fingered npm install (crossenv instead of cross-env); brandjacking mimics a trusted name. The XZ incident is the artisanal version of this category — the everyday version is a steady stream of credential-stealers and crypto-miners published to public registries every single week.

Dependency confusion

In 2021, researcher Alex Birsan showed that if your build references an internal package name that also exists (or can be claimed) on a public registry, many package managers will happily pull the public one — because it has a higher version number. He used the technique to land code inside Apple, Microsoft, and dozens of other companies. Dependency confusion turns your private namespace into an attack surface you didn’t know you had.

Compromised build pipelines

The most damaging category, because it poisons software that is otherwise perfectly legitimate. In the 2020 SolarWinds incident, attackers — Microsoft tracks the actor as NOBELIUM, widely attributed to Russia’s SVR (APT29) — breached the build pipeline for the Orion network-management product and inserted the SUNBURST backdoor into a signed, official update. Around 18,000 organizations installed it. The code was signed. The update was authentic. The build itself was the compromise.

Maintainer and account compromise

This is the XZ Utils category, and it is the one that should keep appsec leads up at night. Rather than break a system, the attacker becomes a trusted insider — through a stolen maintainer account, a social-engineering campaign, or, as analyses of the XZ incident describe it, a patient multi-year cultivation of a maintainer persona until that persona held the commit bit. Open source runs on the unpaid labor of small numbers of maintainers, and that is precisely the pressure point.

Poisoned updates and toolchain attacks

Auto-update is a feature and a liability: a single compromised update channel reaches every installed instance at once. And the most subtle category lives one level deeper — in the compiler and toolchain itself. Trojan Source, published by Nicholas Boucher and Ross Anderson, used bidirectional-Unicode control characters to make source code render differently from how a compiler interprets it, so that a human reviewer and the build see two different programs. It was assigned CVE-2021-42574 (bidi reordering) and CVE-2021-42694 (homoglyphs), and it affects most major languages. Even a careful manual code review can miss an attack that is invisible by design.

Software supply chain attacks flow downstream from a single compromised component

The common thread across all six is that nothing here is a “vulnerability” in the classic CVE-in-your-code sense. The defect is in the relationship — in code, tooling, or people you trusted and did not verify.

Modern defenses

The good news: the half-decade since SolarWinds has produced a genuinely useful toolkit. None of it is a silver bullet, and the value comes from layering. Here is each defense at a practical altitude.

Build provenance and SLSA. SLSA (Supply-chain Levels for Software Artifacts, an OpenSSF project) is a framework for answering one question: can you prove how this artifact was built? Its v1.0 specification defines a Build track with levels L0 through L3 — from “no guarantees” up to a hardened, tamper-resistant build platform that emits signed provenance describing exactly which sources and steps produced the artifact. (The spec has since advanced to v1.2.) Provenance is what turns “trust me, it’s the official build” into something a machine can verify — and it is precisely the control that addresses a SolarWinds-style pipeline compromise.

SBOM — a software bill of materials. You cannot defend an inventory you do not have. An SBOM is a machine-readable list of every component in a piece of software, and the two dominant formats are SPDX (standardized as ISO/IEC 5962:2021) and CycloneDX (an OWASP project, also standardized as ECMA-424). An SBOM does not secure anything by itself — its value is speed. When the next Log4Shell-class bug drops, the teams that already maintain SBOMs answer “are we affected?” in minutes instead of weeks.

Artifact signing with Sigstore. Sigstore (also OpenSSF) and its cosign CLI let you sign and verify artifacts and container images. The interesting part is keyless signing: instead of managing long-lived private keys, you sign with short-lived certificates from Fulcio and record the signature in the Rekor transparency log. Signing answers “is this artifact really from who it claims?” — and it is rapidly becoming table stakes; Kubernetes itself now ships signed release artifacts.

Dependency pinning and verification. Pin exact versions with lock files, and verify integrity hashes on install so a registry can’t silently swap a package out from under you. Prefer a curated internal registry or proxy over pulling straight from the public internet — that single control closes most of the dependency-confusion attack surface.

Build-system hardening. Treat your CI/CD pipeline as the production system it actually is. Scope build credentials to least privilege, isolate build steps, deny builds write-access to production, and audit who can change pipeline configuration. SolarWinds is the cautionary tale: the build environment was the crown jewels.

Third-party and vendor risk. Not all of your supply chain is open source. Commercial dependencies, SaaS integrations, and the firmware in the devices you ship all carry risk you inherit. This is where supply chain security meets old-fashioned vendor due diligence — and where regulation is increasingly drawing the line.

Where to start

Reading that list, the honest reaction is “we do almost none of this.” That is the normal starting point, and it is also where a lot of teams freeze — because they are measuring themselves against an idealized end state instead of against last month.

We have a strong opinion here, and it is the same philosophy we apply to software product security: measure progress, not the gap. The distance between where you are and some platonic “fully secure supply chain” will always be non-zero, and staring at it is paralyzing. What actually matters is trajectory — is each quarter’s posture better than the last? A pragmatic first year looks like this:

  1. Inventory first. You cannot secure what you cannot see. Generate an SBOM for your most important product and learn what is actually in it. The list is always longer and stranger than the team expects, and the surprise is the value.
  2. Pin and verify. Lock dependency versions, enforce integrity hashes, and route installs through a curated internal registry or proxy. Low effort, immediate reduction in attack surface.
  3. Sign your artifacts. Stand up cosign for the builds you ship. Now downstream consumers — including your own deployment pipeline — can verify what they’re running.
  4. Harden the build. Audit who and what can modify your CI/CD pipeline, scope credentials down, and treat the build environment as production. This is the SolarWinds lesson, applied.
  5. Monitor continuously. Wire SBOM-driven vulnerability monitoring into the pipeline so that “are we exposed to the new CVE?” is a query, not a fire drill.

Each step is independently valuable and independently shippable. You do not need all five before any of them counts. That is the entire point of measuring progress.

Regulation is catching up

For years, supply chain security was a best-effort discipline. That era is ending, and the obligations are becoming concrete enough to land on a roadmap.

In the United States, Executive Order 14028 (“Improving the Nation’s Cybersecurity,” signed 12 May 2021) pushed secure software development into federal procurement, and NIST SP 800-218 — the Secure Software Development Framework (SSDF) — is the practice catalog that operationalizes it. In practice the federal requirement centers on a secure-development attestation, with agencies able to request supporting artifacts such as SBOMs on a risk basis — not a blanket public-SBOM mandate.

In the EU, the Cyber Resilience Act (CRA) entered into force on 10 December 2024. It introduces secure-by-design requirements, vulnerability handling during a defined support period, and mandatory reporting of actively exploited vulnerabilities. The reporting obligations begin to apply in September 2026, with the main obligations following in December 2027. If you ship software or connected products into the EU market, the CRA is a planning item now, not a 2027 problem.

The direction of travel is unambiguous: “we trust our suppliers” is no longer an acceptable answer to a regulator, an auditor, or an enterprise buyer’s security questionnaire.

How BSG helps

Software supply chain risk is a first-class part of application security, and we treat it that way in our engagements. When BSG assesses a product, we look past the application’s own code at the dependencies, build pipeline, and third-party components it leans on — the same blind spots the XZ and SolarWinds incidents exploited. That means reviewing what is actually in your SBOM, probing CI/CD and build-system trust boundaries, and pressure-testing the third-party integrations attackers reach for first.

We then help you turn findings into a roadmap you can ship against — provenance, signing, pinning, monitoring — sequenced so that each quarter is measurably more defensible than the last. For container-based stacks, that work extends naturally into Kubernetes and image supply-chain testing. Not a compliance checkbox. A trajectory.

The XZ backdoor was caught by a 0.5-second delay that one engineer refused to ignore. That is not a security strategy. Knowing what is in your software, where it came from, and how it was built — that is.

Worried the next XZ Utils is buried in your dependencies?
BSG's application-security team assesses software supply chain risk as part of every appsec engagement — reviewing what's really in your SBOM, probing build-pipeline and CI/CD trust boundaries, and stress-testing the third-party components attackers reach for first — with reproducible findings and a roadmap you can ship against, backed by 12 years and 300+ engagements.

Request a quote →