Merge pull request #200 from github/hvitved/dataflow/call-sensitivity

Data flow: Call-sensitive resolution of lambda/block calls
This commit is contained in:
Tom Hvitved
2021-06-04 16:25:13 +02:00
committed by GitHub
8 changed files with 375 additions and 113 deletions

View File

@@ -0,0 +1,35 @@
edges
| call_sensitivity.rb:7:13:7:13 | x : | call_sensitivity.rb:8:11:8:11 | x : |
| call_sensitivity.rb:8:11:8:11 | x : | call_sensitivity.rb:15:20:15:20 | x : |
| call_sensitivity.rb:15:9:15:15 | "taint" : | call_sensitivity.rb:7:13:7:13 | x : |
| call_sensitivity.rb:15:20:15:20 | x : | call_sensitivity.rb:15:28:15:28 | x |
| call_sensitivity.rb:17:27:17:27 | x : | call_sensitivity.rb:18:17:18:17 | x : |
| call_sensitivity.rb:17:27:17:27 | x : | call_sensitivity.rb:18:17:18:17 | x : |
| call_sensitivity.rb:18:17:18:17 | x : | call_sensitivity.rb:27:17:27:17 | x : |
| call_sensitivity.rb:18:17:18:17 | x : | call_sensitivity.rb:36:23:36:23 | x : |
| call_sensitivity.rb:27:17:27:17 | x : | call_sensitivity.rb:27:27:27:27 | x |
| call_sensitivity.rb:28:25:28:31 | "taint" : | call_sensitivity.rb:17:27:17:27 | x : |
| call_sensitivity.rb:36:23:36:23 | x : | call_sensitivity.rb:36:31:36:31 | x |
| call_sensitivity.rb:37:25:37:31 | "taint" : | call_sensitivity.rb:17:27:17:27 | x : |
nodes
| call_sensitivity.rb:5:6:5:12 | "taint" | semmle.label | "taint" |
| call_sensitivity.rb:7:13:7:13 | x : | semmle.label | x : |
| call_sensitivity.rb:8:11:8:11 | x : | semmle.label | x : |
| call_sensitivity.rb:15:9:15:15 | "taint" : | semmle.label | "taint" : |
| call_sensitivity.rb:15:20:15:20 | x : | semmle.label | x : |
| call_sensitivity.rb:15:28:15:28 | x | semmle.label | x |
| call_sensitivity.rb:17:27:17:27 | x : | semmle.label | x : |
| call_sensitivity.rb:17:27:17:27 | x : | semmle.label | x : |
| call_sensitivity.rb:18:17:18:17 | x : | semmle.label | x : |
| call_sensitivity.rb:18:17:18:17 | x : | semmle.label | x : |
| call_sensitivity.rb:27:17:27:17 | x : | semmle.label | x : |
| call_sensitivity.rb:27:27:27:27 | x | semmle.label | x |
| call_sensitivity.rb:28:25:28:31 | "taint" : | semmle.label | "taint" : |
| call_sensitivity.rb:36:23:36:23 | x : | semmle.label | x : |
| call_sensitivity.rb:36:31:36:31 | x | semmle.label | x |
| call_sensitivity.rb:37:25:37:31 | "taint" : | semmle.label | "taint" : |
#select
| call_sensitivity.rb:5:6:5:12 | "taint" | call_sensitivity.rb:5:6:5:12 | "taint" | call_sensitivity.rb:5:6:5:12 | "taint" | $@ | call_sensitivity.rb:5:6:5:12 | "taint" | "taint" |
| call_sensitivity.rb:15:28:15:28 | x | call_sensitivity.rb:15:9:15:15 | "taint" : | call_sensitivity.rb:15:28:15:28 | x | $@ | call_sensitivity.rb:15:9:15:15 | "taint" : | "taint" : |
| call_sensitivity.rb:27:27:27:27 | x | call_sensitivity.rb:28:25:28:31 | "taint" : | call_sensitivity.rb:27:27:27:27 | x | $@ | call_sensitivity.rb:28:25:28:31 | "taint" : | "taint" : |
| call_sensitivity.rb:36:31:36:31 | x | call_sensitivity.rb:37:25:37:31 | "taint" : | call_sensitivity.rb:36:31:36:31 | x | $@ | call_sensitivity.rb:37:25:37:31 | "taint" : | "taint" : |

View File

@@ -0,0 +1,26 @@
/**
* @kind path-problem
*/
import ruby
import codeql_ruby.DataFlow
import DataFlow::PathGraph
class Conf extends DataFlow::Configuration {
Conf() { this = "Conf" }
override predicate isSource(DataFlow::Node src) {
src.asExpr().getExpr().(StringLiteral).getValueText() = "taint"
}
override predicate isSink(DataFlow::Node sink) {
exists(MethodCall mc |
mc.getMethodName() = "sink" and
mc.getAnArgument() = sink.asExpr().getExpr()
)
}
}
from DataFlow::PathNode source, DataFlow::PathNode sink, Conf conf
where conf.hasFlowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -0,0 +1,38 @@
def sink s
puts s
end
sink "taint"
def yielder x
yield x
end
yielder "no taint" { |x| sink x } # no flow
yielder "taint" { |x| puts x } # no flow
yielder "taint" { |x| sink x } # flow
def apply_lambda (lambda, x)
lambda.call(x)
end
my_lambda = -> (x) { sink x }
apply_lambda(my_lambda, "no taint") # no flow
my_lambda = -> (x) { puts x }
apply_lambda(my_lambda, "taint") # no flow
my_lambda = -> (x) { sink x }
apply_lambda(my_lambda, "taint") # flow
my_lambda = lambda { |x| sink x }
apply_lambda(my_lambda, "no taint") # no flow
my_lambda = lambda { |x| puts x }
apply_lambda(my_lambda, "taint") # no flow
my_lambda = lambda { |x| sink x }
apply_lambda(my_lambda, "taint") # flow