Skip to content

Commit d6508f3

Browse files
committed
Add taint flow for Commander.js direct property access and action callbacks
1 parent 39170f3 commit d6508f3

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

javascript/ql/lib/semmle/javascript/frameworks/CommandLineArguments.qll

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,17 @@ private class ArgsParseStep extends TaintTracking::SharedTaintStep {
9696
)
9797
or
9898
exists(API::Node commanderNode | commanderNode = commander() |
99-
pred = commanderNode.getMember("parse").getACall().getAnArgument() and
100-
succ = commanderNode.getMember("opts").getACall()
99+
pred = commanderNode.getMember(["parse", "parseAsync"]).getACall().getAnArgument() and
100+
succ =
101+
[
102+
commanderNode.getMember("opts").getACall(), commanderNode.getAMember().asSource(),
103+
commander()
104+
.getMember("action")
105+
.getACall()
106+
.getArgument(0)
107+
.(DataFlow::FunctionNode)
108+
.getAParameter()
109+
]
101110
)
102111
or
103112
exists(DataFlow::MethodCallNode methodCall | methodCall = yargs() |

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
| child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | child_process-test.js:83:19:83:36 | req.query.fileName | This command line depends on a $@. | child_process-test.js:83:19:83:36 | req.query.fileName | user-provided value |
2323
| child_process-test.js:94:11:94:35 | "ping " ... ms.host | child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | This command line depends on a $@. | child_process-test.js:94:21:94:30 | ctx.params | user-provided value |
2424
| command-line-libs.js:14:8:14:18 | options.cmd | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:14:8:14:18 | options.cmd | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value |
25+
| command-line-libs.js:15:8:15:18 | program.cmd | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:15:8:15:18 | program.cmd | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value |
26+
| command-line-libs.js:21:12:21:17 | script | command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:21:12:21:17 | script | This command line depends on a $@. | command-line-libs.js:9:16:9:23 | req.body | user-provided value |
2527
| command-line-libs.js:49:8:49:17 | parsed.cmd | command-line-libs.js:42:16:42:23 | req.body | command-line-libs.js:49:8:49:17 | parsed.cmd | This command line depends on a $@. | command-line-libs.js:42:16:42:23 | req.body | user-provided value |
2628
| exec-sh2.js:10:12:10:57 | cp.spaw ... ptions) | exec-sh2.js:14:25:14:31 | req.url | exec-sh2.js:10:40:10:46 | command | This command line depends on a $@. | exec-sh2.js:14:25:14:31 | req.url | user-provided value |
2729
| exec-sh.js:15:12:15:61 | cp.spaw ... ptions) | exec-sh.js:19:25:19:31 | req.url | exec-sh.js:15:44:15:50 | command | This command line depends on a $@. | exec-sh.js:19:25:19:31 | req.url | user-provided value |
@@ -119,11 +121,16 @@ edges
119121
| child_process-test.js:73:25:73:31 | req.url | child_process-test.js:73:15:73:38 | url.par ... , true) | provenance | |
120122
| child_process-test.js:94:21:94:30 | ctx.params | child_process-test.js:94:11:94:35 | "ping " ... ms.host | provenance | |
121123
| command-line-libs.js:9:9:9:34 | args | command-line-libs.js:12:17:12:20 | args | provenance | |
124+
| command-line-libs.js:9:9:9:34 | args | command-line-libs.js:23:29:23:32 | args | provenance | |
122125
| command-line-libs.js:9:16:9:23 | req.body | command-line-libs.js:9:9:9:34 | args | provenance | |
123126
| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:13:19:13:32 | program.opts() | provenance | |
127+
| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:15:8:15:18 | program.cmd | provenance | |
128+
| command-line-libs.js:12:17:12:20 | args | command-line-libs.js:20:14:20:19 | script | provenance | |
124129
| command-line-libs.js:13:9:13:32 | options | command-line-libs.js:14:8:14:14 | options | provenance | |
125130
| command-line-libs.js:13:19:13:32 | program.opts() | command-line-libs.js:13:9:13:32 | options | provenance | |
126131
| command-line-libs.js:14:8:14:14 | options | command-line-libs.js:14:8:14:18 | options.cmd | provenance | |
132+
| command-line-libs.js:20:14:20:19 | script | command-line-libs.js:21:12:21:17 | script | provenance | |
133+
| command-line-libs.js:23:29:23:32 | args | command-line-libs.js:20:14:20:19 | script | provenance | |
127134
| command-line-libs.js:42:9:42:34 | args | command-line-libs.js:43:24:43:27 | args | provenance | |
128135
| command-line-libs.js:42:16:42:23 | req.body | command-line-libs.js:42:9:42:34 | args | provenance | |
129136
| command-line-libs.js:43:9:47:12 | parsed | command-line-libs.js:49:8:49:13 | parsed | provenance | |
@@ -292,6 +299,10 @@ nodes
292299
| command-line-libs.js:13:19:13:32 | program.opts() | semmle.label | program.opts() |
293300
| command-line-libs.js:14:8:14:14 | options | semmle.label | options |
294301
| command-line-libs.js:14:8:14:18 | options.cmd | semmle.label | options.cmd |
302+
| command-line-libs.js:15:8:15:18 | program.cmd | semmle.label | program.cmd |
303+
| command-line-libs.js:20:14:20:19 | script | semmle.label | script |
304+
| command-line-libs.js:21:12:21:17 | script | semmle.label | script |
305+
| command-line-libs.js:23:29:23:32 | args | semmle.label | args |
295306
| command-line-libs.js:42:9:42:34 | args | semmle.label | args |
296307
| command-line-libs.js:42:16:42:23 | req.body | semmle.label | req.body |
297308
| command-line-libs.js:43:9:47:12 | parsed | semmle.label | parsed |

javascript/ql/test/query-tests/Security/CWE-078/CommandInjection/command-line-libs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ app.post('/Command', async (req, res) => {
1212
program.parse(args, { from: 'user' });
1313
const options = program.opts();
1414
exec(options.cmd); // $ Alert
15-
exec(program.cmd); // $ MISSING: Alert
15+
exec(program.cmd); // $ Alert
1616

1717
const program1 = new Command();
1818
program1
1919
.command('run <script>')
2020
.action((script) => {
21-
exec(script); // $ MISSING: Alert
21+
exec(script); // $ Alert
2222
});
2323
await program1.parseAsync(args);
2424
});

0 commit comments

Comments
 (0)