The XZ Backdoor
Introduction
In February 2024, a backdoor was deliberately introduced into XZ Utils, a compression library present on nearly every Linux system in existence. Over a period of more than two years, an individual operating under the pseudonym “Jia Tan” cultivated the appearance of a diligent, trustworthy open-source contributor, eventually gaining maintainer privileges within the project — a position they then leveraged to embed malicious code directly into official release artifacts. The backdoor specifically targeted liblzma, a transitive dependency of OpenSSH on Debian- and Fedora-based systems, and would have granted an attacker in possession of a specific private key the ability to achieve unauthenticated remote code execution over SSH across potentially millions of servers worldwide. It stands as one of the most sophisticated supply-chain attacks ever documented in open-source software. Its discovery came down to a stroke of luck rather than a targeted audit: on March 29, 2024, software engineer Andres Freund noticed an anomalous, barely perceptible delay in SSH login times while benchmarking PostgreSQL performance. That anomaly led him directly to the compromised library — mere weeks before the affected versions would likely have propagated into stable distributions such as Debian Stable or Ubuntu LTS.
Timeline
Involved People
Andres Freund
Microsoft engineer and PostgreSQL developer. Noticed a 500ms SSH login delay while benchmarking on Debian Sid, traced it to liblzma, and disclosed the backdoor on March 29, 2024.
Lasse Collin
Finnish software developer who had been working on LZMA-based compression tooling since around 2005. In 2009, he formally launched XZ Utils, introducing the .xz format and the liblzma library as its core, and served as the project’s sole maintainer for well over a decade, managing contributions from the wider open-source community.
“Jia Tan” (JiaT75)
Pseudonym, real identity never confirmed. He created the GitHub account in January 2021, spent over two years building credibility as a legitimate contributor before embedding the backdoor. Commit-timing inconsistencies suggest the account may have been operated by more than one person.
“Jigar Kumar”
A suspected sock puppet account that began publicly pressuring Lasse Collin starting in April 2022. Repeatedly complained that patches were being processed too slowly and pushed for a second maintainer to be added. No verified real identity, no presence outside the campaign period.
“Dennis Ens”
Another suspected sock puppet account that reinforced “Jigar Kumar’s” pressure campaign starting in May 2022. Initially asked about the status of “XZ for Java” before also joining the pressure on Collin. Also never identified.
“Hans Jansen”
A separate persona who contributed a performance patch in mid-2023 that later became part of the backdoor infrastructure. In March 2024, the same identity pushed Debian maintainers to quickly adopt the (already backdoored) release. Also never identified.
Linux distribution maintainers (Red Hat, Debian, SUSE, Fedora)
Reacted within hours of the backdoor becoming public, rolling back affected package versions and issuing security advisories.
Social Engineering Timeline
- 2021-10-29: Jia Tan sends first patch message to xz-devel XZ-DEVEL
- 2022-01-28: Jia Tan writes his first commit: “liblzma: Add NULL checks to LZMA and LZMA2 properties encoders.” Lasse Collin merges this commit at 2022-02-06 GitHub
- 2022-04-28: Jigar Kumar complains that patches are waiting too long on the mailing list XZ-DEVEL
- 2022-05-19: Dennis Ens asks if XZ for Java is still maintained XZ-DEVEL
- 2022-05-19: Lasse Collin replies that Jia Tan helped him “off-list” and might get a bigger role in the future XZ-DEVEL
- 2022-05-27: Jigar Kumar complains about the speed of new merge requests XZ-DEVEL
- 2022-06-07: Jigar Kumar writes that the project needs a new maintainer XZ-DEVEL
- 2022-06-08: Lasse Collin replies to the messages and writes that Jia Tan might get a bigger role XZ-DEVEL
- 2022-06-10: The Name “Jia Tan” is named as Author for the first time in Github metadata GitHub
- 2022-06-13: Commit gets Merged with a new Email Address of Jia Tan Tukaani
- 2022-06-14: Jigar Kumar sends another email to Lasse Collin and complains about the speed XZ-DEVEL
- 2022-06-21: Dennis Ens sends another email to Lasse Collin and wants him to pass the ownership XZ-DEVEL
- 2022-06-22: Jigar Kumar asks in the mailing list why Jia Tan cannot commit his own code XZ-DEVEL
- 2022-06-29: Lasse Collin mentions that a change in maintainership is in progress XZ-DEVL
- 2022-10-18: JiaT75 has org-level access on tukaani-project
Proof that the GH Archive query for jiaT75 shows:
The CreateEvent at 12:20:43 UTC marks the repository’s initialization within the organization, with pusher_type: “user” confirming this action was performed directly by an authenticated user — an operation that requires organization-level write access at the time of execution. Three subsequent commits follow within the hour, establishing the PR template and README documentation. Notably, no corresponding MembershipEvent exists in the public GH Archive record, likely indicating the organization’s membership visibility was configured as private. This makes the repository creation event itself the earliest independently verifiable evidence of organizational access.

