A AegiFlow
HIGHCVSS 7.7

GHSA-fr26-jjhm-638c

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

Published
2026-10-09
Modified
2026-10-09
Sources
github-advisory

Summary

### 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 : # 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 ```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 - "]}' ls -l # → 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 packages

EcosystemPackageAffected versionsFixed versions
PyPIpyload-ng——

Remediation: No patched version is listed by GitHub.

References

Includes data from the GitHub Advisory Database, licensed under CC-BY 4.0.