24
24
import java .nio .file .StandardOpenOption ;
25
25
import java .util .StringJoiner ;
26
26
import java .util .zip .GZIPInputStream ;
27
+ import java .util .zip .ZipEntry ;
27
28
import java .util .zip .ZipFile ;
28
29
import org .apache .baremaps .workflow .Task ;
29
30
import org .apache .baremaps .workflow .WorkflowContext ;
@@ -154,22 +155,27 @@ protected static void decompressTarBz2(Path source, Path target) throws IOExcept
154
155
}
155
156
}
156
157
157
- private static void decompressTar (Path target , TarArchiveInputStream tarInputStream )
158
+ public static void decompressTar (Path target , TarArchiveInputStream tarInputStream )
158
159
throws IOException {
159
160
TarArchiveEntry entry ;
160
161
while ((entry = tarInputStream .getNextEntry ()) != null ) {
161
- var path = target .resolve (entry .getName ());
162
- if (entry .isDirectory ()) {
163
- Files .createDirectories (path );
164
- } else {
165
- Files .createDirectories (path .getParent ());
166
- Files .write (path , new byte [] {},
167
- StandardOpenOption .CREATE ,
168
- StandardOpenOption .TRUNCATE_EXISTING );
169
- try (BufferedOutputStream outputStream =
170
- new BufferedOutputStream (Files .newOutputStream (path ))) {
171
- tarInputStream .transferTo (outputStream );
162
+ File destination = target .resolve (entry .getName ()).normalize ().toFile ();
163
+ String canonicalDestinationPath = destination .getCanonicalPath ();
164
+ String canonicalTargetPath = target .toFile ().getCanonicalPath ();
165
+ if (canonicalDestinationPath .startsWith (canonicalTargetPath )) {
166
+ if (entry .isDirectory ()) {
167
+ Files .createDirectories (destination .toPath ());
168
+ } else {
169
+ Files .createDirectories (destination .toPath ().getParent ());
170
+ try (BufferedOutputStream outputStream =
171
+ new BufferedOutputStream (Files .newOutputStream (destination .toPath (),
172
+ StandardOpenOption .CREATE ,
173
+ StandardOpenOption .TRUNCATE_EXISTING ))) {
174
+ tarInputStream .transferTo (outputStream );
175
+ }
172
176
}
177
+ } else {
178
+ throw new IOException ("Entry is outside of the target directory" );
173
179
}
174
180
}
175
181
}
@@ -183,23 +189,29 @@ private static void decompressTar(Path target, TarArchiveInputStream tarInputStr
183
189
*/
184
190
@ SuppressWarnings ("squid:S5042" )
185
191
protected static void decompressZip (Path source , Path target ) throws IOException {
186
- Files .createDirectories (target );
187
- try (var zipFile = new ZipFile (source .toFile ())) {
192
+ try (ZipFile zipFile = new ZipFile (source .toFile ())) {
188
193
var entries = zipFile .entries ();
189
194
while (entries .hasMoreElements ()) {
190
- var entry = entries .nextElement ();
191
- var path = target .resolve (entry .getName ());
192
- if (entry .isDirectory ()) {
193
- Files .createDirectories (path );
194
- } else {
195
- Files .createDirectories (path .getParent ());
196
- Files .write (path , new byte [] {},
197
- StandardOpenOption .CREATE ,
198
- StandardOpenOption .TRUNCATE_EXISTING );
199
- try (var input = new BufferedInputStream (zipFile .getInputStream (entry ));
200
- var output = new BufferedOutputStream (new FileOutputStream (path .toFile ()))) {
201
- input .transferTo (output );
195
+ ZipEntry entry = entries .nextElement ();
196
+ File destination = target .resolve (entry .getName ()).normalize ().toFile ();
197
+ String canonicalDestinationPath = destination .getCanonicalPath ();
198
+ String canonicalTargetPath = target .toFile ().getCanonicalPath ();
199
+
200
+ if (canonicalDestinationPath .startsWith (canonicalTargetPath )) {
201
+ if (entry .isDirectory ()) {
202
+ Files .createDirectories (destination .toPath ());
203
+ } else {
204
+ Files .createDirectories (destination .toPath ().getParent ());
205
+ try (BufferedInputStream input = new BufferedInputStream (zipFile .getInputStream (entry ));
206
+ BufferedOutputStream output =
207
+ new BufferedOutputStream (Files .newOutputStream (destination .toPath (),
208
+ StandardOpenOption .CREATE ,
209
+ StandardOpenOption .TRUNCATE_EXISTING ))) {
210
+ input .transferTo (output );
211
+ }
202
212
}
213
+ } else {
214
+ throw new IOException ("Entry is outside of the target directory" );
203
215
}
204
216
}
205
217
}
0 commit comments