DedSec Project

Safe archive inspection: nested files, symlinks and size limits — DedSec Project

Inspect archives as structured data before extraction Enumerate without trusting file names An archive entry's stored name may contain parent traversal ../ , absolute paths, repeated names…

Inspect archives as structured data before extraction

Enumerate without trusting file names

An archive entry's stored name may contain parent traversal ../, absolute paths, repeated names or platform-specific separators. The declared uncompressed size can be enormous relative to its compressed size. Before accepting an unknown ZIP, set limits for file count, total uncompressed bytes and per-entry size; normalize names without permitting escape from the destination.

from pathlib import PurePosixPath
names = ["docs/readme.txt", "../outside.txt", "/absolute/config"]
for name in names:
    parts = PurePosixPath(name.replace("\\", "/")).parts
    safe = not name.startswith(("/", "\\")) and ".." not in parts
    print(name, safe)

Detect collisions before writing

Files named A.txt and a.txt may collide on case-insensitive systems. Repeated paths in one archive might be interpreted differently by different extractors. Symlink targets can point outside the extraction root even when entry names look harmless. A content scanner must consider the resolved destination and refuse unsupported link types, not merely strip ../ from suspicious strings.

Use a deliberately hostile fixture

Create a tiny ZIP whose members include one safe path, one traversal path and two case-colliding names, without extracting it to a real project. Build a validator that returns a structured list of rejected entries. The expected behavior is fail-closed on the entire archive or quarantined extraction under a deliberately safe policy, not silently writing some unsafe members.

Success boundaries

Document each configured limit and verify that zero bytes are written outside a disposable extraction root. A valid CRC does not prove a safe filename, acceptable decompressed size or trustworthy publisher. Keep the test archive alongside a hash and the expected rejection report.