@@ -86,21 +86,38 @@ public static void extractFiles(File archive, File extractTo, Engine engine) thr
8686        if  (archive  == null  || extractTo  == null ) {
8787            return ;
8888        }
89- 
89+         final  String  destPath ;
90+         try  {
91+             destPath  = extractTo .getCanonicalPath ();
92+         } catch  (IOException  ex ) {
93+             throw  new  ExtractionException ("Unable to extract files to destination path" , ex );
94+         }
9095        ZipEntry  entry ;
9196        try  (FileInputStream  fis  = new  FileInputStream (archive );
9297                BufferedInputStream  bis  = new  BufferedInputStream (fis );
9398                ZipInputStream  zis  = new  ZipInputStream (bis )) {
9499            while  ((entry  = zis .getNextEntry ()) != null ) {
95100                if  (entry .isDirectory ()) {
96101                    final  File  d  = new  File (extractTo , entry .getName ());
102+                     if  (!d .getCanonicalPath ().startsWith (destPath )) {
103+                         final  String  msg  = String .format (
104+                                 "Archive (%s) contains a path that would be extracted outside of the target directory." ,
105+                                 archive .getAbsolutePath ());
106+                         throw  new  ExtractionException (msg );
107+                     }
97108                    if  (!d .exists () && !d .mkdirs ()) {
98109                        final  String  msg  = String .format ("Unable to create '%s'." , d .getAbsolutePath ());
99110                        throw  new  ExtractionException (msg );
100111                    }
101112                } else  {
102113                    final  File  file  = new  File (extractTo , entry .getName ());
103114                    if  (engine  == null  || engine .accept (file )) {
115+                         if  (!file .getCanonicalPath ().startsWith (destPath )) {
116+                             final  String  msg  = String .format (
117+                                     "Archive (%s) contains a file that would be extracted outside of the target directory." ,
118+                                     archive .getAbsolutePath ());
119+                             throw  new  ExtractionException (msg );
120+                         }
104121                        try  (FileOutputStream  fos  = new  FileOutputStream (file )) {
105122                            IOUtils .copy (zis , fos );
106123                        } catch  (FileNotFoundException  ex ) {
@@ -136,8 +153,7 @@ public static void extractFilesUsingFilter(File archive, File destination, Filen
136153        }
137154
138155        try  (FileInputStream  fis  = new  FileInputStream (archive )) {
139-             extractArchive (new  ZipArchiveInputStream (new  BufferedInputStream (
140-                     fis )), destination , filter );
156+             extractArchive (new  ZipArchiveInputStream (new  BufferedInputStream (fis )), destination , filter );
141157        } catch  (FileNotFoundException  ex ) {
142158            final  String  msg  = String .format ("Error extracting file `%s` with filter: %s" , archive .getAbsolutePath (), ex .getMessage ());
143159            LOGGER .debug (msg , ex );
@@ -163,9 +179,17 @@ private static void extractArchive(ArchiveInputStream input,
163179            throws  ArchiveExtractionException  {
164180        ArchiveEntry  entry ;
165181        try  {
182+             String  destPath  = destination .getCanonicalPath ();
183+ 
166184            while  ((entry  = input .getNextEntry ()) != null ) {
167185                if  (entry .isDirectory ()) {
168186                    final  File  dir  = new  File (destination , entry .getName ());
187+                     if  (!dir .getCanonicalPath ().startsWith (destPath )) {
188+                         final  String  msg  = String .format (
189+                                 "Archive contains a path (%s) that would be extracted outside of the target directory." ,
190+                                 dir .getAbsolutePath ());
191+                         throw  new  AnalysisException (msg );
192+                     }
169193                    if  (!dir .exists () && !dir .mkdirs ()) {
170194                        final  String  msg  = String .format (
171195                                "Unable to create directory '%s'." ,
@@ -197,21 +221,30 @@ private static void extractArchive(ArchiveInputStream input,
197221    private  static  void  extractFile (ArchiveInputStream  input , File  destination ,
198222            FilenameFilter  filter , ArchiveEntry  entry ) throws  ExtractionException  {
199223        final  File  file  = new  File (destination , entry .getName ());
200-         if  (filter .accept (file .getParentFile (), file .getName ())) {
201-             LOGGER .debug ("Extracting '{}'" , file .getPath ());
202-             createParentFile (file );
224+         try  {
225+             if  (filter .accept (file .getParentFile (), file .getName ())) {
226+                 final  String  destPath  = destination .getCanonicalPath ();
227+                 if  (!file .getCanonicalPath ().startsWith (destPath )) {
228+                     final  String  msg  = String .format (
229+                             "Archive contains a file (%s) that would be extracted outside of the target directory." ,
230+                             file .getAbsolutePath ());
231+                     throw  new  ExtractionException (msg );
232+                 }
233+                 LOGGER .debug ("Extracting '{}'" , file .getPath ());
234+                 createParentFile (file );
203235
204-             try  (FileOutputStream  fos  = new  FileOutputStream (file )) {
205-                 IOUtils .copy (input , fos );
206-             } catch  (FileNotFoundException  ex ) {
207-                 LOGGER .debug ("" , ex );
208-                 final  String  msg  = String .format ("Unable to find file '%s'." , file .getName ());
209-                 throw  new  ExtractionException (msg , ex );
210-             } catch  (IOException  ex ) {
211-                 LOGGER .debug ("" , ex );
212-                 final  String  msg  = String .format ("IO Exception while parsing file '%s'." , file .getName ());
213-                 throw  new  ExtractionException (msg , ex );
236+                 try  (FileOutputStream  fos  = new  FileOutputStream (file )) {
237+                     IOUtils .copy (input , fos );
238+                 } catch  (FileNotFoundException  ex ) {
239+                     LOGGER .debug ("" , ex );
240+                     final  String  msg  = String .format ("Unable to find file '%s'." , file .getName ());
241+                     throw  new  ExtractionException (msg , ex );
242+                 }
214243            }
244+         } catch  (IOException  ex ) {
245+             LOGGER .debug ("" , ex );
246+             final  String  msg  = String .format ("IO Exception while parsing file '%s'." , file .getName ());
247+             throw  new  ExtractionException (msg , ex );
215248        }
216249    }
217250
0 commit comments