- 2022-11-30: Lasse Collin changes the bug report email address from his personal address to xz@tukaani.org Tukaani
- 2022-12-20: Jia Tan names his full name for the first time: “Jia Cheong Tan” Tukaani
- 2023-03-18: Jia Tan builds his first release Tukaani
- 2023-03-20: Jia Tan changes the contact email address for oss-fuzz GitHub
- 2023-06-27: Jia Tan merges a patch from Hans Jansen that was used in the backdoor Tukaani GitHub
- 2023-07-07: Jia Tan disabled ifunc in oss-fuzz GitHub
Attack Timeline
- 2024-02-23: Jia Tan adds the Backdoor in the Binary Test Input Files Tukaani
- 2024-02-24: Jia Tan releases the Backdoor in v5.6.0 - Release has an extra file (build-to-host.m4) file that adds the backdoor when built on deb/rpm systems Tukaani
- 2024-02-24: Gentoo Users published bugs with the release v5.6.0 Gentoo Gentoo
- 2024-02-26: Debian adds xz-utils 5.6.0-0.1 to Debian unstable Debian
- 2024-02-28: Debian adds v5.6.0-0.2 to Debian unstable Debian
- 2024-02-29: Pull Request in systemd was created to stop linking liblzma into libsystemd - Important because this would have defeated the attack - maybe accelerated the attacker’s schedule GitHub
- 2024-03-04: Bug Report in Red Hat because of valgrind errors RedHat
- 2024-03-05: libsystemd removed liblzma - would have stopped the backdoor completely GitHub
- 2024-03-05: Debian adds v5.6.0-0.2 to Debian testing Debian
- 2024-03-09: Jia Tan updated the backdoor again Tukaani
- 2024-03-09: Jia Tan releases a new version with the updated backdoor Tukaani
- 2024-03-20: Lasse Collin introduces Jia Tan as maintainer to the linux kernel LKML
- 2024-03-25: Hans Jansen pressures Debian Community to update XZ-Utils to v5.6.1-1 Debian
- 2024-03-27: v5.6.1-1 gets accepted in unstable Debian
- 2024-03-28: Jia Tan emails Ubuntu to sync XZ-Utils 5.6.1-1 from Debian unstable Ubuntu
Detection Timeline
- 2024-03-28: Andres Freund emails Debian privately and openwall that liblzma compromises ssh
- 2024-03-28: Debian reverted the xz-utils version to 5.6.1+really5.4.5-1 Debian
- 2024-03-29: Arch Linux changes the version to build from git Arch
- 2024-03-29: Andres Freund posts the message publicly on openwall OpenWall
- 2024-03-29: RedHat makes the backdoor public on fedora40 and Fedora Rawhide RedHat
- 2024-03-29: Github disables the xz Repository because of violation of terms of service

