Skip to content

Commit a541fdf

Browse files
committed
v1.2 code quality improvements including commnets too
1 parent 1bf159e commit a541fdf

File tree

1 file changed

+16
-31
lines changed
  • python/ql/src/experimental/Security/CWE-074/paramiko

1 file changed

+16
-31
lines changed

python/ql/src/experimental/Security/CWE-074/paramiko/paramiko.ql

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,49 +18,34 @@ import semmle.python.dataflow.new.RemoteFlowSources
1818
import semmle.python.ApiGraphs
1919
import DataFlow::PathGraph
2020

21+
private API::Node paramikoClient() {
22+
result = API::moduleImport("paramiko").getMember("SSHClient").getReturn()
23+
}
24+
2125
class ParamikoCMDInjectionConfiguration extends TaintTracking::Configuration {
2226
ParamikoCMDInjectionConfiguration() { this = "ParamikoCMDInjectionConfiguration" }
2327

2428
override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
2529

30+
/**
31+
* exec_command of `paramiko.SSHClient` class execute command on ssh target server
32+
* the `paramiko.ProxyCommand` is equivalent of `ssh -o ProxyCommand="CMD"`
33+
* and it run CMD on current system that running the ssh command
34+
* the Sink related to proxy command is the `connect` method of `paramiko.SSHClient` class
35+
*/
2636
override predicate isSink(DataFlow::Node sink) {
27-
sink =
28-
[
29-
API::moduleImport("paramiko")
30-
.getMember("SSHClient")
31-
.getReturn()
32-
.getMember("exec_command")
33-
.getACall()
34-
.getArgByName("command"),
35-
API::moduleImport("paramiko")
36-
.getMember("SSHClient")
37-
.getReturn()
38-
.getMember("exec_command")
39-
.getACall()
40-
.getArg(0)
41-
]
37+
sink = paramikoClient().getMember("exec_command").getACall().getParameter(0, "command").asSink()
4238
or
43-
sink =
44-
[
45-
API::moduleImport("paramiko")
46-
.getMember("SSHClient")
47-
.getReturn()
48-
.getMember("connect")
49-
.getACall()
50-
.getArgByName("sock"),
51-
API::moduleImport("paramiko")
52-
.getMember("SSHClient")
53-
.getReturn()
54-
.getMember("connect")
55-
.getACall()
56-
.getArg(11)
57-
]
39+
sink = paramikoClient().getMember("connect").getACall().getParameter(11, "sock").asSink()
5840
}
5941

42+
/**
43+
* this additional taint step help taint tracking to find the vulnerable `connect` method of `paramiko.SSHClient` class
44+
*/
6045
override predicate isAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
6146
exists(API::CallNode call |
6247
call = API::moduleImport("paramiko").getMember("ProxyCommand").getACall() and
63-
nodeFrom = [call.getArg(0), call.getArgByName("command_line")] and
48+
nodeFrom = call.getParameter(0, "command_line").asSink() and
6449
nodeTo = call
6550
)
6651
}

0 commit comments

Comments
 (0)