44
55import Member
66import semmle.code.java.security.ExternalProcess
7+ private import semmle.code.java.dataflow.DataFlow
78private import semmle.code.java.dataflow.FlowSteps
89
910// --- Standard types ---
@@ -177,6 +178,11 @@ class TypeObjectInputStream extends RefType {
177178 TypeObjectInputStream ( ) { this .hasQualifiedName ( "java.io" , "ObjectInputStream" ) }
178179}
179180
181+ /** The class `java.io.InputStream`. */
182+ class TypeInputStream extends RefType {
183+ TypeInputStream ( ) { this .hasQualifiedName ( "java.io" , "InputStream" ) }
184+ }
185+
180186/** The class `java.nio.file.Paths`. */
181187class TypePaths extends Class {
182188 TypePaths ( ) { this .hasQualifiedName ( "java.nio.file" , "Paths" ) }
@@ -197,6 +203,48 @@ class TypeFile extends Class {
197203 TypeFile ( ) { this .hasQualifiedName ( "java.io" , "File" ) }
198204}
199205
206+ /**
207+ * A taint step from an update of the `bytes[]` parameter in an override of the `InputStream.read` method
208+ * to a class instance expression of the type extending `InputStream`.
209+ *
210+ * This models how a subtype of `InputStream` could be tainted by the definition of its methods, which will
211+ * normally only happen in anonymous classes.
212+ */
213+ private class InputStreamWrapperAnonymousStep extends AdditionalTaintStep {
214+ override predicate step ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
215+ exists ( Method m , AnonymousClass wrapper |
216+ m .hasName ( "read" ) and
217+ m .getDeclaringType ( ) = wrapper and
218+ wrapper .getASourceSupertype + ( ) instanceof TypeInputStream
219+ |
220+ n1 .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = m .getParameter ( 0 ) .getAnAccess ( ) and
221+ n2 .asExpr ( ) = wrapper .getClassInstanceExpr ( )
222+ )
223+ }
224+ }
225+
226+ /**
227+ * A taint step from an `InputStream` argument of the constructor of an `InputStream` subtype
228+ * to the call of the constructor, only if the argument is assigned to a class field.
229+ *
230+ * This models how it's assumed that an `InputStream` wrapper is tainted by the wrapped stream,
231+ * and is a workaround to low `fieldFlowBranchLimit`s in dataflow configurations.
232+ */
233+ private class InputStreamWrapperConstructorStep extends AdditionalTaintStep {
234+ override predicate step ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
235+ exists ( ClassInstanceExpr cc , Argument a , AssignExpr ae |
236+ cc .getConstructedType ( ) .getASourceSupertype + ( ) instanceof TypeInputStream and
237+ cc .getAnArgument ( ) = a and
238+ cc .getCallee ( ) .getParameter ( a .getParameterPos ( ) ) .getAnAccess ( ) = ae .getRhs ( ) and
239+ ae .getDest ( ) .( FieldWrite ) .getField ( ) .getType ( ) .( RefType ) .getASourceSupertype * ( ) instanceof
240+ TypeInputStream
241+ |
242+ n1 .asExpr ( ) = a and
243+ n2 .asExpr ( ) = cc
244+ )
245+ }
246+ }
247+
200248// --- Standard methods ---
201249/**
202250 * DEPRECATED: Any constructor of class `java.lang.ProcessBuilder`.
0 commit comments