- 2024-03-29: Github disables the accounts of Lasse Collin and Jia Tan Tukaani
- 2024-03-30: Debian announces that they stopped archive processing Fulda
Cleanup
- 2024-03-30: Lasse Collin removes Jia Tan from the mail xz@tukaani.org Tukaani
- 2024-04-09: Github Repository of XZ was restored on Github Tukaani
- 2024-05-29: Clean Versions of XZ-Utils were released again Tukaani
Technical Analysis
The sophistication of the XZ Utils backdoor lies not in a single exploit primitive, but in how several legitimate-looking mechanisms were carefully chained together to activate only under narrow, specific conditions — evading both casual review and automated tooling for over two years. Critically, the malicious payload was never present in the public Git history in an obviously readable form. It was introduced through two separate vectors: binary test files disguised as legitimate decompression test fixtures, and a subtly modified build-to-host.m4 build script. Since the compromised code only existed in the official release tarballs — the pre-packaged source archives distributed to downstream Linux distributions — and not in the version-controlled repository itself, casual inspection of the public Git repository would not have revealed anything unusual. The backdoor leveraged GNU Indirect Functions (IFUNC), a glibc/linker feature that allows a function’s implementation to be resolved at load time rather than compile time. This is typically used for legitimate performance optimizations, such as selecting a CPU-specific instruction path. Here, it was repurposed to execute attacker-controlled code extremely early in process initialization — before standard memory protections, such as marking function tables read-only, had taken effect. Once active, the payload hooked RSA_public_decrypt, a function used by OpenSSH during key verification, replacing it with a malicious implementation capable of executing attacker-supplied code. The backdoor was deliberately narrow in scope, which likely aided its stealth:
- It only activated on x86-64 systems using glibc
- It required the build to be triggered via dpkg or rpm packaging systems, specifically targeting Debian- and Fedora-derived distributions
- Execution required possession of a specific Ed448 private key held only by the attacker — without it, the injected code path remained dormant, meaning even direct testing of an infected system wouldn’t necessarily reveal malicious behavior
Every extracted backdoor string so far from the version 5.6.1 was published here: GitHub
Impact
CVE-2024-3094 is widely regarded as one of the most consequential supply-chain security incidents in the history of open-source software — not because of what it actually caused, but because of how close it came to succeeding at a truly global scale. liblzma is not a niche dependency. As a component of XZ Utils, it is present on virtually every Linux system in existence, either directly or transitively — most critically as a dependency chain leading into OpenSSH on Debian- and Fedora-based systems via libsystemd. A compromise at this layer isn’t isolated to a single application — it strikes at the trust boundary of remote access itself. Had the backdoor gone undetected, an attacker in possession of the corresponding private key could have achieved unauthenticated remote code execution on any affected system exposing SSH — without needing valid credentials, without triggering a failed login, and without leaving the kind of obvious forensic trail a traditional exploit chain might. This is close to the worst-case outcome for a server-side vulnerability: silent, credential-free, and remotely triggerable. The backdoor had already been adopted by rolling-release distributions — Debian Sid, Fedora Rawhide, openSUSE Tumbleweed, Arch Linux, and Kali Linux. Critically, the timing appears to have been deliberately aligned with the release schedules of Fedora 40/41 and RHEL 9.4, both expected in the following weeks. Had Andres Freund not noticed a barely perceptible SSH latency increase while benchmarking an unrelated project, there is a credible chance the compromised versions would have propagated into stable, long-term-support distributions — at which point remediation would have required patching a vastly larger, slower-moving population of production servers already relying on the backdoored code. Perhaps most alarming is what this incident reveals about the structure of open-source security itself: a single, unpaid, burned-out volunteer maintainer controlled a critical piece of internet infrastructure, and a patient, well-resourced attacker was able to exploit that human vulnerability more easily than any purely technical one. The backdoor was caught not through a security audit, a code review process, or automated tooling, but through one engineer’s attentiveness to an anomaly that had nothing to do with security testing. That this was, by most accounts, a matter of chance rather than process, is arguably the most sobering part of the entire incident.
Lessons Learned
Lasse Collin’s own acknowledgment of long-term mental health struggles was, in retrospect, the exact opening the attacker needed. Critical infrastructure software maintained by a single, unpaid volunteer represents a systemic risk that has nothing to do with code quality — the “bus factor” of one is itself an attack surface. Organizations that depend on open-source infrastructure have a responsibility to contribute funding, maintenance support, or additional maintainers to projects they rely on, rather than treating sustained volunteer labor as a free, infinite resource. Nearly three years of patient, legitimate-looking contributions accomplished what no zero-day could have: trusted commit access to a project embedded in almost every Linux distribution on Earth. This incident is a reminder that trust, once established through a long track record, is rarely re-verified — and that attackers who understand this can bypass technical defenses entirely by targeting the human and social layer of a project instead. The backdoor was deliberately placed in generated release tarballs rather than the version-controlled Git repository, specifically to evade the kind of scrutiny that public commits typically receive. This highlights a blind spot common across many open-source projects: distribution artifacts are often built and published with far less oversight than the source code itself, even though they are what actually ends up running on production systems. Had reproducible build practices been rigorously enforced and verified across distributions, the discrepancy between the tarball contents and the public repository would have been far easier to detect independently, rather than relying on chance. The backdoor wasn’t caught by an automated scanner, a security audit, or a review process — it was caught because one engineer noticed a barely perceptible, half-second delay in SSH logins and chose to investigate rather than dismiss it. This underscores both the value of curious, careful engineers and the uncomfortable reality that open-source security often depends on exactly this kind of chance encounter rather than systematic assurance. This incident is a clear illustration of how deep and invisible modern software supply chains have become, and why dependency transparency (e.g. SBOMs — Software Bill of Materials) is increasingly treated as a security necessity rather than a bureaucratic afterthought.
- 2024-05-29: Lasse Collin named Sam James as second maintainer - Sam James was formally named a supporting maintainer of XZ Utils on May 29, 2024, the same day Lasse Collin released version 5.6.2, which removed the backdoor entirely. XZ-DEVEL
Nice to know
Interesting for readers who want to see the backdoor’s mechanichs demonstrated safely:
Shortly after the backdoor’s disclosure, amlweems published xzbot, a small toolkit built to make the backdoor’s mechanics tangible rather than purely theoretical. The repository contains a few components:
- A honeypot — a deliberately vulnerable SSH server used to observe and log real-world exploitation attempts in the wild, useful for researchers tracking whether anyone was actively scanning for vulnerable systems after disclosure
- An OpenSSH patch — adds logging for any connection attempt whose public key matches the backdoor’s specific format, allowing defenders to detect exploitation attempts against real systems
- A key-replacement patch — swaps the backdoor’s hardcoded Ed448 public key with a researcher-controlled one, enabling safe, controlled demonstration in an isolated lab environment
- Documentation of the payload format — a plain-language breakdown of how the backdoor structures its trigger data within an SSH certificate field