Safeguard
Supply Chain•

xz Utils: why the backdoor lived in the release tarball, not git

The xz backdoor build script sat in release tarballs but not in git. Here is why that gap matters and how to compare tarballs with source tags.

Safeguard Security Team
4 min read

In the xz Utils backdoor, a key obfuscated build script appeared in the release tarballs but not in the upstream git repository. Anyone who reviewed only git would have missed it. The practical lesson is to treat the tarball you build from as a separate artifact and compare it with the tagged source.

What the public analysis says

Andres Freund's report to the oss-security list on 29 March 2024 describes a file called m4/build-to-host.m4. He states it was present in the release tarballs for xz 5.6.0 and 5.6.1 but absent from upstream git. The script ran at the end of configure and changed how liblzma was built, so that it unpacked and ran another shell script.

Two obfuscated test files were also committed to the repository, so git was not clean either. The point is narrower: the piece that wired everything into the build was only in the archive people downloaded.

Why this gap is easy to miss

Most review habits assume the repository is the source of truth. Code review, static analysis and blame all run on git. Packagers, though, often start from a release archive published by the maintainers.

Autotools makes this worse. Release tarballs commonly contain generated files, such as a configure script and m4 macros, that are not stored in git. Those files are legitimate, long, and rarely read by humans. That is a good place to hide something.

The same report says the script checked whether the build was running as part of a Debian or RPM package, among other conditions. It would not do its work in every environment, which reduces the chance a casual build reveals it.

A comparison you can run

You do not need special tooling to start. For any dependency you build from an archive:

# fetch the archive and the tagged source
tar -xf project-1.2.3.tar.gz
git clone --depth 1 --branch v1.2.3 https://example.org/project.git
# compare, ignoring the .git directory
diff -r --exclude=.git project-1.2.3 project

Expect differences. Generated build files will show up. The value is in reading the list: every file that exists only in the archive deserves a reason. Any file that is both archive-only and unusually large, minified or encoded deserves a closer look.

What to change in your process

  • Record the hash of every archive you build from, and the tag or commit you believe it matches.
  • Prefer building from a tagged source checkout when the project supports it, and regenerate build files yourself.
  • Flag archive-only files that are executable, encoded or very long.
  • Watch for new maintainers or sudden changes in release handling on libraries you depend on deeply.
  • Keep an inventory so that when an advisory lands you can answer where the library lives. CISA's alert named 5.6.0 and 5.6.1 and advised a downgrade to an uncompromised version such as 5.4.6.

None of this guarantees you will catch a patient attacker. It does turn an invisible gap into a visible diff.

Where Safeguard fits

Safeguard's SBOM and dependency scanning can tell you which of your builds contain a given library and version, which is the first question after an advisory like this. You can try a free scan at gold.safeguard.sh/scan. It does not replace comparing archives with source.

Quick check

Was the xz backdoor only in the tarball?

No. Per the public report, the build script that activated it was tarball only, but obfuscated test files were also committed to the repository.

Which xz versions were affected?

Versions 5.6.0 and 5.6.1, according to the oss-security report and the CISA alert.

Sources

Last reviewed: 19 October 2026.

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.