---
title: "Unpack archives safely · Agent Wranglers"
url: https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/safe-archive-extraction
updated: 2026-10-20
licence: "All rights reserved"
---

# Unpack archives safely

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Requests and files](https://agentwranglers.se/playbook/adversarial-testing/requests-and-files)
- Rule: 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: Check each entry's name before writing it, as in [keep file paths inside their folder](https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/block-path-traversal). 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.
- Check: The agent uploads an archive with an entry named `../../marker.txt`, one with a link to `/etc`, and one that expands past the cap. All three are refused, and no file appears outside the target folder.

Example:

```python
# 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
// 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")
	}
}
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/safe-archive-extraction`.

- Previous: [Treat data from other APIs as untrusted](https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/third-party-api-data)
- Next: [Keep private pages out of shared caches](https://agentwranglers.se/playbook/adversarial-testing/requests-and-files/private-responses-uncached)
- [Requests and files](https://agentwranglers.se/playbook/adversarial-testing/requests-and-files)
