Skip to content

Commit 120faf9

Browse files
committed
add a code injection sink for JSDOM when "runScripts" is set to "dangerously"
1 parent e6e4a48 commit 120faf9

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,17 @@ module CodeInjection {
138138
API::moduleImport("module").getInstance().getMember("_compile").getACall().getArgument(0)
139139
}
140140
}
141+
142+
/**
143+
* A construction of a JSDOM object (server side DOM), where scripts are allowed.
144+
*/
145+
class JSDomWithRunScripts extends Sink {
146+
JSDomWithRunScripts() {
147+
exists(DataFlow::NewNode instance |
148+
instance = API::moduleImport("jsdom").getMember("JSDOM").getInstance().getAnImmediateUse() and
149+
this = instance.getArgument(0) and
150+
instance.getOptionArgument(1, "runScripts").mayHaveStringValue("dangerously")
151+
)
152+
}
153+
}
141154
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ nodes
108108
| express.js:21:19:21:48 | req.par ... ntext") |
109109
| express.js:21:19:21:48 | req.par ... ntext") |
110110
| express.js:21:19:21:48 | req.par ... ntext") |
111+
| express.js:28:13:28:31 | req.param("wobble") |
112+
| express.js:28:13:28:31 | req.param("wobble") |
113+
| express.js:28:13:28:31 | req.param("wobble") |
111114
| module.js:9:16:9:29 | req.query.code |
112115
| module.js:9:16:9:29 | req.query.code |
113116
| module.js:9:16:9:29 | req.query.code |
@@ -249,6 +252,7 @@ edges
249252
| express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") |
250253
| express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") |
251254
| express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") |
255+
| express.js:28:13:28:31 | req.param("wobble") | express.js:28:13:28:31 | req.param("wobble") |
252256
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code |
253257
| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted |
254258
| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted |
@@ -312,6 +316,7 @@ edges
312316
| express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") | $@ flows to here and is interpreted as code. | express.js:17:30:17:53 | req.par ... cript") | User-provided value |
313317
| 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") | $@ flows to here and is interpreted as code. | express.js:19:37:19:70 | req.par ... odule") | User-provided value |
314318
| 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") | $@ flows to here and is interpreted as code. | express.js:21:19:21:48 | req.par ... ntext") | User-provided value |
319+
| express.js:28:13:28:31 | req.param("wobble") | express.js:28:13:28:31 | req.param("wobble") | express.js:28:13:28:31 | req.param("wobble") | $@ flows to here and is interpreted as code. | express.js:28:13:28:31 | req.param("wobble") | User-provided value |
315320
| 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 | $@ flows to here and is interpreted as code. | module.js:9:16:9:29 | req.query.code | User-provided value |
316321
| 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 | $@ flows to here and is interpreted as code. | react-native.js:7:17:7:33 | req.param("code") | User-provided value |
317322
| react-native.js:10:23:10:29 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:10:23:10:29 | tainted | $@ flows to here and is interpreted as code. | 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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ nodes
112112
| express.js:21:19:21:48 | req.par ... ntext") |
113113
| express.js:21:19:21:48 | req.par ... ntext") |
114114
| express.js:21:19:21:48 | req.par ... ntext") |
115+
| express.js:28:13:28:31 | req.param("wobble") |
116+
| express.js:28:13:28:31 | req.param("wobble") |
117+
| express.js:28:13:28:31 | req.param("wobble") |
115118
| module.js:9:16:9:29 | req.query.code |
116119
| module.js:9:16:9:29 | req.query.code |
117120
| module.js:9:16:9:29 | req.query.code |
@@ -257,6 +260,7 @@ edges
257260
| express.js:17:30:17:53 | req.par ... cript") | express.js:17:30:17:53 | req.par ... cript") |
258261
| express.js:19:37:19:70 | req.par ... odule") | express.js:19:37:19:70 | req.par ... odule") |
259262
| express.js:21:19:21:48 | req.par ... ntext") | express.js:21:19:21:48 | req.par ... ntext") |
263+
| express.js:28:13:28:31 | req.param("wobble") | express.js:28:13:28:31 | req.param("wobble") |
260264
| module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code |
261265
| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted |
262266
| 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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,13 @@ app.get('/some/path', function(req, res) {
2020
// NOT OK
2121
vm.runInContext(req.param("code_runInContext"), vm.createContext());
2222
});
23+
24+
import {JSDOM} from "jsdom";
25+
26+
app.get('/some/path', function(req, res) {
27+
// NOT OK
28+
new JSDOM(req.param("wobble"), {runScripts: "dangerously"});
29+
30+
// OK
31+
new JSDOM(req.param("wobble"), {runScripts: "outside-only"});
32+
});

0 commit comments

Comments
 (0)