Skip to content

Commit 7ae389b

Browse files
authored
Merge pull request github#12026 from erik-krogh/nodePty
JS: add code-injection sink for node-pty
2 parents 86e9bf2 + 0cefa98 commit 7ae389b

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added sinks from the [`node-pty`](https://www.npmjs.com/package/node-pty) library to the `js/code-injection` query.

javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,27 @@ module CodeInjection {
294294
}
295295
}
296296

297+
/**
298+
* An execution of a terminal command via the `node-pty` library, seen as a code injection sink.
299+
* Example:
300+
* ```JS
301+
* var pty = require('node-pty');
302+
* var ptyProcess = pty.spawn("bash", [], {...});
303+
* ptyProcess.write('ls\r');
304+
* ```
305+
*/
306+
class NodePty extends Sink {
307+
NodePty() {
308+
this =
309+
API::moduleImport("node-pty")
310+
.getMember("spawn")
311+
.getReturn()
312+
.getMember("write")
313+
.getACall()
314+
.getArgument(0)
315+
}
316+
}
317+
297318
/** A sink for code injection via template injection. */
298319
abstract private class TemplateSink extends Sink {
299320
deprecated override string getMessageSuffix() {

javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ nodes
8484
| express.js:26:17:26:35 | req.param("wobble") |
8585
| express.js:27:34:27:38 | taint |
8686
| express.js:27:34:27:38 | taint |
87+
| express.js:34:9:34:35 | taint |
88+
| express.js:34:17:34:35 | req.param("wobble") |
89+
| express.js:34:17:34:35 | req.param("wobble") |
90+
| express.js:43:15:43:19 | taint |
91+
| express.js:43:15:43:19 | taint |
8792
| module.js:9:16:9:29 | req.query.code |
8893
| module.js:9:16:9:29 | req.query.code |
8994
| module.js:9:16:9:29 | req.query.code |
@@ -216,6 +221,10 @@ edges
216221
| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint |
217222
| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint |
218223
| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint |
224+
| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint |
225+
| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint |
226+
| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint |
227+
| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint |
219228
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code |
220229
| module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code |
221230
| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted |
@@ -311,6 +320,7 @@ edges
311320
| express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") | This code execution depends on a $@. | express.js:19:37:19:70 | req.par ... odule") | user-provided value |
312321
| express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") | This code execution depends on a $@. | express.js:21:19:21:48 | req.par ... ntext") | user-provided value |
313322
| express.js:27:34:27:38 | taint | express.js:26:17:26:35 | req.param("wobble") | express.js:27:34:27:38 | taint | This code execution depends on a $@. | express.js:26:17:26:35 | req.param("wobble") | user-provided value |
323+
| express.js:43:15:43:19 | taint | express.js:34:17:34:35 | req.param("wobble") | express.js:43:15:43:19 | taint | This code execution depends on a $@. | express.js:34:17:34:35 | req.param("wobble") | user-provided value |
314324
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | This code execution depends on a $@. | module.js:9:16:9:29 | req.query.code | user-provided value |
315325
| module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | This code execution depends on a $@. | module.js:11:17:11:30 | req.query.code | user-provided value |
316326
| react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | This code execution depends on a $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value |

javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ nodes
8888
| express.js:26:17:26:35 | req.param("wobble") |
8989
| express.js:27:34:27:38 | taint |
9090
| express.js:27:34:27:38 | taint |
91+
| express.js:34:9:34:35 | taint |
92+
| express.js:34:17:34:35 | req.param("wobble") |
93+
| express.js:34:17:34:35 | req.param("wobble") |
94+
| express.js:43:15:43:19 | taint |
95+
| express.js:43:15:43:19 | taint |
9196
| module.js:9:16:9:29 | req.query.code |
9297
| module.js:9:16:9:29 | req.query.code |
9398
| module.js:9:16:9:29 | req.query.code |
@@ -224,6 +229,10 @@ edges
224229
| express.js:26:9:26:35 | taint | express.js:27:34:27:38 | taint |
225230
| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint |
226231
| express.js:26:17:26:35 | req.param("wobble") | express.js:26:9:26:35 | taint |
232+
| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint |
233+
| express.js:34:9:34:35 | taint | express.js:43:15:43:19 | taint |
234+
| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint |
235+
| express.js:34:17:34:35 | req.param("wobble") | express.js:34:9:34:35 | taint |
227236
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code |
228237
| module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code |
229238
| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted |

javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/express.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,18 @@ app.get('/other/path', function(req, res) {
2828

2929
cp.execFileSync('node', ['-e', `console.log(${JSON.stringify(taint)})`]); // OK
3030
});
31+
32+
const pty = require('node-pty');
33+
app.get('/terminal', function(req, res) {
34+
const taint = req.param("wobble");
35+
const shell = pty.spawn('bash', [], {
36+
name: 'xterm-color',
37+
cols: 80,
38+
rows: 30,
39+
cwd: process.env.HOME,
40+
env: process.env
41+
});
42+
43+
shell.write(taint); // NOT OK
44+
});
45+

0 commit comments

Comments
 (0)