1616
1717import java .io .*;
1818import java .nio .file .Files ;
19+ import java .nio .file .Path ;
20+ import java .nio .file .Paths ;
1921import java .util .ArrayList ;
2022import java .util .List ;
2123import java .util .Stack ;
@@ -584,23 +586,31 @@ private static void compressToJar(File[] files, String outputPath) throws IOExce
584586
585587 private static void decompressZip (File archive , String directory ) throws IOException {
586588 byte [] buffer = new byte [BUFFER_SIZE ];
589+ final Path targetDir = Paths .get (directory ).toAbsolutePath ().normalize ();
587590 try (ZipInputStream zis = new ZipInputStream (Files .newInputStream (archive .toPath ()))) {
588591 ZipEntry zipEntry ;
589592 while ((zipEntry = zis .getNextEntry ()) != null ) {
590- File newFile = new File (directory , zipEntry .getName ());
591- if (zipEntry .isDirectory ()) {
592- if (!newFile .isDirectory () && !newFile .mkdirs ()) {
593- throw new IOException ("Failed to create directory " + newFile );
594- }
595- } else {
596- File parent = newFile .getParentFile ();
597- if (!parent .isDirectory () && !parent .mkdirs ()) {
598- throw new IOException ("Failed to create directory " + parent );
599- }
600- try (FileOutputStream fos = new FileOutputStream (newFile )) {
601- int len ;
602- while ((len = zis .read (buffer )) > 0 ) {
603- fos .write (buffer , 0 , len );
593+ Path entryPath = targetDir .resolve (zipEntry .getName ()).normalize ();
594+ if (!entryPath .startsWith (targetDir ))
595+ {
596+ log .error (DIRECTORY_ATTACK + "{}" , zipEntry .getName ());
597+ return ;
598+ }else {
599+ File newFile = entryPath .toFile ();
600+ if (zipEntry .isDirectory ()) {
601+ if (!newFile .isDirectory () && !newFile .mkdirs ()) {
602+ throw new IOException ("Failed to create directory " + newFile );
603+ }
604+ } else {
605+ File parent = newFile .getParentFile ();
606+ if (!parent .isDirectory () && !parent .mkdirs ()) {
607+ throw new IOException ("Failed to create directory " + parent );
608+ }
609+ try (FileOutputStream fos = new FileOutputStream (newFile )) {
610+ int len ;
611+ while ((len = zis .read (buffer )) > 0 ) {
612+ fos .write (buffer , 0 , len );
613+ }
604614 }
605615 }
606616 }
@@ -610,23 +620,30 @@ private static void decompressZip(File archive, String directory) throws IOExcep
610620
611621 private static void decompress7z (File archive , String directory ) throws IOException {
612622 byte [] buffer = new byte [BUFFER_SIZE ];
623+ final Path targetDir = Paths .get (directory ).toAbsolutePath ().normalize ();
613624 try (SevenZFile sevenZFile = new SevenZFile (archive )) {
614625 SevenZArchiveEntry entry ;
615626 while ((entry = sevenZFile .getNextEntry ()) != null ) {
616- File newFile = new File (directory , entry .getName ());
617- if (entry .isDirectory ()) {
618- if (!newFile .isDirectory () && !newFile .mkdirs ()) {
619- throw new IOException ("Failed to create directory " + newFile );
620- }
621- } else {
622- File parent = newFile .getParentFile ();
623- if (!parent .isDirectory () && !parent .mkdirs ()) {
624- throw new IOException ("Failed to create directory " + parent );
625- }
626- try (OutputStream out = Files .newOutputStream (newFile .toPath ())) {
627- int bytesRead ;
628- while ((bytesRead = sevenZFile .read (buffer )) != -1 ) {
629- out .write (buffer , 0 , bytesRead );
627+ Path entryPath = targetDir .resolve (entry .getName ()).normalize ();
628+ if (!entryPath .startsWith (targetDir )) {
629+ log .error (DIRECTORY_ATTACK + "{}" , entry .getName ());
630+ return ;
631+ }else {
632+ File newFile = entryPath .toFile ();
633+ if (entry .isDirectory ()) {
634+ if (!newFile .isDirectory () && !newFile .mkdirs ()) {
635+ throw new IOException ("Failed to create directory " + newFile );
636+ }
637+ } else {
638+ File parent = newFile .getParentFile ();
639+ if (!parent .isDirectory () && !parent .mkdirs ()) {
640+ throw new IOException ("Failed to create directory " + parent );
641+ }
642+ try (OutputStream out = Files .newOutputStream (newFile .toPath ())) {
643+ int bytesRead ;
644+ while ((bytesRead = sevenZFile .read (buffer )) != -1 ) {
645+ out .write (buffer , 0 , bytesRead );
646+ }
630647 }
631648 }
632649 }
@@ -636,23 +653,30 @@ private static void decompress7z(File archive, String directory) throws IOExcept
636653
637654 private static void decompressTar (File archive , String directory ) throws IOException {
638655 byte [] buffer = new byte [BUFFER_SIZE ];
656+ final Path targetDir = Paths .get (directory ).toAbsolutePath ().normalize ();
639657 try (TarArchiveInputStream tis = new TarArchiveInputStream (Files .newInputStream (archive .toPath ()))) {
640658 TarArchiveEntry entry ;
641659 while ((entry = tis .getNextEntry ()) != null ) {
642- File newFile = new File (directory , entry .getName ());
643- if (entry .isDirectory ()) {
644- if (!newFile .isDirectory () && !newFile .mkdirs ()) {
645- throw new IOException ("Failed to create directory " + newFile );
646- }
647- } else {
648- File parent = newFile .getParentFile ();
649- if (!parent .isDirectory () && !parent .mkdirs ()) {
650- throw new IOException ("Failed to create directory " + parent );
651- }
652- try (OutputStream out = Files .newOutputStream (newFile .toPath ())) {
653- int len ;
654- while ((len = tis .read (buffer )) != -1 ) {
655- out .write (buffer , 0 , len );
660+ Path entryPath = targetDir .resolve (entry .getName ()).normalize ();
661+ if (!entryPath .startsWith (targetDir )) {
662+ log .error (DIRECTORY_ATTACK + "{}" , entry .getName ());
663+ return ;
664+ }else {
665+ File newFile = entryPath .toFile ();
666+ if (entry .isDirectory ()) {
667+ if (!newFile .isDirectory () && !newFile .mkdirs ()) {
668+ throw new IOException ("Failed to create directory " + newFile );
669+ }
670+ } else {
671+ File parent = newFile .getParentFile ();
672+ if (!parent .isDirectory () && !parent .mkdirs ()) {
673+ throw new IOException ("Failed to create directory " + parent );
674+ }
675+ try (OutputStream out = Files .newOutputStream (newFile .toPath ())) {
676+ int len ;
677+ while ((len = tis .read (buffer )) != -1 ) {
678+ out .write (buffer , 0 , len );
679+ }
656680 }
657681 }
658682 }
0 commit comments