update tests for zip4j, add aditional flow steps for zip4j, remove BombTypeInputStream class since we don't need it anymore, add a predicate which was for testing porpose and was junk

This commit is contained in:
am0o0
2024-07-29 18:10:04 +02:00
parent c8749ff82e
commit 4dc1a10f71
2 changed files with 25 additions and 31 deletions

View File

@@ -23,8 +23,6 @@ module DecompressionBomb {
private class ReadInputStreamQualifierSink extends DecompressionBomb::Sink {
ReadInputStreamQualifierSink() { this.asExpr() = any(BombReadInputStreamCall r).getQualifier() }
}
abstract class BombTypeInputStream extends RefType { }
}
/**
@@ -34,7 +32,7 @@ module XerialSnappy {
/**
* A type that is responsible for `SnappyInputStream` Class
*/
class TypeInputStream extends DecompressionBomb::BombTypeInputStream {
class TypeInputStream extends RefType {
TypeInputStream() {
this.getASupertype*().hasQualifiedName("org.xerial.snappy", "SnappyInputStream")
}
@@ -99,7 +97,7 @@ module ApacheCommons {
/**
* The types that are responsible for specific compression format of `CompressorInputStream` Class
*/
class TypeCompressors extends DecompressionBomb::BombTypeInputStream {
class TypeCompressors extends RefType {
TypeCompressors() {
this.getASupertype*()
.hasQualifiedName("org.apache.commons.compress.compressors.gzip",
@@ -163,15 +161,6 @@ module ApacheCommons {
)
}
}
predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(Call call |
// Constructors
call.getCallee().getDeclaringType() instanceof TypeCompressors and
call.getArgument(0) = n1.asExpr() and
call = n2.asExpr()
)
}
}
/**
@@ -181,7 +170,7 @@ module ApacheCommons {
/**
* The types that are responsible for specific compression format of `ArchiveInputStream` Class
*/
class TypeArchivers extends DecompressionBomb::BombTypeInputStream {
class TypeArchivers extends RefType {
TypeArchivers() {
this.getASupertype*()
.hasQualifiedName("org.apache.commons.compress.archivers.ar", "ArArchiveInputStream") or
@@ -235,7 +224,7 @@ module ApacheCommons {
/**
* A type that is responsible for `ArchiveInputStream` Class
*/
class TypeArchivers extends DecompressionBomb::BombTypeInputStream {
class TypeArchivers extends RefType {
TypeArchivers() {
this.getASupertype*()
.hasQualifiedName("org.apache.commons.compress.archivers", "ArchiveStreamFactory")
@@ -253,11 +242,7 @@ module ApacheCommons {
}
/**
* Gets `n1` and `n2` which `CompressorInputStream n2 = new CompressorStreamFactory().createCompressorInputStream(n1)`
* or `ArchiveInputStream n2 = new ArchiveStreamFactory().createArchiveInputStream(n1)` or
* `n1.read(n2)`,
* second one is added because of sanitizer, we want to compare return value of each `read` or similar method
* that whether there is a flow to a comparison between total read of decompressed stream and a constant value
* Gets `n1` and `n2` which `ZipInputStream n2 = new ZipInputStream(n1)`
*/
private class CompressorsAndArchiversAdditionalTaintStep extends DecompressionBomb::AdditionalStep
{
@@ -314,12 +299,21 @@ module Zip4j {
}
}
class Sink extends DecompressionBomb::Sink {
Sink() {
this.asExpr() = any(ReadInputStreamCall r).getQualifier()
or
exists(ConstructorCall call | call.getConstructedType() instanceof TypeZipInputStream |
this.asExpr() = call.getArgument(0)
/**
* Gets `n1` and `n2` which `CompressorInputStream n2 = new CompressorStreamFactory().createCompressorInputStream(n1)`
* or `ArchiveInputStream n2 = new ArchiveStreamFactory().createArchiveInputStream(n1)` or
* `n1.read(n2)`,
* second one is added because of sanitizer, we want to compare return value of each `read` or similar method
* that whether there is a flow to a comparison between total read of decompressed stream and a constant value
*/
private class CompressorsAndArchiversAdditionalTaintStep extends DecompressionBomb::AdditionalStep
{
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(Call call |
// Constructors
call.getCallee().getDeclaringType() instanceof TypeZipInputStream and
call.getArgument(0) = n1.asExpr() and
call = n2.asExpr()
)
}
}
@@ -332,7 +326,7 @@ module Zip {
/**
* The Types that are responsible for `ZipInputStream`, `GZIPInputStream`, `InflaterInputStream` Classes
*/
class TypeInputStream extends DecompressionBomb::BombTypeInputStream {
class TypeInputStream extends RefType {
TypeInputStream() {
this.getASupertype*()
.hasQualifiedName("java.util.zip",

View File

@@ -12,11 +12,11 @@ public class Zip4jHandler {
LocalFileHeader localFileHeader;
int readLen;
byte[] readBuffer = new byte[4096];
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { // $ hasTaintFlow="inputStream"
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
File extractedFile = new File(localFileHeader.getFileName());
try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) { // $ hasTaintFlow="zipInputStream"
outputStream.write(readBuffer, 0, readLen);
}
}
@@ -28,12 +28,12 @@ public class Zip4jHandler {
LocalFileHeader localFileHeader;
int readLen;
byte[] readBuffer = new byte[4096];
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) { // $ hasTaintFlow="inputStream"
try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
File extractedFile = new File(localFileHeader.getFileName());
try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
int totallRead = 0;
while ((readLen = zipInputStream.read(readBuffer)) != -1) {
while ((readLen = zipInputStream.read(readBuffer)) != -1) { // $ hasTaintFlow="zipInputStream"
totallRead += readLen;
if (totallRead > 1024 * 1024 * 4) {
System.out.println("potential Bomb");