Skip to content

Commit ae4077d

Browse files
committed
add taint flow for arg/command-line-args with custom argv option
1 parent d6508f3 commit ae4077d

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ private class ArgsParseStep extends TaintTracking::SharedTaintStep {
113113
pred = methodCall.getReceiver() and
114114
succ = methodCall
115115
)
116+
or
117+
exists(DataFlow::CallNode call, DataFlow::Node options |
118+
call = DataFlow::moduleImport(["arg", "command-line-args"]).getACall() and
119+
succ = call and
120+
options = call.getArgument(1) and
121+
exists(DataFlow::PropWrite write |
122+
write.getBase() = options and
123+
write.getPropertyName() = "argv" and
124+
pred = write.getRhs()
125+
)
126+
)
116127
}
117128
}
118129

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
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 |
2525
| 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 |
2626
| 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 |
27+
| command-line-libs.js:29:10:29:24 | parsed['--cmd'] | command-line-libs.js:27:23:27:30 | req.body | command-line-libs.js:29:10:29:24 | parsed['--cmd'] | This command line depends on a $@. | command-line-libs.js:27:23:27:30 | req.body | user-provided value |
28+
| command-line-libs.js:37:8:37:18 | options.cmd | command-line-libs.js:35:62:35:69 | req.body | command-line-libs.js:37:8:37:18 | options.cmd | This command line depends on a $@. | command-line-libs.js:35:62:35:69 | req.body | user-provided value |
2729
| 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 |
2830
| 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 |
2931
| 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 |
@@ -131,6 +133,16 @@ edges
131133
| command-line-libs.js:14:8:14:14 | options | command-line-libs.js:14:8:14:18 | options.cmd | provenance | |
132134
| command-line-libs.js:20:14:20:19 | script | command-line-libs.js:21:12:21:17 | script | provenance | |
133135
| command-line-libs.js:23:29:23:32 | args | command-line-libs.js:20:14:20:19 | script | provenance | |
136+
| command-line-libs.js:27:11:27:41 | argsArray | command-line-libs.js:28:53:28:61 | argsArray | provenance | |
137+
| command-line-libs.js:27:23:27:30 | req.body | command-line-libs.js:27:11:27:41 | argsArray | provenance | |
138+
| command-line-libs.js:28:11:28:64 | parsed | command-line-libs.js:29:10:29:15 | parsed | provenance | |
139+
| command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | command-line-libs.js:28:11:28:64 | parsed | provenance | |
140+
| command-line-libs.js:28:53:28:61 | argsArray | command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | provenance | |
141+
| command-line-libs.js:29:10:29:15 | parsed | command-line-libs.js:29:10:29:24 | parsed['--cmd'] | provenance | |
142+
| command-line-libs.js:35:9:35:83 | options | command-line-libs.js:37:8:37:14 | options | provenance | |
143+
| command-line-libs.js:35:19:35:83 | command ... \| [] }) | command-line-libs.js:35:9:35:83 | options | provenance | |
144+
| command-line-libs.js:35:62:35:69 | req.body | command-line-libs.js:35:19:35:83 | command ... \| [] }) | provenance | |
145+
| command-line-libs.js:37:8:37:14 | options | command-line-libs.js:37:8:37:18 | options.cmd | provenance | |
134146
| command-line-libs.js:42:9:42:34 | args | command-line-libs.js:43:24:43:27 | args | provenance | |
135147
| command-line-libs.js:42:16:42:23 | req.body | command-line-libs.js:42:9:42:34 | args | provenance | |
136148
| command-line-libs.js:43:9:47:12 | parsed | command-line-libs.js:49:8:49:13 | parsed | provenance | |
@@ -303,6 +315,18 @@ nodes
303315
| command-line-libs.js:20:14:20:19 | script | semmle.label | script |
304316
| command-line-libs.js:21:12:21:17 | script | semmle.label | script |
305317
| command-line-libs.js:23:29:23:32 | args | semmle.label | args |
318+
| command-line-libs.js:27:11:27:41 | argsArray | semmle.label | argsArray |
319+
| command-line-libs.js:27:23:27:30 | req.body | semmle.label | req.body |
320+
| command-line-libs.js:28:11:28:64 | parsed | semmle.label | parsed |
321+
| command-line-libs.js:28:20:28:64 | arg({ ' ... rray }) | semmle.label | arg({ ' ... rray }) |
322+
| command-line-libs.js:28:53:28:61 | argsArray | semmle.label | argsArray |
323+
| command-line-libs.js:29:10:29:15 | parsed | semmle.label | parsed |
324+
| command-line-libs.js:29:10:29:24 | parsed['--cmd'] | semmle.label | parsed['--cmd'] |
325+
| command-line-libs.js:35:9:35:83 | options | semmle.label | options |
326+
| command-line-libs.js:35:19:35:83 | command ... \| [] }) | semmle.label | command ... \| [] }) |
327+
| command-line-libs.js:35:62:35:69 | req.body | semmle.label | req.body |
328+
| command-line-libs.js:37:8:37:14 | options | semmle.label | options |
329+
| command-line-libs.js:37:8:37:18 | options.cmd | semmle.label | options.cmd |
306330
| command-line-libs.js:42:9:42:34 | args | semmle.label | args |
307331
| command-line-libs.js:42:16:42:23 | req.body | semmle.label | req.body |
308332
| 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: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ app.post('/Command', async (req, res) => {
2424
});
2525

2626
app.post('/arg', (req, res) => {
27-
const argsArray = req.body.args || []; // $ MISSING: Source
27+
const argsArray = req.body.args || []; // $ Source
2828
const parsed = arg({ '--cmd': String }, { argv: argsArray });
29-
exec(parsed['--cmd']); // $ MISSING: Alert
29+
exec(parsed['--cmd']); // $ Alert
3030
});
3131

3232
app.post('/commandLineArgs', (req, res) => {
3333
const commandLineArgs = require('command-line-args');
3434
const optionDefinitions = [{ name: 'cmd', type: String }];
35-
const options = commandLineArgs(optionDefinitions, { argv: req.body.args || [] }); // $ MISSING: Source
35+
const options = commandLineArgs(optionDefinitions, { argv: req.body.args || [] }); // $ Source
3636
if (!options.cmd) return res.status(400).send({ error: 'Missing --cmd' });
37-
exec(options.cmd); // $ MISSING: Alert
37+
exec(options.cmd); // $ Alert
3838
});
3939

4040
app.post('/yargs', (req, res) => {

0 commit comments

Comments
 (0)