Skip to content

Commit

Permalink
[tests] fix zip Slip
Browse files Browse the repository at this point in the history
It was possible to create a directory outside the extraction directory.
https://github.com/eclipse-jdt/eclipse.jdt.core/security/code-scanning/38

Also simplified the code for extraction.

Tested by FullSourceWorkspaceASTTests
  • Loading branch information
EcljpseB0T authored and jukzi committed Sep 5, 2024
1 parent 365bc57 commit 788b82c
Showing 1 changed file with 21 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.*;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.zip.*;

Expand Down Expand Up @@ -1218,68 +1219,31 @@ public static String toString(String[] strings, boolean addExtraNewLine) {
}
return buffer.toString();
}
private static String getZipEntryFileName(File destDir, ZipEntry e, String canonicalDestDirPath) throws IOException {
String result = e.getName();
File destfile = new File(destDir, result);
String canonicalDestFile = destfile.getCanonicalPath();
if (!canonicalDestFile.startsWith(canonicalDestDirPath + File.separator)) {
throw new ZipEntryStorageException("Entry is outside of the target dir: " + e.getName());
}
return result;
}
/**
* Unzip the contents of the given zip in the given directory (create it if it doesn't exist)
*/
public static void unzip(String zipPath, String destDirPath) throws IOException {

InputStream zipIn = new FileInputStream(zipPath);
byte[] buf = new byte[8192];
File destDir = new File(destDirPath);
String canonicalDestDirPath = destDir.getCanonicalPath();
ZipInputStream zis = new ZipInputStream(zipIn);
FileOutputStream fos = null;
try {
ZipEntry zEntry;
while ((zEntry = zis.getNextEntry()) != null) {
// if it is empty directory, create it
if (zEntry.isDirectory()) {
new File(destDir, zEntry.getName()).mkdirs();
continue;
}
// if it is a file, extract it
String filePath = getZipEntryFileName(destDir, zEntry, canonicalDestDirPath);
int lastSeparator = filePath.lastIndexOf("/"); //$NON-NLS-1$
String fileDir = ""; //$NON-NLS-1$
if (lastSeparator >= 0) {
fileDir = filePath.substring(0, lastSeparator);
}
//create directory for a file
new File(destDir, fileDir).mkdirs();
//write file
File outFile = new File(destDir, filePath);
fos = new FileOutputStream(outFile);
int n = 0;
while ((n = zis.read(buf)) >= 0) {
fos.write(buf, 0, n);
}
fos.close();
}
} catch (IOException ioe) {
if (fos != null) {
try {
fos.close();
} catch (IOException ioe2) {
}
}
} finally {
try {
zipIn.close();
if (zis != null)
zis.close();
} catch (IOException ioe) {
}
}
File destDir = new File(destDirPath);
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipPath))) {
ZipEntry zEntry;
while ((zEntry = zis.getNextEntry()) != null) {
// if it is empty directory, create it
String filePath = org.eclipse.jdt.internal.core.util.Util.getEntryName(destDirPath, zEntry);
File outFile = new File(destDir, filePath);
if (zEntry.isDirectory()) {
outFile.mkdirs();
continue;
}
// if it is a file, extract it
Path entryTarget = outFile.toPath();
// create directory for a file
Files.createDirectories(entryTarget.getParent());
// write file
Files.copy(zis, entryTarget);
}
}
}

public static void waitAtLeast(int time) {
long start = System.currentTimeMillis();
do {
Expand Down

0 comments on commit 788b82c

Please sign in to comment.