Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8ea6070

Browse files
committed
add indirect command injection sink for a concatenated array
1 parent 180e9d4 commit 8ea6070

3 files changed

Lines changed: 25 additions & 12 deletions

File tree

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

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ private DataFlow::Node commandArgument(SystemCommandExecution sys, DataFlow::Typ
3030
t.start() and
3131
result = sys.getACommandArgument()
3232
or
33-
exists(DataFlow::TypeBackTracker t2 |
34-
t = t2.smallstep(result, commandArgument(sys, t2))
35-
)
33+
exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, commandArgument(sys, t2)))
3634
}
3735

3836
/**
@@ -43,9 +41,7 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::
4341
t.start() and
4442
result = sys.getArgumentList().getALocalSource()
4543
or
46-
exists(DataFlow::TypeBackTracker t2 |
47-
result = argumentList(sys, t2).backtrack(t2, t)
48-
)
44+
exists(DataFlow::TypeBackTracker t2 | result = argumentList(sys, t2).backtrack(t2, t))
4945
}
5046

5147
/**
@@ -61,15 +57,29 @@ private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::
6157
* let args = ["-c", cmd];
6258
* childProcess.spawn(sh, args, cb);
6359
* ```
60+
* or
61+
* ```
62+
* let cmd = getCommand();
63+
* childProcess.spawn("cmd.exe", ["/c"].concat(cmd), cb);
64+
* ```
6465
*/
6566
predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecution sys) {
66-
exists(
67-
DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC
68-
|
67+
exists(DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC |
6968
shellCmd(shell.asExpr(), dashC) and
7069
shell = commandArgument(sys, DataFlow::TypeBackTracker::end()) and
71-
args = argumentList(sys, DataFlow::TypeBackTracker::end()) and
7270
args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and
73-
source = args.getAPropertyWrite().getRhs()
71+
(
72+
args = argumentList(sys, DataFlow::TypeBackTracker::end()) and
73+
source = args.getAPropertyWrite().getRhs()
74+
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+
)
83+
)
7484
)
7585
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ edges
168168
| 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 |
169169
| 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 |
170170
| 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:56:3:56: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 |
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 |
172173
| 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 |
173174
| 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 |
174175
| 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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ 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
54+
5355
});
5456

5557
function run(cmd, args) {

0 commit comments

Comments
 (0)