Supply Graph

February 16, 2026 · View on GitHub

Detecting supply chain attacks in Debian package builds through graph-based build system tracing.

Caution

This project contains the CVE-2024-3094 and is only meant for research and demonstration purposes!

Warning

This project is not maintained and is for research purposes only!

Overview

This project uses the XZ Upstream Supply Chain Attack (CVE-2024-3094) as a case study to demonstrate how supply chain attacks can be detected by tracing the build system with a graph-based approach.

C/C++ build systems (GNU autotools, Make, CMake) have grown highly complex, exposing a large attack surface. However, at their core, these build systems all compile source code to object files and link them into executables or libraries. For FLOSS projects, we can postulate that every binary must originate from source code within the upstream project. This relationship is modeled as a directed graph — by traversing it, we can verify that all distributed binaries originate from upstream source code, successfully detecting the supply chain attack.

Further studies could scale this approach to analyze all Debian packages regularly to detect anomalies early. To make attacks harder to conceal, the authors propose transitioning to a descriptive build system, which reduces complexity and increases transparency.

Publications

Architecture

The implementation uses a combination of bpftrace and a custom FUSE overlay filesystem to capture all filesystem and IPC (pipe) communication during the build process.

The supply graph is a directed graph representing data flow during a Debian package build:

  • Nodes: Processes (compiler, linker, shell, etc.) and Files (source, object, binary)
  • Edges: Read, Write, Spawn, and Pipe relationships between nodes

By verifying that all distributed binaries (.o, .a, executables) are reachable from upstream source files through legitimate compilation processes, anomalies indicating supply chain attacks can be identified.

Notable challenges:

  • Build processes (especially autotools) perform unexpected operations like overwriting files with different content, moving, and copying (requires tracking content and timing)
  • Some compilation steps communicate not only via files but also via pipes (stdin/stdout), so a filesystem-only view is not sufficient

The main entry point is the build.sh script, which orchestrates the package build and monitoring.

Alternative Build Tracing Methods

Different methods exist on Linux to trace what happens inside a build system. The following have been explored as part of this project:

Requirements

  • Debian Linux (the current implementation does not support Docker and may modify the system)
  • sudo access
  • uv (Python package manager)
  • Python 3.12+
  • C++ compiler (clang++)
  • bpftrace
  • debuild / dpkg-source
  • chroot
  • libfuse3
  • boost
  • Kuzu graph database

Getting Started

1. Build the C++ tools

make
sudo make install

2. Install Python dependencies

uv sync

3. Download test packages

The preparation script downloads the following Debian package sources:

  • xz-5.6.1 (contains CVE-2024-3094)
  • xz-5.6.2
  • openssh-9.2p1
  • openssl-3.0.15
./prepare.sh

4. Run the build analysis

sudo ./bin/build.sh data/xz-5.6.1/xz-utils_5.6.1-1.dsc

5. Analyze the supply graph

uv run analyze-fuse-graph data/xz-5.6.1/

Identified anomalies are displayed at the end of the log:

[...]
Import into Kuzu DB...
Analyzing Graph...
[...]
{
    "object-source-proc": [
        "as",
        "cp",
        "head",
        "ld",
        "strip"
    ],
    "bad-object-source": [
        {
            "_id": {
                "offset": 3763,
                "table": 1
            },
            "_label": "File",
            "hash": "b418bfd34aa246b2e7b5cb5d263a640e5d080810f767370c4d2c24662a2749634735887",
            "inode": "4735887",
            "sha256": "b418bfd34aa246b2e7b5cb5d263a640e5d080810f767370c4d2c24662a274963",
            "path": "/data/xz-5.6.1/xz-utils-5.6.1/debian/normal-build/src/liblzma/liblzma_la-crc64-fast.o",
            "name": "liblzma_la-crc64-fast.o",
            "type": ".o",
            "is_upstream": false
        }
    ],
    "top-level-file-types": [
        "",
        ".0t",
        ".1",
        ".Debian",
        ".ac",
        ".am",
        ".docs",
        ".gmo",
        ".in",
        ".inc",
        ".lzma",
        ".m4",
        ".map"
    ]
}

The liblzma_la-crc64-fast.o object file is flagged as anomalous — it does not originate from upstream source code, which is the injected backdoor from CVE-2024-3094.

Build Artifacts

Each analysis run produces the following artifacts in the package data directory:

FileDescription
bpftrace.jsonIPC communication trace
fuse.jsonFilesystem operation trace
build.logBuild process log
db.kuzuKuzu graph database populated with the supply graph
packet.files.csvList of files per Debian package
upstream_files.txtList of files in the upstream archive
result.jsonAnalysis result with detected anomalies

Visualize the Supply Graph

Use the Kuzu web UI to browse and visualize the graph:

docker run -p 8000:8000 \
    -v ./data/xz-5.6.1/db:/database:Z \
    -e KUZU_FILE=db.kuzu \
    --rm kuzudb/explorer:latest

Then open http://localhost:8000 in your browser.

Docker Limitations

bpftrace does not currently work inside Docker (bpftrace#4384), and there are PID namespace mismatches between eBPF (kernel space) and FUSE (userspace inside the container).

A possible workaround is to run the build step inside the container and monitor from outside.

Future Work

  • Docker compatibility
  • Evaluate Tetragon as an alternative to bpftrace

License

This project is licensed under the Apache License 2.0.

Acknowledgments

This project is developed by Fraunhofer AISEC.

This work was funded by the German Federal Ministry of Education and Research (BMBF) as part of the ALPAKA project.