fix: prevent zipbomb forged headers attacks (#980, PR #982)

This commit is contained in:
skylot
2020-09-27 21:10:30 +03:00
committed by GitHub
parent 73ca2e0fa4
commit 9b1761f71f
6 changed files with 125 additions and 40 deletions
@@ -7,7 +7,6 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -69,7 +68,7 @@ public final class ResourcesLoader {
if (!ZipSecurity.isValidZipEntry(entry)) {
return null;
}
try (InputStream inputStream = new BufferedInputStream(zipFile.getInputStream(entry))) {
try (InputStream inputStream = ZipSecurity.getInputStreamForEntry(zipFile, entry)) {
return decoder.decode(entry.getSize(), inputStream);
}
}
@@ -129,17 +128,9 @@ public final class ResourcesLoader {
return;
}
if (FileUtils.isZipFile(file)) {
try (ZipFile zip = new ZipFile(file)) {
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (ZipSecurity.isValidZipEntry(entry)) {
addEntry(list, file, entry);
}
}
} catch (Exception e) {
LOG.warn("Failed to open zip file: {}", file.getAbsolutePath());
}
ZipSecurity.visitZipEntries(file, (zipFile, entry) -> {
addEntry(list, file, entry);
});
} else {
addResourceFile(list, file);
}
@@ -325,22 +325,22 @@ public class ClsSet {
private void load(File input) throws IOException, DecodeException {
String name = input.getName();
try (InputStream inputStream = new FileInputStream(input)) {
if (name.endsWith(CLST_EXTENSION)) {
if (name.endsWith(CLST_EXTENSION)) {
try (InputStream inputStream = new FileInputStream(input)) {
load(inputStream);
} else if (name.endsWith(".jar")) {
try (ZipInputStream in = new ZipInputStream(inputStream)) {
ZipEntry entry = in.getNextEntry();
while (entry != null) {
if (entry.getName().endsWith(CLST_EXTENSION) && ZipSecurity.isValidZipEntry(entry)) {
load(in);
}
entry = in.getNextEntry();
}
} else if (name.endsWith(".jar")) {
ZipSecurity.readZipEntries(input, (entry, in) -> {
if (entry.getName().endsWith(CLST_EXTENSION)) {
try {
load(in);
} catch (Exception e) {
throw new JadxRuntimeException("Failed to load jadx class set");
}
}
} else {
throw new JadxRuntimeException("Unknown file format: " + name);
}
});
} else {
throw new JadxRuntimeException("Unknown file format: " + name);
}
}
@@ -2,6 +2,7 @@ package jadx.core.xmlgen;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import org.slf4j.Logger;
@@ -89,9 +90,11 @@ public class ResourcesSaver implements Runnable {
private void saveResourceFile(ResourceFile resFile, File outFile) throws JadxException {
ResourcesLoader.decodeStream(resFile, (size, is) -> {
Path target = outFile.toPath();
try {
Files.copy(is, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
Files.deleteIfExists(target); // delete partially written file
throw new JadxRuntimeException("Resource file save error", e);
}
return null;