@@ -6,12 +6,6 @@ private import codeql.ruby.DataFlow
6
6
private import codeql.ruby.dataflow.FlowSummary
7
7
private import codeql.ruby.dataflow.internal.DataFlowDispatch
8
8
9
- // TODO: the way we interpret `preservesValue` in this module may not be
10
- // correct: we assume that if the input string appears intact in the output,
11
- // then value is preserves. This means that we consider appending or prepending
12
- // characters to the string to be value-preserving.
13
- // We may want to be stricter here, and define value-preserving as when the
14
- // output string exactly matches the input string.
15
9
/**
16
10
* Provides flow summaries for the `String` class.
17
11
*
@@ -79,7 +73,7 @@ module String {
79
73
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
80
74
input = [ "Receiver" , "Argument[0]" , "ArrayElement of Argument[0]" ] and
81
75
output = "ReturnValue" and
82
- preservesValue = true
76
+ preservesValue = false
83
77
}
84
78
}
85
79
@@ -110,7 +104,7 @@ module String {
110
104
override MethodCall getACall ( ) { result = mc }
111
105
112
106
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
113
- valueIdentityFlow ( input , output , preservesValue )
107
+ taintIdentityFlow ( input , output , preservesValue )
114
108
}
115
109
}
116
110
@@ -138,13 +132,10 @@ module String {
138
132
CenterSummary ( ) { this = [ "center" , "ljust" , "rjust" ] }
139
133
140
134
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
141
- (
142
- input = "Receiver" and
143
- output = "ReturnValue"
144
- or
145
- input = "Argument[1]" and
146
- output = "ReturnValue"
147
- ) and
135
+ taintIdentityFlow ( input , output , preservesValue )
136
+ or
137
+ input = "Argument[1]" and
138
+ output = "ReturnValue" and
148
139
preservesValue = false
149
140
}
150
141
}
@@ -160,13 +151,12 @@ module String {
160
151
override MethodCall getACall ( ) { result = mc }
161
152
162
153
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
154
+ taintIdentityFlow ( input , output , preservesValue )
155
+ or
156
+ this = [ "chomp!" , "chop!" ] and
163
157
input = "Receiver" and
164
158
preservesValue = false and
165
- (
166
- output = "ReturnValue"
167
- or
168
- this = [ "chomp!" , "chop!" ] and output = "Receiver"
169
- )
159
+ output = "Receiver"
170
160
}
171
161
}
172
162
@@ -185,7 +175,7 @@ module String {
185
175
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
186
176
input = [ "Receiver" , "Argument[_]" ] and
187
177
output = [ "ReturnValue" , "Receiver" ] and
188
- preservesValue = true
178
+ preservesValue = false
189
179
}
190
180
}
191
181
@@ -279,9 +269,7 @@ module String {
279
269
ForceEncodingSummary ( ) { this = "force_encoding" }
280
270
281
271
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
282
- input = "Receiver" and
283
- output = "ReturnValue" and
284
- preservesValue = false
272
+ taintIdentityFlow ( input , output , preservesValue )
285
273
}
286
274
}
287
275
@@ -309,13 +297,9 @@ module String {
309
297
// receiver -> return value
310
298
// replacement -> return value
311
299
// block return -> return value
312
- (
313
- input = [ "Receiver" , "Argument[1]" ] and
314
- preservesValue = false
315
- or
316
- input = "ReturnValue of BlockArgument" and preservesValue = true
317
- ) and
318
- output = "ReturnValue"
300
+ preservesValue = false and
301
+ output = "ReturnValue" and
302
+ input = [ "Receiver" , "Argument[1]" , "ReturnValue of BlockArgument" ]
319
303
}
320
304
}
321
305
@@ -330,12 +314,9 @@ module String {
330
314
}
331
315
332
316
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
333
- (
334
- input = "Receiver" and preservesValue = false
335
- or
336
- input = "Argument[1]" and preservesValue = true
337
- ) and
338
- output = "ReturnValue"
317
+ taintIdentityFlow ( input , output , preservesValue )
318
+ or
319
+ input = "Argument[1]" and output = "ReturnValue" and preservesValue = false
339
320
}
340
321
}
341
322
@@ -357,7 +338,7 @@ module String {
357
338
StripSummary ( ) { this = [ "strip" , "lstrip" , "rstrip" ] + [ "" , "!" ] }
358
339
359
340
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
360
- valueIdentityFlow ( input , output , preservesValue )
341
+ taintIdentityFlow ( input , output , preservesValue )
361
342
}
362
343
}
363
344
@@ -427,14 +408,14 @@ module String {
427
408
428
409
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
429
410
input = "Receiver" and
430
- (
431
- // Parameter[_] doesn't seem to work
432
- output = "Parameter[" + [ 0 .. 10 ] + "] of BlockArgument" and preservesValue = false
433
- or
434
- // scan(pattern) -> array
435
- output = "ReturnValue" and
436
- preservesValue = true
437
- )
411
+ preservesValue = false and
412
+ output =
413
+ [
414
+ // scan(pattern) -> array
415
+ "ReturnValue" ,
416
+ // Parameter[_] doesn't seem to work
417
+ "Parameter[" + [ 0 .. 10 ] + "] of BlockArgument"
418
+ ]
438
419
}
439
420
}
440
421
@@ -443,14 +424,14 @@ module String {
443
424
444
425
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
445
426
input = "Receiver" and
446
- (
447
- // scan(pattern) {|match, ...| block } -> str
448
- output = "ArrayElement[?] of ReturnValue" and
449
- preservesValue = false
450
- or
451
- // Parameter[_] doesn't seem to work
452
- output = "Parameter[" + [ 0 .. 10 ] + "] of BlockArgument" and preservesValue = false
453
- )
427
+ preservesValue = false and
428
+ output =
429
+ [
430
+ // scan(pattern) {|match, ...| block } -> str
431
+ "ArrayElement[?] of ReturnValue" ,
432
+ // Parameter[_] doesn't seem to work
433
+ "Parameter[" + [ 0 .. 10 ] + "] of BlockArgument"
434
+ ]
454
435
}
455
436
}
456
437
@@ -470,35 +451,48 @@ module String {
470
451
ScrubBlockSummary ( ) { this = "scrub_block" and exists ( mc .getBlock ( ) ) }
471
452
472
453
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
473
- input = "Receiver" and
474
- output = "Parameter[0] of BlockArgument" and
475
- preservesValue = true
476
- or
477
- input = "Argument[0]" and output = "ReturnValue" and preservesValue = true
478
- or
479
- input = "ReturnValue of BlockArgument" and
480
- output = "ReturnValue" and
481
- preservesValue = true
482
- or
483
454
taintIdentityFlow ( input , output , preservesValue )
455
+ or
456
+ preservesValue = false and
457
+ (
458
+ input = "Receiver" and
459
+ output = "Parameter[0] of BlockArgument"
460
+ or
461
+ input = "Argument[0]" and output = "ReturnValue"
462
+ or
463
+ input = "ReturnValue of BlockArgument" and
464
+ output = "ReturnValue"
465
+ )
484
466
}
485
467
}
486
468
487
469
private class ScrubNoBlockSummary extends ScrubSummary {
488
470
ScrubNoBlockSummary ( ) { this = "scrub_no_block" and not exists ( mc .getBlock ( ) ) }
489
471
490
472
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
491
- input = "Receiver" and
492
- output = "Parameter[0] of BlockArgument" and
493
- preservesValue = true
494
- or
495
- input = "Argument[0]" and output = "ReturnValue" and preservesValue = true
473
+ taintIdentityFlow ( input , output , preservesValue )
496
474
or
475
+ preservesValue = false and
476
+ (
477
+ input = "Receiver" and
478
+ output = "Parameter[0] of BlockArgument"
479
+ or
480
+ input = "Argument[0]" and output = "ReturnValue"
481
+ )
482
+ }
483
+ }
484
+
485
+ /**
486
+ * A flow summary for `String#shellescape`.
487
+ */
488
+ private class ShellescapeSummary extends SimpleSummarizedCallable {
489
+ ShellescapeSummary ( ) { this = "shellescape" }
490
+
491
+ override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
497
492
taintIdentityFlow ( input , output , preservesValue )
498
493
}
499
494
}
500
495
501
- // TODO: what do we do about `String#shellescape`?
502
496
/**
503
497
* A flow summary for `String#shellsplit`.
504
498
*/
@@ -552,7 +546,9 @@ module String {
552
546
TrSummary ( ) { this = [ "tr" , "tr_s" ] + [ "" , "!" ] }
553
547
554
548
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
555
- input = [ "Receiver" , "Argument[1]" ] and output = "ReturnValue" and preservesValue = false
549
+ taintIdentityFlow ( input , output , preservesValue )
550
+ or
551
+ input = "Argument[1]" and output = "ReturnValue" and preservesValue = false
556
552
}
557
553
}
558
554
@@ -604,7 +600,7 @@ module String {
604
600
}
605
601
606
602
override predicate propagatesFlowExt ( string input , string output , boolean preservesValue ) {
607
- input = [ "Receiver" ] and
603
+ input = "Receiver" and
608
604
output = "Parameter[0] of BlockArgument" and
609
605
preservesValue = true
610
606
or
0 commit comments