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.