ZipToolView zip files online — 100% private

What is Zip Slip?

Zip Slip is a path-traversal vulnerability in archive extraction. A malicious archive stores an entry whose name climbs out of the destination folder — something like ../../../../etc/cronjob — and a buggy extractor faithfully writes the file there, outside the directory you chose. It was catalogued publicly by the security team at Snyk in 2018 and turned out to affect dozens of unzip libraries across many languages.

The root cause is mundane. An extractor takes the target directory, appends the entry’s name, and writes — without checking whether .. segments (or a leading absolute path) resolve above the target. The fix is correspondingly simple: normalize the path and strip or reject any segment that would escape, before a single byte is written.

The reassuring part is the scope. Zip Slip is an *extraction* bug, not a *viewing* bug. Listing a file tree or previewing an entry inside a viewer writes nothing to disk, so it cannot trigger. Browsing an untrusted archive is safe; the risk only appears in code that extracts files to the filesystem, and only when that code forgets to sanitize. See the full picture in security and privacy.

How Zip Slip works

The zip format lets an entry’s filename be almost any string, including strings with directory separators and parent-directory references. There is nothing malformed about an entry called ../../../../etc/cronjob from the format’s point of view — it is just a name. The vulnerability appears when an extractor trusts that name as a real filesystem path.

Imagine extracting into /tmp/work. A naive extractor concatenates the target with the entry name: /tmp/work + /../../../../etc/cronjob resolves to /etc/cronjob. The file is written a long way above the folder you picked. If that destination is a location the operating system or another program reads and executes — a cron directory, a startup folder, a DLL search path, a plugin folder — the attacker has just planted code where it will run, which is how a path traversal becomes remote code execution.

The escape need not use forward slashes. On Windows, backslash variants (..\..\Windows\System32\...) and drive-absolute paths (C:\boot.ini or /etc/passwd on Unix) achieve the same climb. A robust defense has to handle all of them, which is why the bug kept reappearing: each new extractor had to remember every form, and some did not.

  • Forward-slash climb: ../../../../etc/cronjob resolves above the target.
  • Backslash climb on Windows: ..\..\Windows\System32\evil.dll.
  • Absolute paths: /etc/passwd (Unix) or C:\Windows\... (Windows) ignore the target entirely.
  • If the escaped destination is executed (cron, startup, DLL/plugin path), traversal becomes code execution.

Why it is an extraction bug, not an archive bug

The archive is not broken. The zip format intentionally permits arbitrary filename strings; it is the extractor’s responsibility to refuse names that are unsafe as filesystem paths. Zip Slip is a bug in the code that unpacks, not in the bytes that are packed. The same class of traversal exists for tar, jar, and any format that carries a stored path.

This distinction is what makes browsing safe. Building a file tree and previewing an entry never writes to disk at all — there is nothing for a traversal to climb, because nothing is being placed on the filesystem. The attack surface exists only at the moment bytes are written to real paths, which is exclusively an extraction operation.

Which libraries were affected

When Snyk published Zip Slip in 2018, the finding was not a single bug in one product — it was a class of bug spread across the ecosystem. Vulnerable extraction code turned up in libraries for Java, Go, JavaScript and Node.js, Python, Ruby, .NET, and Android, including widely used packages that had to ship patches. The common thread was always the same missing check before writing.

Because the flaw is a pattern rather than a one-off, it keeps being rediscovered. Related path-traversal issues in popular archivers — including 7-Zip — were still being assigned CVEs in 2025. The lesson the industry took from Zip Slip is that path sanitization has to be a default, built into every extractor, not an afterthought a developer remembers to add.

  • Snyk catalogued Zip Slip in 2018 across Java, Go, JS/Node, Python, Ruby, .NET, and Android libraries.
  • It is a recurring pattern, not a single incident — each new extractor must remember to sanitize.
  • Related path-traversal CVEs in archivers such as 7-Zip were still appearing in 2025.

How ZipTool defends against it

ZipTool handles the traversal case at the one place it matters: before writing an entry to disk during extraction. Every entry path is sanitized first. The path is split on both / and \, each segment is trimmed, and every empty, ., or .. segment is dropped before the parts are rejoined. So ../../../../etc/cronjob collapses to etc/cronjob, and an absolute path like /etc/passwd loses its leading slash and becomes the relative etc/passwd — always landing inside the directory you chose.

