Python: Fix problem with missing use-use flow

This commit is contained in:
Rasmus Wriedt Larsen
2020-10-01 12:55:11 +02:00
parent 9b3509f0ba
commit 3247b300ae
2 changed files with 38 additions and 12 deletions

View File

@@ -27,19 +27,30 @@ class CommandInjectionConfiguration extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) {
sink = any(SystemCommandExecution e).getCommand()
sink = any(SystemCommandExecution e).getCommand() and
// Since the implementation of os.popen looks like
// ```py
// def popen(cmd, mode="r", buffering=-1):
// ...
// proc = subprocess.Popen(cmd, ...)
// ```
// any time we would report flow to the `os.popen` sink, we can ALSO report the flow
// from the `cmd` parameter to the `subprocess.Popen` sink -- obviously we don't want
// that.
//
// However, simply removing taint edges out of a sink is not a good enough solution,
// since we would only flag one of the `os.system` calls in the following example due
// to use-use flow
// ```py
// os.system(cmd)
// os.system(cmd)
// ```
//
// Best solution I could come up with is to exclude all sinks inside the standard
// library -- this does have a downside: If we have overlooked a function in the
// standard library that internally runs a command, we no longer give an alert :|
not sink.getLocation().getFile().inStdlib()
}
// Since the implementation of os.popen looks like
// ```py
// def popen(cmd, mode="r", buffering=-1):
// ...
// proc = subprocess.Popen(cmd, ...)
// ```
// any time we would report flow to the `os.popen` sink, we can ALSO report the flow
// from the `cmd` parameter to the `subprocess.Popen` sink -- obviously we don't want
// that, so to prevent that we remove any taint edges out of a sink.
override predicate isSanitizerOut(DataFlow::Node node) { isSink(node) }
}
from CommandInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink