Skip to content

Commit

Permalink
Prevent zip slip and path injection (#875)
Browse files Browse the repository at this point in the history
  • Loading branch information
bchapuis committed Jun 13, 2024
1 parent 375d0a3 commit cb617a5
Showing 1 changed file with 37 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.file.StandardOpenOption;
import java.util.StringJoiner;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.baremaps.workflow.Task;
import org.apache.baremaps.workflow.WorkflowContext;
Expand Down Expand Up @@ -154,22 +155,26 @@ protected static void decompressTarBz2(Path source, Path target) throws IOExcept
}
}

private static void decompressTar(Path target, TarArchiveInputStream tarInputStream)
throws IOException {
public static void decompressTar(Path target, TarArchiveInputStream tarInputStream) throws IOException {
TarArchiveEntry entry;
while ((entry = tarInputStream.getNextEntry()) != null) {
var path = target.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(path);
} else {
Files.createDirectories(path.getParent());
Files.write(path, new byte[] {},
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
try (BufferedOutputStream outputStream =
new BufferedOutputStream(Files.newOutputStream(path))) {
tarInputStream.transferTo(outputStream);
Path resolvedPath = target.resolve(entry.getName()).normalize();
File file = resolvedPath.toFile();

String canonicalDestinationPath = file.getCanonicalPath();
String canonicalTargetPath = target.toFile().getCanonicalPath();

if (canonicalDestinationPath.startsWith(canonicalTargetPath)) {
if (entry.isDirectory()) {
Files.createDirectories(resolvedPath);
} else {
Files.createDirectories(resolvedPath.getParent());
try (BufferedOutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(resolvedPath, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING))) {
tarInputStream.transferTo(outputStream);
}
}
} else {
throw new IOException("Entry is outside of the target directory");
}
}
}
Expand All @@ -183,23 +188,28 @@ private static void decompressTar(Path target, TarArchiveInputStream tarInputStr
*/
@SuppressWarnings("squid:S5042")
protected static void decompressZip(Path source, Path target) throws IOException {
Files.createDirectories(target);
try (var zipFile = new ZipFile(source.toFile())) {
try (ZipFile zipFile = new ZipFile(source.toFile())) {
var entries = zipFile.entries();
while (entries.hasMoreElements()) {
var entry = entries.nextElement();
var path = target.resolve(entry.getName());
if (entry.isDirectory()) {
Files.createDirectories(path);
} else {
Files.createDirectories(path.getParent());
Files.write(path, new byte[] {},
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING);
try (var input = new BufferedInputStream(zipFile.getInputStream(entry));
var output = new BufferedOutputStream(new FileOutputStream(path.toFile()))) {
input.transferTo(output);
ZipEntry entry = entries.nextElement();
Path resolvedPath = target.resolve(entry.getName()).normalize();
File file = resolvedPath.toFile();

String canonicalDestinationPath = file.getCanonicalPath();
String canonicalTargetPath = target.toFile().getCanonicalPath();

if (canonicalDestinationPath.startsWith(canonicalTargetPath)) {
if (entry.isDirectory()) {
Files.createDirectories(resolvedPath);
} else {
Files.createDirectories(resolvedPath.getParent());
try (BufferedInputStream input = new BufferedInputStream(zipFile.getInputStream(entry));
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(file))) {
input.transferTo(output);
}
}
} else {
throw new IOException("Entry is outside of the target directory");
}
}
}
Expand Down

0 comments on commit cb617a5

Please sign in to comment.