Safeguard
Engineering

Insider Threats in Open Source Projects: Lessons from XZ Utils

The XZ Utils backdoor was a three-year social engineering operation, not a coding mistake. What the timeline shows about maintainer trust, and what you can actually monitor.

Marcus Webb
DevSecOps Lead
6 min read

The XZ Utils backdoor (CVE-2024-3094) was not a software bug — it was a multi-year insider operation in which the persona "Jia Tan" earned maintainer rights to a foundational compression library, then hid an SSH backdoor in build scripts and binary test files that ordinary code review never inspects. It earned a CVSS score of 10.0, and unlike most 10.0s, nobody argued the score was inflated. The only reason it did not become the worst supply chain incident on record is that a Postgres developer noticed his SSH logins were about 500 milliseconds slower than they should have been.

If your threat model for open source stops at "known CVEs in our dependencies," XZ is the case study that proves the model incomplete. The attack surface was not the code. It was the maintainer.

The timeline, compressed

DateEvent
Late 2021GitHub account JiaT75 created; first innocuous patches to xz
Mid 2022Sock-puppet accounts pressure maintainer Lasse Collin on the mailing list
Jan 2023Jia Tan gains commit access
Mar 2023Jia Tan becomes primary release contact; oss-fuzz config quietly adjusted
Jul 2023Groundwork lands: ifunc support that later hosts the hook
Feb 24, 2024xz 5.6.0 released with the backdoor
Mar 9, 2024xz 5.6.1 released, patching backdoor bugs that caused valgrind noise
Mar 29, 2024Andres Freund reports the backdoor after profiling slow sshd logins

Three years from account creation to payload. The persona filed useful patches, fixed real bugs, and behaved like a model contributor for long enough that commit access looked like the obvious next step.

The pressure campaign was the exploit

Lasse Collin maintained xz essentially alone, unpaid, and said openly on the mailing list that he was dealing with burnout. Right on cue, accounts named "Jigar Kumar" and "Dennis Ens" — never seen before, never seen since — began posting complaints: patches were rotting, the project was dying, progress would not happen "until there is a new maintainer." Jia Tan, helpful and patient, was the visible contrast.

This is the part worth internalizing. The technical payload was sophisticated, but the initial access technique was a coordinated harassment campaign against one exhausted volunteer. Every dependency in your tree with a bus factor of one is exposed to exactly this play. You can enumerate those: check maintainer counts and commit concentration for your critical transitive dependencies. Tools that surface OpenSSF Scorecard data will flag single-maintainer projects for you, and the list is usually longer than anyone expects.

Why code review never saw it

The backdoor was engineered to live in the places review does not reach:

  • The malicious object code was hidden inside two binary test fixtures, tests/files/bad-3-corrupt_lzma2.xz and tests/files/good-large_compressed.lzma. Binary test files are effectively review-exempt in most projects.
  • The extraction logic lived in a modified build-to-host.m4 that existed only in the release tarball, not in the git repository. Anyone auditing the repo saw clean autoconf files.
  • At build time — and only when building for x86-64 glibc Linux inside deb or rpm packaging — the script stitched the payload into liblzma.
  • At runtime, a GNU indirect function (ifunc) resolver hooked RSA_public_decrypt in sshd, which links liblzma indirectly through libsystemd on most systemd distributions. The backdoor gave the attacker's key remote code execution before authentication.

Every layer exploited a review blind spot: binary artifacts, generated build scripts, tarball-versus-git drift, and dynamic linking that connects a compression library to your SSH daemon without anyone deciding it should.

Signals you can actually monitor

You will not out-review a professional operation, but several of the blind spots are mechanically checkable:

  1. Diff release tarballs against tagged source. The build-to-host.m4 divergence was detectable with a single comparison between git archive output and the published tarball. Some ecosystems now do this for you — npm provenance and PyPI attestations bind a package to its source repo — but for C projects distributed as tarballs, you have to check.
  2. Alert on binary files in dependency updates. A new or changed binary blob in a version bump of a compression library is worth one human minute.
  3. Watch maintainer-change plus cadence-change together. New primary maintainer followed by an unusually eager release push (Jia Tan personally lobbied Debian and Fedora to ship 5.6.x quickly) is a strong combined signal.
  4. Introduce a soak period. The backdoor lived in the newest releases only. Organizations that lag hot-off-the-press versions of low-level libraries by 2–4 weeks were structurally immune. A software composition analysis pipeline like Safeguard SCA can enforce a minimum release age policy so "don't adopt day-zero releases of core libraries" is a gate, not a habit.

None of these are exotic. They are boring controls aimed at the exact seams this attack used.

When it happens anyway: answer the exposure question fast

The morning of March 29, 2024, every security team on Earth asked the same question: do we run xz 5.6.0 or 5.6.1 anywhere? Teams with current SBOMs answered in minutes with a query. Teams without them answered in days, by SSHing into boxes and running xz --version, which is a grim way to spend a Friday. Maintaining queryable inventory through something like SBOM Studio is the difference between an incident and an all-hands fire drill — the same lesson we covered in our piece on reconstructing dependency compromise timelines.

The other post-incident lesson: distributions reverted to 5.4.x within hours, and Lasse Collin — the person the campaign was designed to sideline — led the cleanup and shipped a clean 5.6.2. The ecosystem's response was genuinely fast. The intrusion's three-year runway was the failure, not the final week.

Frequently asked questions

Was the XZ backdoor ever exploited in the wild?

No confirmed exploitation has been reported. The compromised versions, 5.6.0 and 5.6.1, only reached bleeding-edge distributions like Debian sid, Fedora Rawhide/40 beta, and openSUSE Tumbleweed before discovery. Stable enterprise distributions never shipped it.

How was the backdoor actually discovered?

Andres Freund, a PostgreSQL developer at Microsoft, was benchmarking and noticed sshd logins consuming unusual CPU and adding roughly 500 ms of latency, alongside valgrind errors in liblzma. He traced the slowdown to the injected code and reported it on March 29, 2024. It was luck — expensive, well-earned luck.

Would an SBOM have prevented the attack?

No. SBOMs are inventory, not prevention; nothing in a manifest reveals a backdoor hidden in test fixtures. What an SBOM does is collapse your incident response time from days to minutes when the disclosure lands, which materially changes the blast radius.

Is "Jia Tan" one person?

Unknown, and probably not. The operational discipline — consistent timezone patterns pointing away from the claimed identity, multi-year patience, coordinated sock puppets, and the payload's engineering quality — has led most analysts to assess it as a state-sponsored team operating a shared persona.

Never miss an update

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