mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
v3
This commit is contained in:
@@ -24,29 +24,53 @@ import java
|
||||
* Providing Decompression sinks and additional taint steps for `org.xerial.snappy` package
|
||||
*/
|
||||
module XserialSnappy {
|
||||
/**
|
||||
* A type that is responsible for `SnappyInputStream` Class
|
||||
*/
|
||||
class TypeInputStream extends RefType {
|
||||
TypeInputStream() {
|
||||
this.getASupertype*().hasQualifiedName("org.xerial.snappy", "SnappyInputStream")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets `n1` and `n2` which `SnappyInputStream n2 = new SnappyInputStream(n2)` 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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
(
|
||||
call.getCallee().getDeclaringType() instanceof TypeInputStream or
|
||||
call.(MethodAccess).getReceiverType() instanceof TypeInputStream
|
||||
) and
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeInputStream t) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(TypeInputStream t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `SnappyInputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
this.getReceiverType() instanceof TypeInputStream and
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
@@ -58,6 +82,9 @@ module XserialSnappy {
|
||||
* Providing Decompression sinks and additional taint steps for `org.apache.commons.compress` package
|
||||
*/
|
||||
module ApacheCommons {
|
||||
/**
|
||||
* A type that is responsible for `ArchiveInputStream` Class
|
||||
*/
|
||||
class TypeArchiveInputStream extends RefType {
|
||||
TypeArchiveInputStream() {
|
||||
this.getASupertype*()
|
||||
@@ -65,6 +92,9 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type that is responsible for `CompressorInputStream` Class
|
||||
*/
|
||||
class TypeCompressorInputStream extends RefType {
|
||||
TypeCompressorInputStream() {
|
||||
this.getASupertype*()
|
||||
@@ -72,7 +102,13 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Providing Decompression sinks and additional taint steps for `org.apache.commons.compress.compressors.*` Types
|
||||
*/
|
||||
module Compressors {
|
||||
/**
|
||||
* The types that are responsible for specific compression format of `CompressorInputStream` Class
|
||||
*/
|
||||
class TypeCompressors extends RefType {
|
||||
TypeCompressors() {
|
||||
this.getASupertype*()
|
||||
@@ -113,23 +149,44 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets `n1` and `n2` which `*CompressorInputStream n2 = new *CompressorInputStream(n2)` or
|
||||
* `n2 = inputStream.read(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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
(
|
||||
call.getCallee().getDeclaringType() instanceof TypeCompressors or
|
||||
call.(MethodAccess).getReceiverType() instanceof TypeCompressors
|
||||
) and
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeCompressors t) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(TypeCompressors t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `*CompressorInputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
this.getReceiverType() instanceof TypeCompressors and
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
@@ -137,7 +194,13 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Providing Decompression sinks and additional taint steps for Types from `org.apache.commons.compress.archivers.*` packages
|
||||
*/
|
||||
module Archivers {
|
||||
/**
|
||||
* The types that are responsible for specific compression format of `ArchiveInputStream` Class
|
||||
*/
|
||||
class TypeArchivers extends RefType {
|
||||
TypeArchivers() {
|
||||
this.getASupertype*()
|
||||
@@ -156,32 +219,43 @@ module ApacheCommons {
|
||||
}
|
||||
|
||||
/**
|
||||
*```java
|
||||
* ZipArchiveInputStream n2 = new ZipArchiveInputStream(n1);
|
||||
* ZipArchiveInputStream n = new ZipArchiveInputStream(inputStream);
|
||||
* n2 = n.read(n1);
|
||||
*```
|
||||
* Gets `n1` and `n2` which `*ArchiveInputStream n2 = new *ArchiveInputStream(n2)` or
|
||||
* `n2 = inputStream.read(n2)` 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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeArchivers t) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(TypeArchivers t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
// constructors
|
||||
call.getCallee().getDeclaringType() instanceof TypeArchivers
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() instanceof TypeArchivers
|
||||
) and
|
||||
n1.asExpr() = call.getArgument(0) and
|
||||
n2.asExpr() = call
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `*ArchiveInputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
this.getReceiverType() instanceof TypeArchivers and
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
@@ -189,7 +263,13 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Providing Decompression sinks and additional taint steps for `CompressorStreamFactory` and `ArchiveStreamFactory` Types
|
||||
*/
|
||||
module Factory {
|
||||
/**
|
||||
* A type that is responsible for `ArchiveInputStream` Class
|
||||
*/
|
||||
class TypeArchivers extends RefType {
|
||||
TypeArchivers() {
|
||||
this.getASupertype*()
|
||||
@@ -197,6 +277,9 @@ module ApacheCommons {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A type that is responsible for `CompressorStreamFactory` Class
|
||||
*/
|
||||
class TypeCompressors extends RefType {
|
||||
TypeCompressors() {
|
||||
this.getASupertype*()
|
||||
@@ -205,29 +288,43 @@ module ApacheCommons {
|
||||
}
|
||||
|
||||
/**
|
||||
* ```java
|
||||
*CompressorInputStream n2 = new CompressorStreamFactory().createCompressorInputStream(n1)
|
||||
*ArchiveInputStream n2 = new ArchiveStreamFactory().createArchiveInputStream(n1)
|
||||
* ```
|
||||
* 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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
// Constructors
|
||||
(
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeCompressors t)
|
||||
or
|
||||
call.getCallee().getDeclaringType() = any(TypeArchivers t)
|
||||
or
|
||||
// Method calls
|
||||
) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
(
|
||||
call.(MethodAccess).getReceiverType() = any(TypeArchiveInputStream t)
|
||||
or
|
||||
call.(MethodAccess).getReceiverType() = any(TypeCompressorInputStream t)
|
||||
) and
|
||||
n1.asExpr() = call.getArgument(0) and
|
||||
n2.asExpr() = call
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `CompressorInputStream` or `ArchiveInputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
(
|
||||
@@ -238,6 +335,9 @@ module ApacheCommons {
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
@@ -250,6 +350,9 @@ module ApacheCommons {
|
||||
* Providing Decompression sinks and additional taint steps for `net.lingala.zip4j.io` package
|
||||
*/
|
||||
module Zip4j {
|
||||
/**
|
||||
* A type that is responsible for `ZipInputStream` Class
|
||||
*/
|
||||
class TypeZipInputStream extends RefType {
|
||||
TypeZipInputStream() {
|
||||
this.hasQualifiedName("net.lingala.zip4j.io.inputstream", "ZipInputStream")
|
||||
@@ -257,10 +360,7 @@ module Zip4j {
|
||||
}
|
||||
|
||||
/**
|
||||
* ```java
|
||||
* n = new net.lingala.zip4j.io.inputstream.ZipInputStream(inputStream);
|
||||
* this = n.read(readBuffer);
|
||||
* ```
|
||||
* The methods that read bytes and belong to `CompressorInputStream` or `ArchiveInputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
@@ -268,6 +368,9 @@ module Zip4j {
|
||||
this.getMethod().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// while ((readLen = zipInputStream.read(readBuffer)) != -1) {
|
||||
@@ -288,22 +391,27 @@ module Zip4j {
|
||||
}
|
||||
|
||||
/**
|
||||
* ```java
|
||||
* n2 = new net.lingala.zip4j.io.inputstream.ZipInputStream(n1);
|
||||
* // or
|
||||
* n = new net.lingala.zip4j.io.inputstream.ZipInputStream(inputStream);
|
||||
* n2 = n.Method(n1);
|
||||
* ```
|
||||
* Gets `n1` and `n2` which `ZipInputStream n2 = new ZipInputStream(n1)` or `n2 = zipInputStream.read(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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
(
|
||||
call.getCallee().getDeclaringType() instanceof TypeZipInputStream or
|
||||
call.(MethodAccess).getReceiverType() instanceof TypeZipInputStream
|
||||
) and
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeZipInputStream t) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(TypeZipInputStream t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
(
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -312,6 +420,9 @@ module Zip4j {
|
||||
* Providing sinks that can be related to reading uncontrolled buffer and bytes for `org.apache.commons.io` package
|
||||
*/
|
||||
module CommonsIO {
|
||||
/**
|
||||
* The Access to Methods which work with byes and inputStreams and buffers
|
||||
*/
|
||||
class IOUtils extends MethodAccess {
|
||||
IOUtils() {
|
||||
this.getMethod()
|
||||
@@ -328,6 +439,9 @@ module CommonsIO {
|
||||
* Providing Decompression sinks and additional taint steps for `java.util.zip` package
|
||||
*/
|
||||
module Zip {
|
||||
/**
|
||||
* The Types that are responsible for `ZipInputStream`, `GZIPInputStream`, `InflaterInputStream` Classes
|
||||
*/
|
||||
class TypeInputStream extends RefType {
|
||||
TypeInputStream() {
|
||||
this.getASupertype*()
|
||||
@@ -336,44 +450,65 @@ module Zip {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `*InputStream` Types
|
||||
*/
|
||||
class ReadInputStreamCall extends MethodAccess {
|
||||
ReadInputStreamCall() {
|
||||
this.getReceiverType() instanceof TypeInputStream and
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
predicate isControlledRead() { none() }
|
||||
}
|
||||
|
||||
// *InputStream Izis = new *InputStream(inputStream)
|
||||
/**
|
||||
* Gets `n1` and `n2` which `*InputStream n2 = new *InputStream(n1)` or
|
||||
* `n2 = data.read(n1, 0, BUFFER)` or `n1.read(n2, 0, BUFFER)`,
|
||||
* 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
|
||||
*/
|
||||
predicate inputStreamAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
(
|
||||
call.getCallee().getDeclaringType() instanceof TypeInputStream or
|
||||
call.(MethodAccess).getReceiverType() instanceof TypeInputStream
|
||||
) and
|
||||
// Constructors
|
||||
call.getCallee().getDeclaringType() = any(TypeInputStream t) and
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
or
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(TypeInputStream t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
call.getArgument(0) = n2.asExpr() and
|
||||
call.getQualifier() = n1.asExpr()
|
||||
or
|
||||
call.getArgument(0) = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A type that is responsible for `Inflater` Class
|
||||
*/
|
||||
class TypeInflator extends RefType {
|
||||
TypeInflator() { this.hasQualifiedName("java.util.zip", "Inflater") }
|
||||
}
|
||||
|
||||
class Inflatorsource extends Call {
|
||||
Inflatorsource() {
|
||||
exists(Call c | c.getCallee().(Constructor).getDeclaringType() instanceof TypeInflator |
|
||||
this = c
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets `n1` and `n2` which `Inflater inflater_As_n2 = new Inflater(); inflater_As_n2 = inflater.setInput(n1)` or `n1.inflate(n2)` or
|
||||
* `n2 = inflater.inflate(n1)`,
|
||||
* third 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
|
||||
*/
|
||||
predicate inflatorAdditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
// inflater.inflate(n2)
|
||||
// n1.inflate(n2)
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof TypeInflator and
|
||||
ma.getArgument(0) = n2.asExpr() and
|
||||
@@ -381,8 +516,16 @@ module Zip {
|
||||
ma.getCallee().hasName("inflate")
|
||||
)
|
||||
or
|
||||
// n2 = inflater.inflate(n1)
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof TypeInflator and
|
||||
ma = n2.asExpr() and
|
||||
ma.getArgument(0) = n1.asExpr() and
|
||||
ma.getCallee().hasName("inflate")
|
||||
)
|
||||
or
|
||||
// Inflater inflater = new Inflater();
|
||||
// n2 = inflater.setInput(n1)
|
||||
// inflater_As_n2 = inflater.setInput(n1)
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof TypeInflator and
|
||||
n1.asExpr() = ma.getArgument(0) and
|
||||
@@ -391,32 +534,35 @@ module Zip {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `Inflater` Type
|
||||
*/
|
||||
class InflateCall extends MethodAccess {
|
||||
InflateCall() {
|
||||
this.getReceiverType() instanceof TypeInflator and
|
||||
this.getCallee().hasName("inflate")
|
||||
}
|
||||
|
||||
/**
|
||||
* An Argument which responsible for the destination of decompressed bytes and is used as a sink
|
||||
*/
|
||||
Expr getAWriteArgument() { result = this.getArgument(0) }
|
||||
|
||||
// look at Zip4j comments for this method
|
||||
predicate isControlledRead() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A type that is responsible for `ZipFile` Class
|
||||
*/
|
||||
class TypeZipFile extends RefType {
|
||||
TypeZipFile() { this.hasQualifiedName("java.util.zip", "ZipFile") }
|
||||
}
|
||||
|
||||
class ZipFilesource extends Call {
|
||||
ZipFilesource() {
|
||||
exists(Call c | c.getCallee().(Constructor).getDeclaringType() instanceof TypeZipFile |
|
||||
this = c
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ZipFile zipFileAsn2 = new ZipFile(n1);
|
||||
// InputStream n2 = zipFile.getInputStream(n1);
|
||||
/**
|
||||
* Gets `n1` and `n2` which `ZipFile n2 = new ZipFile(n1);` or
|
||||
* `InputStream n2 = zipFile.getInputStream(n1);` or `zipFile_As_n1.getInputStream(n2);`
|
||||
*/
|
||||
predicate zipFileadditionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(MethodAccess ma |
|
||||
ma.getReceiverType() instanceof TypeZipFile and
|
||||
@@ -433,6 +579,50 @@ module Zip {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Providing InputStream and it subClasses that mostly related to Sinks of ZipFile Type,
|
||||
* we can do
|
||||
*/
|
||||
module InputStream {
|
||||
/**
|
||||
* The Types that are responsible for `InputStream` Class and all classes that are child of InputStream Class
|
||||
*/
|
||||
class TypeInputStream extends RefType {
|
||||
TypeInputStream() { this.getASupertype*().hasQualifiedName("java.io", "InputStream") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The methods that read bytes and belong to `InputStream` Type and all Types that are child of InputStream Type
|
||||
*/
|
||||
class Read extends MethodAccess {
|
||||
Read() {
|
||||
this.getReceiverType() instanceof TypeInputStream and
|
||||
this.getCallee().hasName(["read", "readNBytes", "readAllBytes"])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* general additional taint steps for all inputStream and all Types that are child of inputStream
|
||||
*/
|
||||
predicate additionalTaintStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Call call |
|
||||
// Method calls
|
||||
call.(MethodAccess).getReceiverType() = any(InputStream::TypeInputStream t) and
|
||||
call.getCallee().hasName(["read", "readNBytes", "readAllBytes"]) and
|
||||
(
|
||||
// call.getArgument(0) = n2.asExpr() and
|
||||
// call.getQualifier() = n1.asExpr()
|
||||
// or
|
||||
// call.getArgument(0) = n1.asExpr() and
|
||||
// call = n2.asExpr()
|
||||
// or
|
||||
// TODO: only implement following
|
||||
call.getQualifier() = n1.asExpr() and
|
||||
call = n2.asExpr()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module DecompressionBombsConfig implements DataFlow::StateConfigSig {
|
||||
class FlowState = DataFlow::FlowState;
|
||||
@@ -483,9 +673,6 @@ module DecompressionBombsConfig implements DataFlow::StateConfigSig {
|
||||
)
|
||||
}
|
||||
|
||||
// predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
// inputStreamAdditionalTaintStep(nodeFrom, nodeTo)
|
||||
// }
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node nodeFrom, FlowState stateFrom, DataFlow::Node nodeTo, FlowState stateTo
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user