@@ -370,19 +370,31 @@ public static void unzip(ZipInputStream in, File destDir) throws IOException {
370370 public static void unzipFile (File sourceFile , File destDir ) throws IOException {
371371 if (!sourceFile .exists ()) throw new IOException ("source file does not exist: " + sourceFile );
372372
373+ // Canonicalize destination directory path
374+ File canonicalDestDir = destDir .getCanonicalFile ();
375+
373376 try (ZipFile zipFile = new ZipFile (sourceFile )) {
374377 Enumeration <? extends ZipEntry > entries = zipFile .entries ();
375378
376379 while (entries .hasMoreElements ()) {
377380 ZipEntry entry = entries .nextElement ();
378381 if (entry .isDirectory ()) continue ;
379382
380- File file = new File (destDir , entry .getName ());
381- String path = file .getAbsolutePath ();
383+ // Create file object and validate path
384+ File file = new File (canonicalDestDir , entry .getName ());
385+ File canonicalFile = file .getCanonicalFile ();
386+
387+ // Prevent zip slip - check if file path is within destination directory
388+ if (!canonicalFile .toPath ().startsWith (canonicalDestDir .toPath ())) {
389+ throw new IOException ("Entry is outside of the target directory: " + entry .getName ());
390+ }
391+
392+ // Create parent directories
382393 file .getParentFile ().mkdirs ();
383394
395+ // Extract file content
384396 try (InputStream is = zipFile .getInputStream (entry );
385- OutputStream os = new BufferedOutputStream (new FileOutputStream (path ))) {
397+ OutputStream os = new BufferedOutputStream (new FileOutputStream (canonicalFile ))) {
386398 IOUtils .copy (is , os );
387399 }
388400 }
0 commit comments