XZ Utils Backdoor: A Technical Deep Dive
How a two-year-long social engineering effort inserted a backdoor into xz/liblzma's release tarballs, and how a Postgres developer's curiosity about slow SSH logins caught it.
6 min read
Summary
On March 29, 2024, developer Andres Freund posted to the oss-security mailing list that upstream xz/liblzma had been backdoored in versions 5.6.0 and 5.6.1 (openwall.com). The backdoor lived in the distributed release tarballs — not the GitHub auto-generated source archives — and, on affected systems, allowed compromise of the OpenSSH server through libsystemd's dependency on liblzma. Freund found it after noticing SSH logins on Debian sid consuming unusual CPU and triggering valgrind errors. At disclosure time, 5.6.0 and 5.6.1 had not yet been picked up by stable distributions, mostly landing in pre-release or unstable branches such as Debian sid and pending Fedora 40/41 builds (openwall.com; news.ycombinator.com).
Timeline
- Prior weeks (undated in sources): Freund notices SSH logins on Debian sid taking excessive CPU and producing valgrind errors while doing unrelated Postgres benchmarking work (openwall.com).
- Prior ~2 years: A contributor using the handle "Jia Tan" (GitHub account JiaT75) is active in the xz project, including adding binary test files later found to contain obfuscated exploit payloads (news.ycombinator.com).
- Before release: The same account pushes a Fedora packager to add xz 5.6.x to Fedora 40 and 41, citing "great new features," and helps fix a valgrind issue that, per the packager's account, was actually caused by the backdoor itself (news.ycombinator.com).
- 5.6.1 release: Further commits work around the valgrind/crash symptoms caused by the injected code, adjusting the exploit accordingly (openwall.com).
- Night before disclosure: The Fedora packager describes "an inadvertent break of the embargo," triggering an overnight race to fix the issue before public disclosure (news.ycombinator.com).
- Fri, 29 Mar 2024, 08:51:26 -0700: Freund publishes a full technical writeup to oss-security: the compromised tarball, the compromised test files, affected systems, and reproduction steps (openwall.com).
- Same day: GitHub suspends the JiaT75 and Lasse Collin (Larhzu) accounts and disables all Tukaani project repositories, including the releases page (news.ycombinator.com).
- Shortly after disclosure: Alpine Linux ships a patch removing the affected code (news.ycombinator.com).
- Following disclosure: Maintainers begin auditing and removing Jia Tan's public key from keyrings and approved-publisher lists across Arch, openSUSE, and AUR packages (pacman-static, mingw-w64-xz) (news.ycombinator.com).
The sources give no specific time for "full recovery" beyond these individual patches and account suspensions.
Root cause
The proximate cause was malicious code injected into the release tarballs of xz 5.6.0 and 5.6.1 — a line added to m4/build-to-host.m4 that does not exist in the upstream git repository (openwall.com). That line runs an obfuscated script at the end of configure, which, under matching preconditions, patches liblzma's Makefile to pipe test data through sed, tr, and xz -d into /bin/bash, deobfuscating and executing the real payload. The payload was hidden as binary blobs inside two test files, tests/files/bad-3-corrupt_lzma2.xz and tests/files/good-large_compressed.lzma — files not actually exercised by any real test in 5.6.0 (openwall.com).
Contributing factors:
- Tarball/repo divergence as accepted practice. Autoconf-based C projects commonly ship generated files (like
configureandbuild-to-host.m4) in release tarballs that don't appear in git — normal for build tooling, but it also gave the attacker a hiding place invisible to anyone auditing the public repo (news.ycombinator.com). - Long-term trust-building. The account had been an active xz contributor for roughly two years, doing routine work like adding test files, which normalized binary blobs in the repo (news.ycombinator.com).
- Social engineering of downstream maintainers. The account pushed directly for inclusion in Fedora 40/41, framed the release as having valuable new features, and helped fix bugs the backdoor itself had introduced — building credibility and urgency (news.ycombinator.com).
- Anti-analysis conditions. The payload activated only under narrow conditions — x86-64 Linux, glibc, gcc, GNU linker, and specifically Debian- or RPM-style package builds — designed, per Freund's analysis, to make reproduction harder for investigators (openwall.com).
- A separately sabotaged sandbox check. A commit attributed to the same contributor introduced a stray character into C code responsible for a Landlock sandboxing capability check, silently disabling that check — a second, independent weakening of defenses flagged by commenters reviewing the commit history (news.ycombinator.com).
Impact
- Observed slowdown: Freund's writeup reports SSH authentication attempts against localhost taking roughly 2.7x longer with the backdoored liblzma present:
- Affected package state: Debian sid installations were confirmed affected; xz 5.6.0/5.6.1 had not yet been widely integrated by distributions, and where present, mostly in pre-release branches (openwall.com).
- Near-miss for stable distros: The backdoor was in the process of being pushed into Fedora 40 and 41 via direct engagement with a packager (news.ycombinator.com).
- Mechanism of exposure: OpenSSH does not link liblzma directly, but several distributions patch OpenSSH for systemd notification support, and libsystemd depends on liblzma — this indirect chain is what exposed sshd (openwall.com).
- Downstream cleanup surface: The contributor's public key also appeared in AUR packages (mingw-w64-xz, pacman-static) and in openSUSE and Arch keyrings/publisher lists, prompting maintainers to review and remove those references (news.ycombinator.com).
The sources give no count of affected end users, servers, or organizations.
What went well
- Anomaly-driven detection. Freund wasn't looking for a backdoor — he noticed unrelated performance anomalies during other work and traced them to the injected code (openwall.com).
- Documented reproduction. The writeup lists exact trigger preconditions (unset
TERM,argv[0]of/usr/sbin/sshd, unsetLD_DEBUG/LD_PROFILE, setLANG) and a reproduction command:
- Disclosure included commit hashes, file paths, and tooling. The oss-security post gave exact commit hashes, injected code excerpts, and the analysis toolchain (
perf record,gdb), letting other researchers verify findings directly (openwall.com). - GitHub suspended the implicated accounts and disabled Tukaani's repositories, including the releases page, cutting off distribution of the infected tarballs (news.ycombinator.com).
- Alpine shipped a fix within hours of the disclosure being discussed on Hacker News (news.ycombinator.com).
- Community members cross-referenced the attacker's public key across AUR, Arch, and openSUSE, and independently found the separate Landlock sandbox sabotage commit (news.ycombinator.com).
Action items
- Remove the implicated contributor's public key from keyrings, approved-publisher lists, and package metadata — already underway for Arch, openSUSE, and AUR packages (pacman-static, mingw-w64-xz) (news.ycombinator.com).
- Treat any package touched by the implicated contributor over their roughly two years of involvement as suspect until independently verified, per the Fedora packager's comment that older xz versions warrant scrutiny too (news.ycombinator.com).
- Weigh repository suspension against archiving: commenters raised whether archiving instead of fully disabling repos would better balance containment against enabling continued forensic analysis; the sources don't say whether this was resolved (news.ycombinator.com).
- Build automated diffing between released tarball contents and the corresponding git tree to flag unexplained additions like the
build-to-host.m4change — proposed in discussion, not confirmed as adopted (news.ycombinator.com). - Add automated verification that configure-time and sandboxing checks (like the sabotaged Landlock check) actually pass on systems where the capability is expected, rather than silently failing closed (news.ycombinator.com).
- The sources do not say what formal, project-wide changes the xz/Tukaani project itself committed to, since its repositories were disabled at the time of these reports.
Sources
- security - backdoor in upstream xz/liblzma leading to ssh server compromise
[](https://www.openwall.com/) * [Products](https://www.openwall.com/) * [Openwall GNU/\*/Linux _server OS_](https://www.openwall.com/Owl/) * [Linux Kernel Runtime Guard](https://www.openwall.com/lkrg/) * [John the Ripper _password cracker_](https://www.openwall.com/john/) * [Free & Open Source for any platform](https://www.openwall.com/john/) * [in the cloud](https://www.openwall.com/john/cloud/) *
- Backdoor in upstream xz/liblzma leading to SSH server compromise
 [](https://news.ycombinator.com/vote?id=39866275&how=up&goto=item%3Fid%3D39865810) Very annoying - the apparent author of the backdoor was in communication with me over several weeks trying to get xz 5.6.x added to Fedora 40 & 41 because of it's "great new features". We even worked with him to fix the valgrind issue (which it turns out now was caused by the backdoor he had added). We had to race last night to fix the problem after an inadvertent brea