Skip to main content
AXTONITNOW
All insights

InsightsCybersecurity

XZ Supply-Chain Compromise: How the liblzma Backdoor Was Planted and How It Stayed Hidden

A chronological look at CVE-2024-3094: years of trust-building, release-tarball stealth, and five obfuscation layers that turned a compression library into a supply-chain warning.

In early 2024, the open-source world got a reminder that supply-chain attacks do not always arrive as a dramatic hack. Sometimes they arrive as a polite contributor, a helpful patch, and two years of patience.

The XZ Utils compromise, tracked as CVE-2024-3094, was a backdoor planted in a widely used compression library. Not in a flashy application. Not in a trendy npm package. In infrastructure so boring that most Linux systems depend on it without ever thinking about it.

That is what made it dangerous. xz/liblzma sits below a lot of other software. If the malicious releases had spread further, attackers could have influenced SSH authentication on affected systems. That would have been a very un-boring outcome from a very boring dependency.

A compromise built over years, not minutes

Unlike many supply-chain incidents that exploit a misconfigured pipeline or a stolen token, the XZ backdoor was a long game. The attacker did not need to break into a build system from the outside. They worked their way into the project's social fabric first, then used that trust to shape the code, the tests, and eventually the release process itself.

The timeline below shows how that unfolded, from a new GitHub identity in 2021 to public disclosure in March 2024.

  1. A new contributor identity appears

    The GitHub account JiaT75 appears and begins building credibility through open-source contributions.

  2. Pressure on the maintainer

    xz maintainer Lasse Collin is dealing with burnout and reduced project activity while multiple new accounts push for more updates and another maintainer.

  3. Trust is built

    Jia Tan contributes patches and features, becomes more involved in xz, and gradually earns trust inside the project.

  4. Maintainer-level access

    Jia Tan starts merging changes and becomes a key trusted contact around the project and its testing ecosystem.

  5. Exploit-enabling test infrastructure appears

    Testing-related code that is later leveraged by the exploit is introduced into the project.

  6. Detection surface is reduced

    A pull request disables IFUNC fuzzing in OSS-Fuzz, making the eventual malicious behaviour harder to catch automatically.

  7. Malicious releases 5.6.0 and 5.6.1

    Altered release tarballs diverge from the public Git history and carry the hidden backdoor into downstream packages.

  8. Discovery and disclosure

    Andrés Freund notices slow SSH logins, high CPU use, and valgrind errors on Debian sid. The backdoor is disclosed and tracked as CVE-2024-3094.

What stands out is the pacing. This was not a smash-and-grab. It was maintainer fatigue, community pressure, incremental access, and technical preparation spread across multiple years. By the time malicious tarballs appeared, the attacker had already shaped parts of the environment that would help the backdoor survive scrutiny.

How the backdoor was obfuscated

The xz backdoor was not dropped in as an obvious malicious file sitting in the repository for everyone to review. It was designed to appear only at the right moment, in the right build, on the right kind of system. That is why it remained hidden for so long.

The obfuscation unfolded in five linked stages:

  1. Hidden in release tarballs

    The malicious logic was added to release tarballs, not plainly visible in the normal Git source tree.

  2. Triggered during the build

    A modified build-to-host.m4 script invoked a hidden script during compilation.

  3. Payload concealed in test files

    Obfuscated and encrypted stages were unpacked from two test files:

    tests/files/bad-3-corrupt_lzma2.xz and tests/files/good-large_compressed.lzma
  4. Only activated under narrow conditions

    The code checked for amd64, glibc, and Debian- or Red Hat-style environments before moving forward.

  5. Runtime hooking of sshd

    IFUNC-based hooking redirected OpenSSH authentication behaviour and targeted /usr/sbin/sshd, helping the backdoor stay quiet until the right conditions were met.

Together, these steps created a backdoor that was difficult to spot in normal source review, difficult to trigger accidentally, and difficult to detect with standard tooling unless you were already looking in exactly the right place.

The malicious code was not in the Git tree everyone reviewed. It was in the release artifact everyone trusted.

Why this incident still matters

The XZ compromise is often remembered as a near miss, and it was. The backdoor was caught before it reached most stable production environments. But “near miss” is not the same as “no lesson.”

The incident showed how a patient attacker can combine maintainer social engineering, trusted release processes, and build-time stealth to target the software supply chain. It also showed that open-source trust models, with small maintainer teams, volunteer burnout, and community pressure, can become part of the attack surface when nobody is paying attention.

What made XZ unusualWhy it matters for business
Years of trust-building
Access was earned socially, not stolen technically.
Supply-chain risk includes people, roles, and maintainer pressure, not only packages and pipelines.
Malware in release tarballs
Source review alone was not enough.
Release integrity and build reproducibility need the same attention as code review.
Environment-specific activation
The backdoor waited for the right target.
Testing in one environment does not prove safety everywhere downstream.
Discovery by anomaly, not scanner
A performance issue exposed the backdoor.
Operational monitoring and skilled engineers still matter when automated checks miss the threat.

What teams should take from this

Most organisations will never maintain a compression library. That is fine. The lesson is broader: critical open-source components deserve more than passive trust, and the path from contributor to maintainer deserves more scrutiny than we usually give it.

Practical responses include verifying release tarballs against source, monitoring maintainer changes in critical dependencies, supporting maintainer sustainability before burnout creates gaps, and treating unusual runtime behaviour in core infrastructure as a security signal rather than a performance nuisance.

XZ was caught because someone noticed SSH behaving oddly. That is both reassuring and uncomfortable. Reassuring because the system worked once. Uncomfortable because the next attempt may be quieter, better funded, and better hidden.

Final thought

The XZ incident was not just a story about one backdoor in one library. It was a reminder that supply-chain attacks can be patient, technical, and social at the same time.

Attackers do not always need to break your CI/CD or poison your registry. Sometimes they just need time, a trusted identity, and a release process that everyone assumes is safe because it always has been.

Your software supply chain is built on more than code. It is built on people, releases, trust, and the boring infrastructure holding it all together. That is worth defending with the same seriousness as production itself.