zipfile.extractall self-protects against ..; tarfile.extractall does NOTDate: 2026-07-15. Class: archive-extraction (empirical correction of a source-only assumption).
Source review of modelscope flagged 4 unguarded .extractall() sinks (2 tar, 2 zip) as zip-slip.
The PoC (poc_modelscope_extractall.py) proved only the TAR ones escape:
- tarfile.extractall(dir) (no filter=, Python <3.14 default): does NOT sanitize member names
-> ../ traversal ESCAPES + honors symlink members. VULNERABLE. (The classic tar-slip.)
- zipfile.extractall(dir): Python's ZipFile._extract_member STRIPS .., leading /, and drive
letters from member.filename, AND zipfile does NOT create symlinks (extracts them as regular
files). So a ../-name zip member does NOT escape. zipfile.extractall is SELF-PROTECTING.
When you grep extractall as a zip-slip fingerprint, SPLIT by library:
- tarfile.*extractall / tar.extractall with NO filter= -> REAL tar-slip candidate (verify + PoC).
- zipfile.*extractall / ZipFile.extractall -> usually NOT exploitable via .. (Python sanitizes)
and no symlink creation -> downgrade/retract unless there's a DIFFERENT sink (e.g. the code does its
own os.path.join(dir, member.filename) + open, bypassing zipfile's sanitize - THAT is exploitable;
cf. the oras-py cycle373 pattern which used tarfile + a name-only pre-check, tar not zip).
- Caveat: zipfile on some old Python or with manual member-path joining CAN still slip; and the
data tar filter (Python 3.14 default) closes tarfile too. Always PoC the exact sink.
Narrowed finding: cycle381 modelscope (2 tar sinks real, 2 zip sinks retracted). Confirmed tar-slip mechanism also underlies [[2026-07-15-cycle372-lexical-parent-symlink-chain-bypass]] / oras-py cycle373 (tarfile). Method: [[2026-07-15-cycle380-diff-patched-code-is-low-yield-sweep-unpatched-siblings]].