mirror of
https://github.com/github/codeql.git
synced 2026-03-04 22:56:47 +01:00
Java: Add taint step for InputStream wrappers
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
import Member
|
||||
import semmle.code.java.security.ExternalProcess
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.FlowSteps
|
||||
|
||||
// --- Standard types ---
|
||||
@@ -177,6 +178,11 @@ class TypeObjectInputStream extends RefType {
|
||||
TypeObjectInputStream() { this.hasQualifiedName("java.io", "ObjectInputStream") }
|
||||
}
|
||||
|
||||
/** The class `java.io.InputStream`. */
|
||||
class TypeInputStream extends RefType {
|
||||
TypeInputStream() { this.hasQualifiedName("java.io", "InputStream") }
|
||||
}
|
||||
|
||||
/** The class `java.nio.file.Paths`. */
|
||||
class TypePaths extends Class {
|
||||
TypePaths() { this.hasQualifiedName("java.nio.file", "Paths") }
|
||||
@@ -197,6 +203,48 @@ class TypeFile extends Class {
|
||||
TypeFile() { this.hasQualifiedName("java.io", "File") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint step from an update of the `bytes[]` parameter in an override of the `InputStream.read` method
|
||||
* to a class instance expression of the type extending `InputStream`.
|
||||
*
|
||||
* This models how a subtype of `InputStream` could be tainted by the definition of its methods, which will
|
||||
* normally only happen in anonymous classes.
|
||||
*/
|
||||
private class InputStreamWrapperAnonymousStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(Method m, AnonymousClass wrapper |
|
||||
m.hasName("read") and
|
||||
m.getDeclaringType() = wrapper and
|
||||
wrapper.getASourceSupertype+() instanceof TypeInputStream
|
||||
|
|
||||
n1.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = m.getParameter(0).getAnAccess() and
|
||||
n2.asExpr() = wrapper.getClassInstanceExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint step from an `InputStream` argument of the constructor of an `InputStream` subtype
|
||||
* to the call of the constructor, only if the argument is assigned to a class field.
|
||||
*
|
||||
* This models how it's assumed that an `InputStream` wrapper is tainted by the wrapped stream,
|
||||
* and is a workaround to low `fieldFlowBranchLimit`s in dataflow configurations.
|
||||
*/
|
||||
private class InputStreamWrapperConstructorStep extends AdditionalTaintStep {
|
||||
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
exists(ClassInstanceExpr cc, Argument a, AssignExpr ae |
|
||||
cc.getConstructedType().getASourceSupertype+() instanceof TypeInputStream and
|
||||
cc.getAnArgument() = a and
|
||||
cc.getCallee().getParameter(a.getParameterPos()).getAnAccess() = ae.getRhs() and
|
||||
ae.getDest().(FieldWrite).getField().getType().(RefType).getASourceSupertype*() instanceof
|
||||
TypeInputStream
|
||||
|
|
||||
n1.asExpr() = a and
|
||||
n2.asExpr() = cc
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// --- Standard methods ---
|
||||
/**
|
||||
* DEPRECATED: Any constructor of class `java.lang.ProcessBuilder`.
|
||||
|
||||
@@ -757,7 +757,7 @@ private predicate baseBound(Expr e, int b, boolean upper) {
|
||||
or
|
||||
exists(Method read |
|
||||
e.(MethodAccess).getMethod().overrides*(read) and
|
||||
read.getDeclaringType().hasQualifiedName("java.io", "InputStream") and
|
||||
read.getDeclaringType() instanceof TypeInputStream and
|
||||
read.hasName("read") and
|
||||
read.getNumberOfParameters() = 0
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user