The directory walk that recreates folder structure only ever creates nested directory handles underneath your chosen root, never resolving above it, so even a pathological name has nowhere harmful to go. And because previewing and listing never touch the filesystem, the traversal surface simply is not present when you are browsing. In short: the dangerous operation (writing real files to real paths) is the one that is guarded.

This is worth saying plainly because it is easy to overstate. Sanitizing paths defends against Zip Slip specifically — an entry escaping its folder. It does not make a malicious *file* harmless once you have extracted and run it, and it does not change the malware risk covered in security and privacy. It closes one well-known class of extraction bug so that what you extract lands where you expect it.

  • Entry paths are sanitized before any write: split on / and \, drop every ., .., and empty segment.
  • Absolute paths become relative, so they stay inside the chosen directory.
  • The folder walk only creates handles under the chosen root — it never resolves above it.
  • Previewing and listing never write to disk, so the traversal surface is absent while browsing.

Checking your own extractor

If you write or maintain code that unpacks archives, the defense is small and worth making automatic. The robust pattern is to resolve the final destination to its canonical absolute path and then assert that it starts with the canonical absolute path of the target directory — if it does not, the entry is trying to escape and should be skipped or renamed. Doing this check once, in one place, closes the whole class.

The strip-segments approach ZipTool uses is the lighter version: normalize the name to forward slashes, drop every . and .. segment and any leading separator, and what remains is guaranteed relative and contained. Either approach works as long as it runs before the write. The trap to avoid is concatenating target + name and trusting the result; that is the one line every vulnerable extractor had in common.

  • Resolve the destination canonically and assert it is under the target directory.
  • Or normalize the name and strip ., .., and leading separators up front.
  • Apply the check once, before writing — never trust target-plus-name directly.
  • Test with an archive whose entry names contain ../ and confirm none land outside.

Frequently asked questions

What is Zip Slip?

Zip Slip is a path-traversal vulnerability in archive extraction, catalogued by Snyk in 2018. A malicious archive stores entries with names like ../../../../etc/cronjob, and a vulnerable extractor writes the file outside the chosen destination folder. If the escaped destination is executed by the OS or another program, the traversal can become remote code execution. It is a bug in extraction code, not in the zip format itself.

How does Zip Slip work?

A naive extractor joins the target directory with the entry’s stored name and writes the result. With a name like ../../../../etc/cronjob extracted into /tmp/work, the destination resolves to /etc/cronjob — above the folder you picked. Backslash variants and absolute paths such as /etc/passwd or C:\Windows\... achieve the same escape on the relevant operating system.

Is Zip Slip an extraction bug or a viewing bug?

Strictly an extraction bug. Listing an archive’s file tree or previewing an entry in a viewer writes nothing to the filesystem, so there is nothing for a path to traverse. The vulnerability only appears in code that extracts files to real paths, and only when that code trusts the stored entry name without sanitizing it.

Was my extractor affected by Zip Slip?

Possibly, if it was written before 2018 and never patched. Snyk’s 2018 advisory named vulnerable libraries across Java, Go, JavaScript and Node.js, Python, Ruby, .NET, and Android. If you use a maintained, post-2018 version of a mainstream library, it almost certainly sanitizes paths. When in doubt, check the library’s changelog for a Zip Slip or path-traversal fix.

Does ZipTool protect against Zip Slip?

Yes. Before writing an entry to disk during extraction, ZipTool sanitizes the path: it splits on / and \, trims each segment, and drops every empty, ., and .. segment, so ../../etc/cronjob collapses to etc/cronjob and absolute paths become relative. The folder walk only ever creates directory handles under your chosen root. Browsing and previewing never write to disk at all, so the traversal surface is absent while you are viewing an archive.

How do I fix Zip Slip in my own code?

Run one check before writing: resolve the destination to its canonical absolute path and assert it starts with the canonical absolute path of the target directory; if not, skip or rename the entry. The lighter version is to normalize the name to forward slashes and strip every ., .., and leading separator. Either way, never trust a bare target-plus-name concatenation — that single line is what every vulnerable extractor had in common.