@@ -60,10 +60,15 @@ private module Cached {
6060 localAdditionalTaintUpdateStep ( src .asExpr ( ) ,
6161 sink .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) )
6262 or
63- exists ( Argument arg |
64- src .asExpr ( ) = arg and
65- arg .isVararg ( ) and
66- sink .( DataFlow:: ImplicitVarargsArray ) .getCall ( ) = arg .getCall ( )
63+ exists ( Content f |
64+ readStep ( src , f , sink ) and
65+ not sink .getTypeBound ( ) instanceof PrimitiveType and
66+ not sink .getTypeBound ( ) instanceof BoxedType and
67+ not sink .getTypeBound ( ) instanceof NumberType
68+ |
69+ f instanceof ArrayContent or
70+ f instanceof CollectionContent or
71+ f instanceof MapValueContent
6772 )
6873 or
6974 FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( src , sink , false )
@@ -93,6 +98,92 @@ private module Cached {
9398
9499import Cached
95100
101+ /**
102+ * These configurations add a number of configuration-dependent additional taint
103+ * steps to all taint configurations. For each sink or additional step provided
104+ * by a given configuration the types are inspected to find those implicit
105+ * collection or array read steps that might be required at the sink or step
106+ * input. The corresponding store steps are then added as additional taint steps
107+ * to provide backwards-compatible taint flow to such sinks and steps.
108+ *
109+ * This is a temporary measure until support is added for such sinks that
110+ * require implicit read steps.
111+ */
112+ private module StoreTaintSteps {
113+ private import semmle.code.java.dataflow.TaintTracking
114+ private import semmle.code.java.dataflow.TaintTracking2
115+
116+ private class StoreTaintConfig extends TaintTracking:: Configuration {
117+ StoreTaintConfig ( ) { this instanceof TaintTracking:: Configuration or none ( ) }
118+
119+ override predicate isSource ( DataFlow:: Node n ) { none ( ) }
120+
121+ override predicate isSink ( DataFlow:: Node n ) { none ( ) }
122+
123+ private predicate needsTaintStore ( RefType container , Type elem , Content f ) {
124+ exists ( DataFlow:: Node arg |
125+ ( isSink ( arg ) or isAdditionalTaintStep ( arg , _) ) and
126+ ( arg .asExpr ( ) instanceof Argument or arg instanceof ArgumentNode ) and
127+ arg .getType ( ) = container
128+ or
129+ needsTaintStore ( _, container , _)
130+ |
131+ container .( Array ) .getComponentType ( ) = elem and
132+ f instanceof ArrayContent
133+ or
134+ container .( CollectionType ) .getElementType ( ) = elem and
135+ f instanceof CollectionContent
136+ or
137+ container .( MapType ) .getValueType ( ) = elem and
138+ f instanceof MapValueContent
139+ )
140+ }
141+
142+ override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
143+ exists ( Content f , Type elem |
144+ storeStep ( node1 , f , node2 ) and
145+ needsTaintStore ( _, elem , f ) and
146+ not exists ( Type srctyp | srctyp = node1 .getTypeBound ( ) | not compatibleTypes ( srctyp , elem ) )
147+ )
148+ }
149+ }
150+
151+ private class StoreTaintConfig2 extends TaintTracking2:: Configuration {
152+ StoreTaintConfig2 ( ) { this instanceof TaintTracking2:: Configuration or none ( ) }
153+
154+ override predicate isSource ( DataFlow:: Node n ) { none ( ) }
155+
156+ override predicate isSink ( DataFlow:: Node n ) { none ( ) }
157+
158+ private predicate needsTaintStore ( RefType container , Type elem , Content f ) {
159+ exists ( DataFlow:: Node arg |
160+ ( isSink ( arg ) or isAdditionalTaintStep ( arg , _) ) and
161+ ( arg .asExpr ( ) instanceof Argument or arg instanceof ArgumentNode ) and
162+ arg .getType ( ) = container
163+ or
164+ needsTaintStore ( _, container , _)
165+ |
166+ container .( Array ) .getComponentType ( ) = elem and
167+ f instanceof ArrayContent
168+ or
169+ container .( CollectionType ) .getElementType ( ) = elem and
170+ f instanceof CollectionContent
171+ or
172+ container .( MapType ) .getValueType ( ) = elem and
173+ f instanceof MapValueContent
174+ )
175+ }
176+
177+ override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
178+ exists ( Content f , Type elem |
179+ storeStep ( node1 , f , node2 ) and
180+ needsTaintStore ( _, elem , f ) and
181+ not exists ( Type srctyp | srctyp = node1 .getTypeBound ( ) | not compatibleTypes ( srctyp , elem ) )
182+ )
183+ }
184+ }
185+ }
186+
96187/**
97188 * Holds if taint can flow in one local step from `src` to `sink` excluding
98189 * local data flow steps. That is, `src` and `sink` are likely to represent
@@ -103,22 +194,8 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) {
103194 or
104195 sink .( AssignAddExpr ) .getSource ( ) = src and sink .getType ( ) instanceof TypeString
105196 or
106- sink .( ArrayCreationExpr ) .getInit ( ) = src
107- or
108- sink .( ArrayInit ) .getAnInit ( ) = src
109- or
110- sink .( ArrayAccess ) .getArray ( ) = src
111- or
112197 sink .( LogicExpr ) .getAnOperand ( ) = src
113198 or
114- exists ( EnhancedForStmt for , SsaExplicitUpdate v |
115- for .getExpr ( ) = src and
116- v .getDefiningExpr ( ) = for .getVariable ( ) and
117- v .getAFirstUse ( ) = sink
118- )
119- or
120- containerReturnValueStep ( src , sink )
121- or
122199 constructorStep ( src , sink )
123200 or
124201 qualifierToMethodStep ( src , sink )
@@ -141,12 +218,6 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) {
141218 * This is restricted to cases where the step updates the value of `sink`.
142219 */
143220private predicate localAdditionalTaintUpdateStep ( Expr src , Expr sink ) {
144- exists ( Assignment assign | assign .getSource ( ) = src |
145- sink = assign .getDest ( ) .( ArrayAccess ) .getArray ( )
146- )
147- or
148- containerUpdateStep ( src , sink )
149- or
150221 qualifierToArgumentStep ( src , sink )
151222 or
152223 argToArgStep ( src , sink )
0 commit comments