@@ -25,7 +25,20 @@ predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
25
25
t .hasName ( [ "byte" , "char" , "Byte" , "Character" ] )
26
26
}
27
27
28
- module ModelGeneratorInput implements ModelGeneratorInputSig< Location , JavaDataFlow > {
28
+ private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
29
+ cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
30
+ cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
31
+ }
32
+
33
+ private predicate relevant ( Callable api ) {
34
+ api .isPublic ( ) and
35
+ api .getDeclaringType ( ) .isPublic ( ) and
36
+ api .fromSource ( ) and
37
+ not isUninterestingForModels ( api ) and
38
+ not isInfrequentlyUsed ( api .getCompilationUnit ( ) )
39
+ }
40
+
41
+ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig< Location , JavaDataFlow > {
29
42
class Type = J:: Type ;
30
43
31
44
class Parameter = J:: Parameter ;
@@ -34,96 +47,8 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
34
47
35
48
class NodeExtended = DataFlow:: Node ;
36
49
37
- Callable getAsExprEnclosingCallable ( NodeExtended node ) {
38
- result = node .asExpr ( ) .getEnclosingCallable ( )
39
- }
40
-
41
50
Callable getEnclosingCallable ( NodeExtended node ) { result = node .getEnclosingCallable ( ) }
42
51
43
- Parameter asParameter ( NodeExtended node ) { result = node .asParameter ( ) }
44
-
45
- private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
46
- cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
47
- cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
48
- }
49
-
50
- private predicate relevant ( Callable api ) {
51
- api .isPublic ( ) and
52
- api .getDeclaringType ( ) .isPublic ( ) and
53
- api .fromSource ( ) and
54
- not isUninterestingForModels ( api ) and
55
- not isInfrequentlyUsed ( api .getCompilationUnit ( ) )
56
- }
57
-
58
- private J:: Method getARelevantOverride ( J:: Method m ) {
59
- result = m .getAnOverride ( ) and
60
- relevant ( result ) and
61
- // Other exclusions for overrides.
62
- not m instanceof J:: ToStringMethod
63
- }
64
-
65
- /**
66
- * Gets the super implementation of `m` if it is relevant.
67
- * If such a super implementations does not exist, returns `m` if it is relevant.
68
- */
69
- private J:: Callable liftedImpl ( J:: Callable m ) {
70
- (
71
- result = getARelevantOverride ( m )
72
- or
73
- result = m and relevant ( m )
74
- ) and
75
- not exists ( getARelevantOverride ( result ) )
76
- }
77
-
78
- private predicate hasManualSummaryModel ( Callable api ) {
79
- api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) or
80
- api = any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
81
- }
82
-
83
- private predicate hasManualSourceModel ( Callable api ) {
84
- api = any ( ExternalFlow:: SourceCallable sc | sc .hasManualModel ( ) ) or
85
- api = any ( FlowSummaryImpl:: Public:: NeutralSourceCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
86
- }
87
-
88
- private predicate hasManualSinkModel ( Callable api ) {
89
- api = any ( ExternalFlow:: SinkCallable sc | sc .hasManualModel ( ) ) or
90
- api = any ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
91
- }
92
-
93
- predicate isUninterestingForDataFlowModels ( Callable api ) {
94
- api .getDeclaringType ( ) instanceof J:: Interface and not exists ( api .getBody ( ) )
95
- }
96
-
97
- predicate isUninterestingForHeuristicDataFlowModels ( Callable api ) { none ( ) }
98
-
99
- class SourceOrSinkTargetApi extends Callable {
100
- SourceOrSinkTargetApi ( ) { relevant ( this ) }
101
- }
102
-
103
- class SinkTargetApi extends SourceOrSinkTargetApi {
104
- SinkTargetApi ( ) { not hasManualSinkModel ( this ) }
105
- }
106
-
107
- class SourceTargetApi extends SourceOrSinkTargetApi {
108
- SourceTargetApi ( ) { not hasManualSourceModel ( this ) }
109
- }
110
-
111
- class SummaryTargetApi extends Callable {
112
- private Callable lift ;
113
-
114
- SummaryTargetApi ( ) {
115
- lift = liftedImpl ( this ) and
116
- not hasManualSummaryModel ( lift )
117
- }
118
-
119
- Callable lift ( ) { result = lift }
120
-
121
- predicate isRelevant ( ) {
122
- relevant ( this ) and
123
- not hasManualSummaryModel ( this )
124
- }
125
- }
126
-
127
52
private string isExtensible ( Callable c ) {
128
53
if c .getDeclaringType ( ) .isFinal ( ) then result = "false" else result = "true"
129
54
}
@@ -204,49 +129,89 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
204
129
node .asExpr ( ) .( J:: ThisAccess ) .isOwnInstanceAccess ( )
205
130
}
206
131
207
- predicate sinkModelSanitizer ( DataFlow:: Node node ) {
208
- // exclude variable capture jump steps
209
- exists ( Ssa:: SsaImplicitInit closure |
210
- closure .captures ( _) and
211
- node .asExpr ( ) = closure .getAFirstUse ( )
212
- )
132
+ predicate containerContent = DataFlowPrivate:: containerContent / 1 ;
133
+
134
+ string partialModelRow ( Callable api , int i ) {
135
+ i = 0 and qualifiedName ( api , result , _) // package
136
+ or
137
+ i = 1 and qualifiedName ( api , _, result ) // type
138
+ or
139
+ i = 2 and result = isExtensible ( api ) // extensible
140
+ or
141
+ i = 3 and result = api .getName ( ) // name
142
+ or
143
+ i = 4 and result = ExternalFlow:: paramsString ( api ) // parameters
144
+ or
145
+ i = 5 and result = "" and exists ( api ) // ext
213
146
}
214
147
215
- predicate apiSource ( DataFlow:: Node source ) {
148
+ string partialNeutralModelRow ( Callable api , int i ) {
149
+ i = 0 and qualifiedName ( api , result , _) // package
150
+ or
151
+ i = 1 and qualifiedName ( api , _, result ) // type
152
+ or
153
+ i = 2 and result = api .getName ( ) // name
154
+ or
155
+ i = 3 and result = ExternalFlow:: paramsString ( api ) // parameters
156
+ }
157
+ }
158
+
159
+ private import ModelGeneratorCommonInput
160
+ private import MakeModelGeneratorFactory< Location , JavaDataFlow , JavaTaintTracking , ModelGeneratorCommonInput >
161
+
162
+ module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
163
+ Callable getAsExprEnclosingCallable ( NodeExtended node ) {
164
+ result = node .asExpr ( ) .getEnclosingCallable ( )
165
+ }
166
+
167
+ Parameter asParameter ( NodeExtended node ) { result = node .asParameter ( ) }
168
+
169
+ private J:: Method getARelevantOverride ( J:: Method m ) {
170
+ result = m .getAnOverride ( ) and
171
+ relevant ( result ) and
172
+ // Other exclusions for overrides.
173
+ not m instanceof J:: ToStringMethod
174
+ }
175
+
176
+ /**
177
+ * Gets the super implementation of `m` if it is relevant.
178
+ * If such a super implementations does not exist, returns `m` if it is relevant.
179
+ */
180
+ private J:: Callable liftedImpl ( J:: Callable m ) {
216
181
(
217
- source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
218
- source instanceof DataFlow:: ParameterNode
182
+ result = getARelevantOverride ( m )
183
+ or
184
+ result = m and relevant ( m )
219
185
) and
220
- exists ( J:: RefType t |
221
- t = source .getEnclosingCallable ( ) .getDeclaringType ( ) .getAnAncestor ( ) and
222
- not t instanceof J:: TypeObject and
223
- t .isPublic ( )
224
- )
186
+ not exists ( getARelevantOverride ( result ) )
225
187
}
226
188
227
- predicate irrelevantSourceSinkApi ( Callable source , SourceTargetApi api ) { none ( ) }
228
-
229
- string getInputArgument ( DataFlow:: Node source ) {
230
- exists ( int pos |
231
- source .( DataFlow:: ParameterNode ) .isParameterOf ( _, pos ) and
232
- if pos >= 0 then result = "Argument[" + pos + "]" else result = qualifierString ( )
233
- )
234
- or
235
- source .asExpr ( ) instanceof J:: FieldAccess and
236
- result = qualifierString ( )
189
+ private predicate hasManualSummaryModel ( Callable api ) {
190
+ api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) or
191
+ api = any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
237
192
}
238
193
239
- bindingset [ kind]
240
- predicate isRelevantSinkKind ( string kind ) {
241
- not kind = "log-injection" and
242
- not kind .matches ( "regex-use%" ) and
243
- not kind = "file-content-store"
194
+ class SummaryTargetApi extends Callable {
195
+ private Callable lift ;
196
+
197
+ SummaryTargetApi ( ) {
198
+ lift = liftedImpl ( this ) and
199
+ not hasManualSummaryModel ( lift )
200
+ }
201
+
202
+ Callable lift ( ) { result = lift }
203
+
204
+ predicate isRelevant ( ) {
205
+ relevant ( this ) and
206
+ not hasManualSummaryModel ( this )
207
+ }
244
208
}
245
209
246
- bindingset [ kind]
247
- predicate isRelevantSourceKind ( string kind ) { any ( ) }
210
+ predicate isUninterestingForDataFlowModels ( Callable api ) {
211
+ api .getDeclaringType ( ) instanceof J:: Interface and not exists ( api .getBody ( ) )
212
+ }
248
213
249
- predicate containerContent = DataFlowPrivate :: containerContent / 1 ;
214
+ predicate isUninterestingForHeuristicDataFlowModels ( Callable api ) { none ( ) }
250
215
251
216
predicate isAdditionalContentFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
252
217
TaintTracking:: defaultAdditionalTaintStep ( node1 , node2 , _) and
@@ -287,34 +252,76 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
287
252
or
288
253
c instanceof DataFlowUtil:: MapKeyContent and result = "MapKey"
289
254
}
255
+ }
290
256
291
- string partialModelRow ( Callable api , int i ) {
292
- i = 0 and qualifiedName ( api , result , _) // package
293
- or
294
- i = 1 and qualifiedName ( api , _, result ) // type
295
- or
296
- i = 2 and result = isExtensible ( api ) // extensible
297
- or
298
- i = 3 and result = api .getName ( ) // name
299
- or
300
- i = 4 and result = ExternalFlow:: paramsString ( api ) // parameters
301
- or
302
- i = 5 and result = "" and exists ( api ) // ext
257
+ private module SourceModelGeneratorInput implements SourceModelGeneratorInputSig {
258
+ private predicate hasManualSourceModel ( Callable api ) {
259
+ api = any ( ExternalFlow:: SourceCallable sc | sc .hasManualModel ( ) ) or
260
+ api = any ( FlowSummaryImpl:: Public:: NeutralSourceCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
303
261
}
304
262
305
- string partialNeutralModelRow ( Callable api , int i ) {
306
- i = 0 and qualifiedName ( api , result , _) // package
307
- or
308
- i = 1 and qualifiedName ( api , _, result ) // type
309
- or
310
- i = 2 and result = api .getName ( ) // name
311
- or
312
- i = 3 and result = ExternalFlow:: paramsString ( api ) // parameters
263
+ class SourceTargetApi extends Callable {
264
+ SourceTargetApi ( ) { relevant ( this ) and not hasManualSourceModel ( this ) }
313
265
}
314
266
267
+ predicate irrelevantSourceSinkApi ( Callable source , SourceTargetApi api ) { none ( ) }
268
+
269
+ bindingset [ kind]
270
+ predicate isRelevantSourceKind ( string kind ) { any ( ) }
271
+
315
272
predicate sourceNode = ExternalFlow:: sourceNode / 2 ;
273
+ }
274
+
275
+ private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
276
+ private predicate hasManualSinkModel ( Callable api ) {
277
+ api = any ( ExternalFlow:: SinkCallable sc | sc .hasManualModel ( ) ) or
278
+ api = any ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
279
+ }
280
+
281
+ class SinkTargetApi extends Callable {
282
+ SinkTargetApi ( ) { relevant ( this ) and not hasManualSinkModel ( this ) }
283
+ }
284
+
285
+ predicate sinkModelSanitizer ( DataFlow:: Node node ) {
286
+ // exclude variable capture jump steps
287
+ exists ( Ssa:: SsaImplicitInit closure |
288
+ closure .captures ( _) and
289
+ node .asExpr ( ) = closure .getAFirstUse ( )
290
+ )
291
+ }
292
+
293
+ predicate apiSource ( DataFlow:: Node source ) {
294
+ (
295
+ source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
296
+ source instanceof DataFlow:: ParameterNode
297
+ ) and
298
+ exists ( J:: RefType t |
299
+ t = source .getEnclosingCallable ( ) .getDeclaringType ( ) .getAnAncestor ( ) and
300
+ not t instanceof J:: TypeObject and
301
+ t .isPublic ( )
302
+ )
303
+ }
304
+
305
+ string getInputArgument ( DataFlow:: Node source ) {
306
+ exists ( int pos |
307
+ source .( DataFlow:: ParameterNode ) .isParameterOf ( _, pos ) and
308
+ if pos >= 0 then result = "Argument[" + pos + "]" else result = qualifierString ( )
309
+ )
310
+ or
311
+ source .asExpr ( ) instanceof J:: FieldAccess and
312
+ result = qualifierString ( )
313
+ }
314
+
315
+ bindingset [ kind]
316
+ predicate isRelevantSinkKind ( string kind ) {
317
+ not kind = "log-injection" and
318
+ not kind .matches ( "regex-use%" ) and
319
+ not kind = "file-content-store"
320
+ }
316
321
317
322
predicate sinkNode = ExternalFlow:: sinkNode / 2 ;
318
323
}
319
324
320
- import MakeModelGenerator< Location , JavaDataFlow , JavaTaintTracking , ModelGeneratorInput >
325
+ import MakeSummaryModelGenerator< SummaryModelGeneratorInput > as SummaryModels
326
+ import MakeSourceModelGenerator< SourceModelGeneratorInput > as SourceModels
327
+ import MakeSinkModelGenerator< SinkModelGeneratorInput > as SinkModels
0 commit comments