java 36 lines · 8 steps

Extracting a zip safely in Java

A zip extractor that streams each entry to disk while defending against path-traversal attacks.

Explained by highlit
1public final class ZipExtractor {
2 
3 private final Path targetDir;
4 
5 public ZipExtractor(Path targetDir) {
6 this.targetDir = targetDir.toAbsolutePath().normalize();
7 }
8 
9 public void extract(Path archive) throws IOException {
10 try (ZipInputStream zis = new ZipInputStream(
11 new BufferedInputStream(Files.newInputStream(archive)))) {
12 ZipEntry entry;
13 while ((entry = zis.getNextEntry()) != null) {
14 Path resolved = resolveSafely(entry.getName());
15 if (entry.isDirectory()) {
16 Files.createDirectories(resolved);
17 } else {
18 Files.createDirectories(resolved.getParent());
19 try (OutputStream out = Files.newOutputStream(resolved,
20 StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
21 zis.transferTo(out);
22 }
23 }
24 zis.closeEntry();
25 }
26 }
27 }
28 
29 private Path resolveSafely(String entryName) throws IOException {
30 Path resolved = targetDir.resolve(entryName).normalize();
31 if (!resolved.startsWith(targetDir)) {
32 throw new IOException("Blocked path traversal attempt: " + entryName);
33 }
34 return resolved;
35 }
36}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Always validate resolved zip entry paths against the target root to prevent Zip Slip attacks.
  2. 2Normalizing paths up front makes later containment checks with startsWith reliable.
  3. 3Try-with-resources on nested streams guarantees handles close even when extraction fails.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Extracting a zip safely in Java — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code