Skip to content

Commit d6a14e6

Browse files
committed
JS: Add test cases for promisification libraries.
1 parent e8ddac0 commit d6a14e6

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@
8282
| other.js:28:27:28:29 | cmd | other.js:5:25:5:31 | req.url | other.js:28:27:28:29 | cmd | This command line depends on a $@. | other.js:5:25:5:31 | req.url | user-provided value |
8383
| other.js:30:33:30:35 | cmd | other.js:5:25:5:31 | req.url | other.js:30:33:30:35 | cmd | This command line depends on a $@. | other.js:5:25:5:31 | req.url | user-provided value |
8484
| other.js:34:44:34:46 | cmd | other.js:5:25:5:31 | req.url | other.js:34:44:34:46 | cmd | This command line depends on a $@. | other.js:5:25:5:31 | req.url | user-provided value |
85+
| promisification.js:24:22:24:25 | code | promisification.js:21:18:21:25 | req.body | promisification.js:24:22:24:25 | code | This command line depends on a $@. | promisification.js:21:18:21:25 | req.body | user-provided value |
86+
| promisification.js:52:21:52:24 | code | promisification.js:49:18:49:25 | req.body | promisification.js:52:21:52:24 | code | This command line depends on a $@. | promisification.js:49:18:49:25 | req.body | user-provided value |
87+
| promisification.js:55:15:55:18 | code | promisification.js:49:18:49:25 | req.body | promisification.js:55:15:55:18 | code | This command line depends on a $@. | promisification.js:49:18:49:25 | req.body | user-provided value |
8588
| third-party-command-injection.js:6:21:6:27 | command | third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | This command line depends on a $@. | third-party-command-injection.js:5:20:5:26 | command | user-provided value |
8689
edges
8790
| actions.js:8:9:8:13 | title | actions.js:9:16:9:20 | title | provenance | |
@@ -259,6 +262,11 @@ edges
259262
| other.js:5:9:5:11 | cmd | other.js:34:44:34:46 | cmd | provenance | |
260263
| other.js:5:15:5:38 | url.par ... , true) | other.js:5:9:5:11 | cmd | provenance | |
261264
| other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | provenance | |
265+
| promisification.js:21:11:21:14 | code | promisification.js:24:22:24:25 | code | provenance | |
266+
| promisification.js:21:18:21:25 | req.body | promisification.js:21:11:21:14 | code | provenance | |
267+
| promisification.js:49:11:49:14 | code | promisification.js:52:21:52:24 | code | provenance | |
268+
| promisification.js:49:11:49:14 | code | promisification.js:55:15:55:18 | code | provenance | |
269+
| promisification.js:49:18:49:25 | req.body | promisification.js:49:11:49:14 | code | provenance | |
262270
| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | provenance | |
263271
nodes
264272
| actions.js:8:9:8:13 | title | semmle.label | title |
@@ -446,6 +454,13 @@ nodes
446454
| other.js:28:27:28:29 | cmd | semmle.label | cmd |
447455
| other.js:30:33:30:35 | cmd | semmle.label | cmd |
448456
| other.js:34:44:34:46 | cmd | semmle.label | cmd |
457+
| promisification.js:21:11:21:14 | code | semmle.label | code |
458+
| promisification.js:21:18:21:25 | req.body | semmle.label | req.body |
459+
| promisification.js:24:22:24:25 | code | semmle.label | code |
460+
| promisification.js:49:11:49:14 | code | semmle.label | code |
461+
| promisification.js:49:18:49:25 | req.body | semmle.label | req.body |
462+
| promisification.js:52:21:52:24 | code | semmle.label | code |
463+
| promisification.js:55:15:55:18 | code | semmle.label | code |
449464
| third-party-command-injection.js:5:20:5:26 | command | semmle.label | command |
450465
| third-party-command-injection.js:6:21:6:27 | command | semmle.label | command |
451466
subpaths
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
const express = require('express');
2+
const bodyParser = require('body-parser');
3+
const cp = require('child_process');
4+
5+
const app = express();
6+
app.use(bodyParser.json());
7+
8+
function legacyEval(code) {
9+
cp.exec(code.code); // $ MISSING: Alert
10+
}
11+
12+
app.post('/eval', async (req, res) => {
13+
const { promisify } = require('util');
14+
const evalAsync = promisify(legacyEval);
15+
const code = req.body; // $ MISSING: Source
16+
evalAsync(code);
17+
});
18+
19+
app.post('/eval', async (req, res) => {
20+
const directPromisify = require('util.promisify');
21+
const code = req.body; // $ Source
22+
23+
const promisifiedExec3 = directPromisify(cp.exec);
24+
promisifiedExec3(code); // $ Alert
25+
});
26+
27+
app.post('/eval', async (req, res) => {
28+
const promisify2 = require('util.promisify-all');
29+
const promisifiedCp = promisify2(cp);
30+
const code = req.body; // $ MISSING: Source
31+
promisifiedCp.exec(code); // $ MISSING: Alert
32+
});
33+
34+
35+
app.post('/eval', async (req, res) => {
36+
var garPromisify = require("@gar/promisify");
37+
const code = req.body; // $ MISSING: Source
38+
39+
const promisifiedExec = garPromisify(cp.exec);
40+
promisifiedExec(code); // $ MISSING: Alert
41+
42+
const promisifiedCp = garPromisify(cp);
43+
promisifiedCp.exec(code); // $ MISSING: Alert
44+
});
45+
46+
app.post('/eval', async (req, res) => {
47+
require('util.promisify/shim')();
48+
const util = require('util');
49+
const code = req.body; // $ Source
50+
51+
const promisifiedExec = util.promisify(cp.exec);
52+
promisifiedExec(code); // $ Alert
53+
54+
const execAsync = util.promisify(cp.exec.bind(cp));
55+
execAsync(code); // $ Alert
56+
});
57+
58+
59+
app.post('/eval', async (req, res) => {
60+
const es6Promisify = require("es6-promisify");
61+
let cmd = req.body; // $ MISSING: Source
62+
63+
// Test basic promisification
64+
const promisifiedExec = es6Promisify(cp.exec);
65+
promisifiedExec(cmd); // $ MISSING: Alert
66+
67+
// Test with method binding
68+
const execBoundAsync = es6Promisify(cp.exec.bind(cp));
69+
execBoundAsync(cmd); // $ MISSING: Alert
70+
71+
const promisifiedExecMulti = es6Promisify(cp.exec, {
72+
multiArgs: true
73+
});
74+
promisifiedExecMulti(cmd); // $ MISSING: Alert
75+
76+
const promisifiedCp = es6Promisify.promisifyAll(cp);
77+
promisifiedCp.exec(cmd); // $ MISSING: Alert
78+
promisifiedCp.execFile(cmd); // $ MISSING: Alert
79+
promisifiedCp.spawn(cmd); // $ MISSING: Alert
80+
81+
const lambda = es6Promisify((code, callback) => {
82+
try {
83+
const result = cp.exec(code); // $ MISSING: Alert
84+
callback(null, result);
85+
} catch (err) {
86+
callback(err);
87+
}
88+
});
89+
lambda(cmd);
90+
});
91+
92+
93+
app.post('/eval', async (req, res) => {
94+
var thenifyAll = require('thenify-all');
95+
var cpThenifyAll = thenifyAll(require('child_process'), {}, [
96+
'exec',
97+
'execSync',
98+
]);
99+
const code = req.body; // $ MISSING: Source
100+
cpThenifyAll.exec(code); // $ MISSING: Alert
101+
cpThenifyAll.execSync(code); // $ MISSING: Alert
102+
cpThenifyAll.execFile(code); // $ MISSING: Alert - not promisified, as it is not listed in `thenifyAll`
103+
104+
105+
var cpThenifyAll1 = thenifyAll.withCallback(require('child_process'), {}, ['exec']);
106+
cpThenifyAll1.exec(code, function (err, string) {}); // $ MISSING: Alert
107+
108+
var cpThenifyAll2 = thenifyAll(require('child_process'));
109+
cpThenifyAll2.exec(code); // $ MISSING: Alert
110+
});
111+
112+
app.post('/eval', async (req, res) => {
113+
const maybe = require('call-me-maybe');
114+
const code = req.body; // $ MISSING: Source
115+
116+
function createExecPromise(cmd) {
117+
return new Promise((resolve) => {
118+
resolve(cmd);
119+
});
120+
}
121+
122+
const cmdPromise = createExecPromise(code);
123+
maybe(null, cmdPromise).then(cmd => {
124+
cp.exec(cmd); // $ MISSING: Alert
125+
});
126+
});
127+
128+
app.post('/eval', async (req, res) => {
129+
const utilPromisify = require('util-promisify');
130+
const code = req.body; // $ MISSING: Source
131+
132+
const promisifiedExec = utilPromisify(cp.exec);
133+
promisifiedExec(code); // $ MISSING: Alert
134+
135+
const execAsync = utilPromisify(cp.exec.bind(cp));
136+
execAsync(code); // $ MISSING: Alert
137+
});
138+
139+
app.post('/eval', async (req, res) => {
140+
const {promisify, promisifyAll} = require('@google-cloud/promisify');
141+
const code = req.body; // $ MISSING: Source
142+
143+
const promisifiedExec = promisify(cp.exec);
144+
promisifiedExec(code); // $ MISSING: Alert
145+
146+
const execAsync = promisify(cp.exec.bind(cp));
147+
execAsync(code); // $ MISSING: Alert
148+
149+
const promisifiedCp = promisifyAll(cp);
150+
promisifiedCp.exec(code); // $ MISSING: Alert
151+
promisifiedCp.execFile(code); // $ MISSING: Alert
152+
promisifiedCp.spawn(code); // $ MISSING: Alert
153+
});

0 commit comments

Comments
 (0)