APS-45Recommended
Unpack archives safely
Keep every entry of an uploaded zip or tar file inside the target folder, and stop unpacking at a fixed total size and file count.
How to do it
Check each entry's name before writing it, as in keep file paths inside their folder. Skip links and device files. Count the bytes as you unpack, and stop at a cap such as 100 MB and 1,000 files. A small archive can expand to many gigabytes. Apply the same caps to compressed request bodies. Scan files for malware before anyone opens what came out.
Examples
Python example
# Python 3.12 or later: the data filter refuses paths outside dest, links out and device files
MAX_BYTES, MAX_FILES = 100 * 1024 * 1024, 1000
with tarfile.open(upload_path) as tar:
members = tar.getmembers()
if len(members) > MAX_FILES or sum(m.size for m in members) > MAX_BYTES:
raise ValueError("archive too large")
tar.extractall(dest, filter="data")
Go example
// Go 1.20 or later: filepath.IsLocal refuses absolute paths and ".."
var total uint64
for count, entry := range zipReader.File {
if !filepath.IsLocal(entry.Name) || entry.Mode()&(fs.ModeSymlink|fs.ModeDevice) != 0 {
return errors.New("unsafe entry: " + entry.Name)
}
total += entry.UncompressedSize64 // the header can lie, so also copy through io.LimitReader
if count >= maxFiles || total > maxBytes {
return errors.New("archive too large")
}
}
How to check
On the test copy, the agent uploads three archives. One has an entry named ../../marker.txt, one holds a link to /etc, and one expands past the cap. All three are refused, and no file appears outside the target folder.
Sources
Related rules
- APS-44 Keep file paths inside their folder in Application security
- MED-44 Scan files for malware before anyone opens them in Files and media
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/requests-files-and-caches/safe-archive-extraction">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.