69
69
* sources "remote" indicates a default remote flow source, and for summaries
70
70
* "taint" indicates a default additional taint step and "value" indicates a
71
71
* globally applicable value-preserving step.
72
+ * 9. The `provenance` column is a tag to indicate the origin of the summary.
73
+ * There are two supported values: "generated" and "manual". "generated" means that
74
+ * the model has been emitted by the model generator tool and "manual" means
75
+ * that the model has been written by hand. This information is used in a heuristic
76
+ * for dataflow analysis to determine, if a model or source code should be used for
77
+ * determining flow.
72
78
*/
73
79
74
80
import csharp
@@ -163,17 +169,10 @@ private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
163
169
164
170
private predicate summaryModel ( string row ) { any ( SummaryModelCsv s ) .row ( row ) }
165
171
166
- bindingset [ input]
167
- private predicate getKind ( string input , string kind , boolean generated ) {
168
- input .splitAt ( ":" , 0 ) = "generated" and kind = input .splitAt ( ":" , 1 ) and generated = true
169
- or
170
- not input .matches ( "%:%" ) and kind = input and generated = false
171
- }
172
-
173
172
/** Holds if a source model exists for the given parameters. */
174
173
predicate sourceModel (
175
174
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
176
- string output , string kind , boolean generated
175
+ string output , string kind , string provenance
177
176
) {
178
177
exists ( string row |
179
178
sourceModel ( row ) and
@@ -185,14 +184,15 @@ predicate sourceModel(
185
184
row .splitAt ( ";" , 4 ) = signature and
186
185
row .splitAt ( ";" , 5 ) = ext and
187
186
row .splitAt ( ";" , 6 ) = output and
188
- exists ( string k | row .splitAt ( ";" , 7 ) = k and getKind ( k , kind , generated ) )
187
+ row .splitAt ( ";" , 7 ) = kind and
188
+ row .splitAt ( ";" , 8 ) = provenance
189
189
)
190
190
}
191
191
192
192
/** Holds if a sink model exists for the given parameters. */
193
193
predicate sinkModel (
194
194
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
195
- string input , string kind , boolean generated
195
+ string input , string kind , string provenance
196
196
) {
197
197
exists ( string row |
198
198
sinkModel ( row ) and
@@ -204,14 +204,15 @@ predicate sinkModel(
204
204
row .splitAt ( ";" , 4 ) = signature and
205
205
row .splitAt ( ";" , 5 ) = ext and
206
206
row .splitAt ( ";" , 6 ) = input and
207
- exists ( string k | row .splitAt ( ";" , 7 ) = k and getKind ( k , kind , generated ) )
207
+ row .splitAt ( ";" , 7 ) = kind and
208
+ row .splitAt ( ";" , 8 ) = provenance
208
209
)
209
210
}
210
211
211
212
/** Holds if a summary model exists for the given parameters. */
212
213
predicate summaryModel (
213
214
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
214
- string input , string output , string kind , boolean generated
215
+ string input , string output , string kind , string provenance
215
216
) {
216
217
exists ( string row |
217
218
summaryModel ( row ) and
@@ -224,7 +225,8 @@ predicate summaryModel(
224
225
row .splitAt ( ";" , 5 ) = ext and
225
226
row .splitAt ( ";" , 6 ) = input and
226
227
row .splitAt ( ";" , 7 ) = output and
227
- exists ( string k | row .splitAt ( ";" , 8 ) = k and getKind ( k , kind , generated ) )
228
+ row .splitAt ( ";" , 8 ) = kind and
229
+ row .splitAt ( ";" , 9 ) = provenance
228
230
)
229
231
}
230
232
@@ -259,25 +261,25 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
259
261
part = "source" and
260
262
n =
261
263
strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
262
- string ext , string output , boolean generated |
264
+ string ext , string output , string provenance |
263
265
canonicalNamespaceLink ( namespace , subns ) and
264
- sourceModel ( subns , type , subtypes , name , signature , ext , output , kind , generated )
266
+ sourceModel ( subns , type , subtypes , name , signature , ext , output , kind , provenance )
265
267
)
266
268
or
267
269
part = "sink" and
268
270
n =
269
271
strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
270
- string ext , string input , boolean generated |
272
+ string ext , string input , string provenance |
271
273
canonicalNamespaceLink ( namespace , subns ) and
272
- sinkModel ( subns , type , subtypes , name , signature , ext , input , kind , generated )
274
+ sinkModel ( subns , type , subtypes , name , signature , ext , input , kind , provenance )
273
275
)
274
276
or
275
277
part = "summary" and
276
278
n =
277
279
strictcount ( string subns , string type , boolean subtypes , string name , string signature ,
278
- string ext , string input , string output , boolean generated |
280
+ string ext , string input , string output , string provenance |
279
281
canonicalNamespaceLink ( namespace , subns ) and
280
- summaryModel ( subns , type , subtypes , name , signature , ext , input , output , kind , generated )
282
+ summaryModel ( subns , type , subtypes , name , signature , ext , input , output , kind , provenance )
281
283
)
282
284
)
283
285
}
@@ -286,12 +288,16 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
286
288
module CsvValidation {
287
289
/** Holds if some row in a CSV-based flow model appears to contain typos. */
288
290
query predicate invalidModelRow ( string msg ) {
289
- exists ( string pred , string namespace , string type , string name , string signature , string ext |
290
- sourceModel ( namespace , type , _, name , signature , ext , _, _, _) and pred = "source"
291
+ exists (
292
+ string pred , string namespace , string type , string name , string signature , string ext ,
293
+ string provenance
294
+ |
295
+ sourceModel ( namespace , type , _, name , signature , ext , _, _, provenance ) and pred = "source"
291
296
or
292
- sinkModel ( namespace , type , _, name , signature , ext , _, _, _ ) and pred = "sink"
297
+ sinkModel ( namespace , type , _, name , signature , ext , _, _, provenance ) and pred = "sink"
293
298
or
294
- summaryModel ( namespace , type , _, name , signature , ext , _, _, _, _) and pred = "summary"
299
+ summaryModel ( namespace , type , _, name , signature , ext , _, _, _, provenance ) and
300
+ pred = "summary"
295
301
|
296
302
not namespace .regexpMatch ( "[a-zA-Z0-9_\\.]+" ) and
297
303
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
@@ -307,6 +313,9 @@ module CsvValidation {
307
313
or
308
314
not ext .regexpMatch ( "|Attribute" ) and
309
315
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
316
+ or
317
+ not provenance = [ "manual" , "generated" ] and
318
+ msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
310
319
)
311
320
or
312
321
exists ( string pred , AccessPath input , string part |
@@ -338,18 +347,18 @@ module CsvValidation {
338
347
)
339
348
or
340
349
exists ( string pred , string row , int expect |
341
- sourceModel ( row ) and expect = 8 and pred = "source"
350
+ sourceModel ( row ) and expect = 9 and pred = "source"
342
351
or
343
- sinkModel ( row ) and expect = 8 and pred = "sink"
352
+ sinkModel ( row ) and expect = 9 and pred = "sink"
344
353
or
345
- summaryModel ( row ) and expect = 9 and pred = "summary"
354
+ summaryModel ( row ) and expect = 10 and pred = "summary"
346
355
|
347
356
exists ( int cols |
348
357
cols = 1 + max ( int n | exists ( row .splitAt ( ";" , n ) ) ) and
349
358
cols != expect and
350
359
msg =
351
360
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
352
- "."
361
+ " in " + row + " ."
353
362
)
354
363
or
355
364
exists ( string b |
@@ -359,23 +368,20 @@ module CsvValidation {
359
368
)
360
369
)
361
370
or
362
- exists ( string row , string k , string kind | summaryModel ( row ) |
363
- k = row .splitAt ( ";" , 8 ) and
364
- getKind ( k , kind , _) and
371
+ exists ( string row , string kind | summaryModel ( row ) |
372
+ kind = row .splitAt ( ";" , 8 ) and
365
373
not kind = [ "taint" , "value" ] and
366
374
msg = "Invalid kind \"" + kind + "\" in summary model."
367
375
)
368
376
or
369
- exists ( string row , string k , string kind | sinkModel ( row ) |
370
- k = row .splitAt ( ";" , 7 ) and
371
- getKind ( k , kind , _) and
377
+ exists ( string row , string kind | sinkModel ( row ) |
378
+ kind = row .splitAt ( ";" , 7 ) and
372
379
not kind = [ "code" , "sql" , "xss" , "remote" , "html" ] and
373
380
msg = "Invalid kind \"" + kind + "\" in sink model."
374
381
)
375
382
or
376
- exists ( string row , string k , string kind | sourceModel ( row ) |
377
- k = row .splitAt ( ";" , 7 ) and
378
- getKind ( k , kind , _) and
383
+ exists ( string row , string kind | sourceModel ( row ) |
384
+ kind = row .splitAt ( ";" , 7 ) and
379
385
not kind = "local" and
380
386
msg = "Invalid kind \"" + kind + "\" in source model."
381
387
)
0 commit comments