Skip to content

Commit c6668da

Browse files
committed
expand how indirectCommandArguments are found
1 parent dd9e3d2 commit c6668da

File tree

3 files changed

+47
-14
lines changed

3 files changed

+47
-14
lines changed

javascript/ql/src/semmle/javascript/security/dataflow/IndirectCommandArgument.qll

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::
4141
t.start() and
4242
result = sys.getArgumentList().getALocalSource()
4343
or
44-
exists(DataFlow::TypeBackTracker t2 | result = argumentList(sys, t2).backtrack(t2, t))
44+
exists(DataFlow::TypeBackTracker t2, DataFlow::SourceNode pred |
45+
pred = argumentList(sys, t2)
46+
|
47+
result = pred.backtrack(t2, t)
48+
or
49+
t = t2.continue() and
50+
TaintTracking::arrayFunctionTaintStep(result, pred, _)
51+
)
4552
}
4653

4754
/**
@@ -68,18 +75,11 @@ predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecutio
6875
shellCmd(shell.asExpr(), dashC) and
6976
shell = commandArgument(sys, DataFlow::TypeBackTracker::end()) and
7077
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
78+
args = argumentList(sys, DataFlow::TypeBackTracker::end()) and
7179
(
72-
args = argumentList(sys, DataFlow::TypeBackTracker::end()) and
73-
source = args.getAPropertyWrite().getRhs()
80+
source = argumentList(sys, DataFlow::TypeBackTracker::end())
7481
or
75-
exists(DataFlow::MethodCallNode concatCall |
76-
args = concatCall.getReceiver() and
77-
concatCall.getMethodName() = "concat" and
78-
concatCall = argumentList(sys, DataFlow::TypeBackTracker::end())
79-
|
80-
source = concatCall.getAnArgument() or
81-
source = concatCall.getAnArgument().getALocalSource().getAPropertyWrite().getRhs()
82-
)
82+
source = argumentList(sys, DataFlow::TypeBackTracker::end()).getAPropertyWrite().getRhs()
8383
)
8484
)
8585
}

javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,23 @@ nodes
2222
| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
2323
| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
2424
| child_process-test.js:25:21:25:23 | cmd |
25+
| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
26+
| child_process-test.js:39:18:39:30 | [ flag, cmd ] |
2527
| child_process-test.js:39:26:39:28 | cmd |
2628
| child_process-test.js:39:26:39:28 | cmd |
2729
| child_process-test.js:43:15:43:17 | cmd |
2830
| child_process-test.js:43:15:43:17 | cmd |
2931
| child_process-test.js:50:15:50:17 | cmd |
3032
| child_process-test.js:50:15:50:17 | cmd |
33+
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
34+
| child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
35+
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
36+
| child_process-test.js:53:46:53:57 | ["bar", cmd] |
37+
| child_process-test.js:53:54:53:56 | cmd |
38+
| child_process-test.js:53:54:53:56 | cmd |
39+
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
40+
| child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
41+
| child_process-test.js:54:46:54:48 | cmd |
3142
| execSeries.js:3:20:3:22 | arr |
3243
| execSeries.js:6:14:6:16 | arr |
3344
| execSeries.js:6:14:6:21 | arr[i++] |
@@ -100,13 +111,24 @@ edges
100111
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd |
101112
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
102113
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd |
114+
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
115+
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:53:54:53:56 | cmd |
116+
| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:54:46:54:48 | cmd |
103117
| child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:44 | url.par ... ).query |
104118
| child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path |
105119
| child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd |
106120
| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) |
107121
| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) |
108122
| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
109123
| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" |
124+
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
125+
| child_process-test.js:39:26:39:28 | cmd | child_process-test.js:39:18:39:30 | [ flag, cmd ] |
126+
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
127+
| child_process-test.js:53:46:53:57 | ["bar", cmd] | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) |
128+
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
129+
| child_process-test.js:53:54:53:56 | cmd | child_process-test.js:53:46:53:57 | ["bar", cmd] |
130+
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
131+
| child_process-test.js:54:46:54:48 | cmd | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) |
110132
| execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr |
111133
| execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] |
112134
| execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command |
@@ -165,11 +187,16 @@ edges
165187
| child_process-test.js:22:18:22:20 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:22:18:22:20 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
166188
| child_process-test.js:23:13:23:15 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:23:13:23:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
167189
| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
190+
| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:39:18:39:30 | [ flag, cmd ] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
168191
| child_process-test.js:39:5:39:31 | cp.spaw ... cmd ]) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:39:26:39:28 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
169192
| child_process-test.js:44:5:44:34 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
170193
| child_process-test.js:51:5:51:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
171-
| child_process-test.js:53:5:53:51 | cp.spaw ... (args)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
172-
| child_process-test.js:58:3:58:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
194+
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:25:53:58 | ['/C', ... , cmd]) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
195+
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:46:53:57 | ["bar", cmd] | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
196+
| child_process-test.js:53:5:53:59 | cp.spaw ... cmd])) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:53:54:53:56 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
197+
| child_process-test.js:54:5:54:50 | cp.spaw ... t(cmd)) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:54:25:54:49 | ['/C', ... at(cmd) | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
198+
| child_process-test.js:59:5:59:39 | cp.exec ... , args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:50:15:50:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
199+
| child_process-test.js:64:3:64:21 | cp.spawn(cmd, args) | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:43:15:43:17 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value |
173200
| execSeries.js:14:41:14:47 | command | execSeries.js:18:34:18:40 | req.url | execSeries.js:14:41:14:47 | command | This command depends on $@. | execSeries.js:18:34:18:40 | req.url | a user-provided value |
174201
| other.js:7:33:7:35 | cmd | other.js:5:25:5:31 | req.url | other.js:7:33:7:35 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |
175202
| other.js:8:28:8:30 | cmd | other.js:5:25:5:31 | req.url | other.js:8:28:8:30 | cmd | This command depends on $@. | other.js:5:25:5:31 | req.url | a user-provided value |

javascript/ql/test/query-tests/Security/CWE-078/child_process-test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ var server = http.createServer(function(req, res) {
5050
args[1] = cmd;
5151
cp.execFile(`/bin` + "/bash", args); // NOT OK
5252

53-
cp.spawn('cmd.exe', ['/C', 'foo'].concat(args)); // NOT OK
53+
cp.spawn('cmd.exe', ['/C', 'foo'].concat(["bar", cmd])); // NOT OK
54+
cp.spawn('cmd.exe', ['/C', 'foo'].concat(cmd)); // NOT OK
55+
56+
let myArgs = [];
57+
myArgs.push(`-` + "c");
58+
myArgs.push(cmd);
59+
cp.execFile(`/bin` + "/bash", args); // NOT OK
5460

5561
});
5662

0 commit comments

Comments
 (0)