Compression Gotchas and Safety¶
Tarbombs¶
A tarbomb is an archive without a single top-level directory that sprays files across your current directory, sometimes overwriting existing ones. Always look first:
tar tf archive.tar.gz | head
unzip -l archive.zip | head
Or extract into a fresh directory:
mkdir out && tar xf archive.tar.gz -C out
aunpack, dtrx and unar do this automatically (universal extractors).
Decompression bombs¶
A small file that expands to an enormous size (gigabytes or terabytes) can fill a disk or exhaust memory. With untrusted input, check the declared size first and enforce limits:
gzip -l file.gz # unreliable over 4 GiB
xz -l file.xz
zstd -l file.zst
unzip -l file.zip
In services, cap the total bytes written and the number of entries rather than trusting headers, which can lie.
Path traversal ("zip slip")¶
Malicious archives can contain entries like ../../etc/cron.d/x, absolute paths, or symlinks that point outside the destination followed by files written "through" them.
- GNU tar strips leading
/and refuses..components by default. - Info-ZIP
unzipstrips../components. - Library code and less careful tools may do neither.
Never extract untrusted archives as root, and validate every path when extracting programmatically (see Rust).
Never run an untrusted shar¶
Shell archives (.shar) are scripts that recreate files when run. Read them, or use unshar, rather than executing them.
Source files disappear (or don't)¶
| Tool | Default behaviour on the input file |
|---|---|
| gzip, bzip2, xz, lzip, compress | Deletes it (-k keeps it) |
| zstd, lz4, brotli, lzop | Keeps it (--rm / -U deletes it) |
| tar, zip, 7z | Never touch sources |
Scripts that switch from gzip to zstd and rely on the source being removed will quietly double their disk usage.
Flag order and argument traps¶
- With bundled tar flags,
fmust come last:tar czf name.tar.gz, nottar cfz(which creates an archive namedz). - Arguments after the archive name in
tar xare members to extract, not a destination. Use-C dir. - Match the compression flag to the file when listing (
tar tjvf file.tar.gzfails), or omit it and let tar detect it. tar -Capplies only to the arguments that follow it.7z -otakes its value with no space:-o/tmp/dest.lz4 in outtreats the second filename as the output, unlike most tools.
Compress, then encrypt¶
Encrypted data doesn't compress. Also avoid weak encryption: zip -e (ZipCrypto) and openssl des3 without -pbkdf2. See encryption.
Operations that need uncompressed tarballs¶
tar -r (append), -u (update), --delete, and -W (verify) only work on plain .tar. Decompress, modify, recompress — or keep a plain tar and compress at the end.
Data that won't compress¶
JPEG, PNG, MP3, MP4, existing archives, and encrypted data barely shrink. Store them instead of recompressing (zip -n, 7z -mx=0, plain tar).
Many tiny files compressed individually compress poorly (no shared history, plus per-file overhead). Tar them first, or use zstd dictionaries.
Metadata and special files¶
| Feature | tar/cpio | zip | 7z |
|---|---|---|---|
| Unix permissions | Yes | Mostly (Info-ZIP) | Partially |
| Owners/groups | Yes | No | No |
| Symlinks | Yes | With -y |
Partially |
| Hard links | Yes | No | No |
| Device files, FIFOs | Yes | No | No |
| ACLs, xattrs, SELinux labels | With flags (GNU tar) | No | No |
| Sparse files | With -S |
No | No |
Use tar for system backups.
Other edge cases¶
- Long paths: use
--format=posix(pax);ustarlimits paths to 255 characters and files to 8 GiB. - Restoring ownership: as root, tar restores original owners, which can be surprising in containers; use
--no-same-owner. Use--numeric-ownerwhen user names map to different IDs on the target. - Memory: high xz presets and
zstd --ultra/--longneed lots of memory on both ends, and can be OOM-killed in containers. - Threads in containers:
-T0sees the host's CPUs. See parallel compression. gzip -lis wrong for files over 4 GiB and for multi-member files.- Old xz-utils: versions 5.6.0 and 5.6.1 contain a backdoor. See xz.