Python: Move experimental paramiko to new dataflow API

This commit is contained in:
Rasmus Wriedt Larsen
2023-08-25 17:23:51 +02:00
parent acd0f2a8fb
commit bfcc194b85
2 changed files with 14 additions and 10 deletions

View File

@@ -16,16 +16,13 @@ import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.RemoteFlowSources
import semmle.python.ApiGraphs
import DataFlow::PathGraph
private API::Node paramikoClient() {
result = API::moduleImport("paramiko").getMember("SSHClient").getReturn()
}
class ParamikoCmdInjectionConfiguration extends TaintTracking::Configuration {
ParamikoCmdInjectionConfiguration() { this = "ParamikoCMDInjectionConfiguration" }
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
private module ParamikoConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
/**
* exec_command of `paramiko.SSHClient` class execute command on ssh target server
@@ -33,7 +30,7 @@ class ParamikoCmdInjectionConfiguration extends TaintTracking::Configuration {
* and it run CMD on current system that running the ssh command
* the Sink related to proxy command is the `connect` method of `paramiko.SSHClient` class
*/
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink = paramikoClient().getMember("exec_command").getACall().getParameter(0, "command").asSink()
or
sink = paramikoClient().getMember("connect").getACall().getParameter(11, "sock").asSink()
@@ -42,7 +39,7 @@ class ParamikoCmdInjectionConfiguration extends TaintTracking::Configuration {
/**
* this additional taint step help taint tracking to find the vulnerable `connect` method of `paramiko.SSHClient` class
*/
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
predicate isAdditionalFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
exists(API::CallNode call |
call = API::moduleImport("paramiko").getMember("ProxyCommand").getACall() and
nodeFrom = call.getParameter(0, "command_line").asSink() and
@@ -51,7 +48,12 @@ class ParamikoCmdInjectionConfiguration extends TaintTracking::Configuration {
}
}
from ParamikoCmdInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
/** Global taint-tracking for detecting "paramiko command injection" vulnerabilities. */
module ParamikoFlow = TaintTracking::Global<ParamikoConfig>;
import ParamikoFlow::PathGraph
from ParamikoFlow::PathNode source, ParamikoFlow::PathNode sink
where ParamikoFlow::flowPath(source, sink)
select sink.getNode(), source, sink, "This code execution depends on a $@.", source.getNode(),
"a user-provided value"

View File

@@ -1,7 +1,8 @@
edges
| paramiko.py:15:21:15:23 | ControlFlowNode for cmd | paramiko.py:16:62:16:64 | ControlFlowNode for cmd |
| paramiko.py:20:21:20:23 | ControlFlowNode for cmd | paramiko.py:21:70:21:72 | ControlFlowNode for cmd |
| paramiko.py:25:21:25:23 | ControlFlowNode for cmd | paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() |
| paramiko.py:25:21:25:23 | ControlFlowNode for cmd | paramiko.py:26:136:26:138 | ControlFlowNode for cmd |
| paramiko.py:26:136:26:138 | ControlFlowNode for cmd | paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() |
nodes
| paramiko.py:15:21:15:23 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
| paramiko.py:16:62:16:64 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
@@ -9,6 +10,7 @@ nodes
| paramiko.py:21:70:21:72 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
| paramiko.py:25:21:25:23 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
| paramiko.py:26:114:26:139 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
| paramiko.py:26:136:26:138 | ControlFlowNode for cmd | semmle.label | ControlFlowNode for cmd |
subpaths
#select
| paramiko.py:16:62:16:64 | ControlFlowNode for cmd | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | paramiko.py:16:62:16:64 | ControlFlowNode for cmd | This code execution depends on a $@. | paramiko.py:15:21:15:23 | ControlFlowNode for cmd | a user-provided value |