@@ -60,6 +60,17 @@ private module Cached {
60
60
localAdditionalTaintUpdateStep ( src .asExpr ( ) ,
61
61
sink .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) )
62
62
or
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
72
+ )
73
+ or
63
74
FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( src , sink , false )
64
75
}
65
76
@@ -87,6 +98,81 @@ private module Cached {
87
98
88
99
import Cached
89
100
101
+ private module StoreTaintSteps {
102
+ private import semmle.code.java.dataflow.TaintTracking
103
+ private import semmle.code.java.dataflow.TaintTracking2
104
+
105
+ private class StoreTaintConfig extends TaintTracking:: Configuration {
106
+ StoreTaintConfig ( ) { this instanceof TaintTracking:: Configuration or none ( ) }
107
+
108
+ override predicate isSource ( DataFlow:: Node n ) { none ( ) }
109
+
110
+ override predicate isSink ( DataFlow:: Node n ) { none ( ) }
111
+
112
+ private predicate needsTaintStore ( RefType container , Type elem , Content f ) {
113
+ exists ( DataFlow:: Node arg |
114
+ ( isSink ( arg ) or isAdditionalTaintStep ( arg , _) ) and
115
+ ( arg .asExpr ( ) instanceof Argument or arg instanceof ArgumentNode ) and
116
+ arg .getType ( ) = container
117
+ or
118
+ needsTaintStore ( _, container , _)
119
+ |
120
+ container .( Array ) .getComponentType ( ) = elem and
121
+ f instanceof ArrayContent
122
+ or
123
+ container .( CollectionType ) .getElementType ( ) = elem and
124
+ f instanceof CollectionContent
125
+ or
126
+ container .( MapType ) .getValueType ( ) = elem and
127
+ f instanceof MapValueContent
128
+ )
129
+ }
130
+
131
+ override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
132
+ exists ( Content f , Type elem |
133
+ storeStep ( node1 , f , node2 ) and
134
+ needsTaintStore ( _, elem , f ) and
135
+ not exists ( Type srctyp | srctyp = node1 .getTypeBound ( ) | not compatibleTypes ( srctyp , elem ) )
136
+ )
137
+ }
138
+ }
139
+
140
+ private class StoreTaintConfig2 extends TaintTracking2:: Configuration {
141
+ StoreTaintConfig2 ( ) { this instanceof TaintTracking2:: Configuration or none ( ) }
142
+
143
+ override predicate isSource ( DataFlow:: Node n ) { none ( ) }
144
+
145
+ override predicate isSink ( DataFlow:: Node n ) { none ( ) }
146
+
147
+ private predicate needsTaintStore ( RefType container , Type elem , Content f ) {
148
+ exists ( DataFlow:: Node arg |
149
+ ( isSink ( arg ) or isAdditionalTaintStep ( arg , _) ) and
150
+ ( arg .asExpr ( ) instanceof Argument or arg instanceof ArgumentNode ) and
151
+ arg .getType ( ) = container
152
+ or
153
+ needsTaintStore ( _, container , _)
154
+ |
155
+ container .( Array ) .getComponentType ( ) = elem and
156
+ f instanceof ArrayContent
157
+ or
158
+ container .( CollectionType ) .getElementType ( ) = elem and
159
+ f instanceof CollectionContent
160
+ or
161
+ container .( MapType ) .getValueType ( ) = elem and
162
+ f instanceof MapValueContent
163
+ )
164
+ }
165
+
166
+ override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
167
+ exists ( Content f , Type elem |
168
+ storeStep ( node1 , f , node2 ) and
169
+ needsTaintStore ( _, elem , f ) and
170
+ not exists ( Type srctyp | srctyp = node1 .getTypeBound ( ) | not compatibleTypes ( srctyp , elem ) )
171
+ )
172
+ }
173
+ }
174
+ }
175
+
90
176
/**
91
177
* Holds if taint can flow in one local step from `src` to `sink` excluding
92
178
* local data flow steps. That is, `src` and `sink` are likely to represent
0 commit comments