From 06114d91d826696b0db3364bd191197b87671228 Mon Sep 17 00:00:00 2001 From: amammad Date: Fri, 22 Sep 2023 19:19:52 +1000 Subject: [PATCH 01/14] V1 --- .../javascript/frameworks/NodeJSLib.qll | 15 + .../frameworks/NodeJSLib/exec.js | 3 + .../frameworks/NodeJSLib/tests.expected | 483 +++++++++--------- 3 files changed, 260 insertions(+), 241 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 258a583e1ca0..9996c4fe2261 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -760,6 +760,21 @@ module NodeJSLib { } } + /** + * The dynamic import expression input can be a `data:` URL which loads any module from that data + */ + class DynamicImport extends SystemCommandExecution, DataFlow::ExprNode { + DynamicImport() { this = any(DynamicImportExpr e).getAChildExpr().flow() } + + override DataFlow::Node getACommandArgument() { result = this } + + override predicate isShellInterpreted(DataFlow::Node arg) { arg = this } + + override predicate isSync() { none() } + + override DataFlow::Node getOptionsArg() { none() } + } + /** * A call to a method from module `child_process`. */ diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js b/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js index d22f0bb760d8..8a3bf9d6da47 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js @@ -5,3 +5,6 @@ cp.execFileSync("sh", ["-c", "node --version"]); cp.fork("foo", ["arg"]); cp.spawn("echo", ["Hi"], cb); cp.spawnSync("echo", ["Hi", "there"]); + +// dynamic import +await import('data:text/javascript,console.log("hello!");') \ No newline at end of file diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index 78c2c35309ff..8336e6f5a064 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -1,45 +1,50 @@ -test_isCreateServer -| createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_RequestInputAccess -| src/http.js:6:26:6:32 | req.url | url | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:8:3:8:20 | req.headers.cookie | cookie | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:9:3:9:17 | req.headers.foo | header | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/https.js:6:26:6:32 | req.url | url | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:8:3:8:20 | req.headers.cookie | cookie | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:9:3:9:17 | req.headers.foo | header | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/indirect.js:17:28:17:34 | req.url | url | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -test_RouteHandler_getAResponseHeader -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | location | src/http.js:7:3:7:42 | res.wri ... rget }) | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | -test_HeaderDefinition_defines -| src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | -| src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html | -| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | application/json | -test_SystemCommandExecution -| es6-imported-exec.js:3:1:3:11 | exec("cmd") | es6-imported-exec.js:3:6:3:10 | "cmd" | -| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:13:3:18 | "node" | -| exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:17:4:20 | "sh" | -| exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:9:5:13 | "foo" | -| exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:10:6:15 | "echo" | -| exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:14:7:19 | "echo" | +test_Credentials +| src/http.js:18:22:18:27 | "auth" | credentials | +| src/https.js:18:23:18:28 | "auth" | credentials | +test_RequestExpr +| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} | +| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} | +| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } | +| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:9:3:9:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:12:28:12:30 | req | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:55:21:55:23 | req | src/http.js:55:12:55:30 | function(req,res){} | +| src/http.js:60:23:60:25 | req | src/http.js:60:14:60:32 | function(req,res){} | +| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() | +| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:28:24:28:26 | req | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +test_HeaderAccess +| src/http.js:9:3:9:17 | req.headers.foo | foo | +| src/https.js:9:3:9:17 | req.headers.foo | foo | test_ResponseExpr | createServer.js:2:35:2:37 | res | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:38:3:40 | res | createServer.js:3:23:3:44 | functio ... res) {} | @@ -101,6 +106,47 @@ test_ResponseExpr | src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | | src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | | src/indirect.js:29:5:29:7 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +test_RouteHandler +| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +test_ClientRequest +| http.js:2:1:2:56 | http.re ... fined)) | +| src/http.js:18:1:18:30 | http.re ... uth" }) | +| src/http.js:21:15:26:6 | http.re ... \\n }) | +| src/http.js:27:16:27:73 | http.re ... POST'}) | +| src/https.js:18:1:18:31 | https.r ... uth" }) | +test_isCreateServer +| createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | test_HeaderDefinition | src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:13:3:13:44 | res.set ... /html') | src/http.js:12:19:16:1 | functio ... ar");\\n} | @@ -109,34 +155,6 @@ test_HeaderDefinition | src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -test_RouteSetup_getServer -| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_ClientRequest -| http.js:2:1:2:56 | http.re ... fined)) | -| src/http.js:18:1:18:30 | http.re ... uth" }) | -| src/http.js:21:15:26:6 | http.re ... \\n }) | -| src/http.js:27:16:27:73 | http.re ... POST'}) | -| src/https.js:18:1:18:31 | https.r ... uth" }) | -test_HeaderDefinition_getAHeaderName -| src/http.js:7:3:7:42 | res.wri ... rget }) | location | -| src/http.js:13:3:13:44 | res.set ... /html') | content-type | -| src/https.js:7:3:7:42 | res.wri ... rget }) | location | -| src/https.js:13:3:13:44 | res.set ... /html') | content-type | -| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | test_ServerDefinition | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:1:3:45 | https.c ... es) {}) | @@ -153,9 +171,106 @@ test_ServerDefinition | src/https.js:12:1:16:2 | https.c ... r");\\n}) | | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_HeaderAccess -| src/http.js:9:3:9:17 | req.headers.foo | foo | -| src/https.js:9:3:9:17 | req.headers.foo | foo | +test_RemoteFlowSources +| createServer.js:7:24:7:27 | data | +| createServer.js:14:24:14:27 | data | +| src/http.js:6:26:6:32 | req.url | +| src/http.js:8:3:8:20 | req.headers.cookie | +| src/http.js:9:3:9:17 | req.headers.foo | +| src/http.js:29:26:29:33 | response | +| src/http.js:30:28:30:32 | chunk | +| src/http.js:40:23:40:30 | authInfo | +| src/http.js:45:23:45:27 | error | +| src/http.js:63:17:63:33 | req.query.myParam | +| src/http.js:73:18:73:22 | chunk | +| src/http.js:82:18:82:22 | chunk | +| src/https.js:6:26:6:32 | req.url | +| src/https.js:8:3:8:20 | req.headers.cookie | +| src/https.js:9:3:9:17 | req.headers.foo | +| src/indirect2.js:10:12:10:25 | req.params.key | +| src/indirect.js:17:28:17:34 | req.url | +test_RequestInputAccess +| src/http.js:6:26:6:32 | req.url | url | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:8:3:8:20 | req.headers.cookie | cookie | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:9:3:9:17 | req.headers.foo | header | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/https.js:6:26:6:32 | req.url | url | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:8:3:8:20 | req.headers.cookie | cookie | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:9:3:9:17 | req.headers.foo | header | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/indirect.js:17:28:17:34 | req.url | url | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +test_ResponseSendArgument +| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } | +| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:85:11:85:15 | "bla" | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/https.js:14:13:14:17 | "foo" | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/https.js:15:11:15:15 | "bar" | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect.js:26:13:26:17 | "foo" | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:29:13:29:17 | "bar" | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +test_RouteSetup_getServer +| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +test_SystemCommandExecution +| es6-imported-exec.js:3:1:3:11 | exec("cmd") | es6-imported-exec.js:3:6:3:10 | "cmd" | +| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:13:3:18 | "node" | +| exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:17:4:20 | "sh" | +| exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:9:5:13 | "foo" | +| exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:10:6:15 | "echo" | +| exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:14:7:19 | "echo" | +| exec.js:10:14:10:58 | 'data:t ... lo!");' | exec.js:10:14:10:58 | 'data:t ... lo!");' | +test_HeaderDefinition_defines +| src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | +| src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html | +| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | application/json | +test_ClientRequest_getADataNode +| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:50:16:50:22 | 'stuff' | +| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:51:14:51:25 | 'more stuff' | +test_RouteSetup_getARouteHandler +| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | +| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:54:1:56:1 | return of function getHandler | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:19:57:30 | getHandler() | +| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:14:60:32 | function(req,res){} | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:67:1:69:1 | return of function getArrowHandler | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:19:70:35 | getArrowHandler() | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:10:3:10:40 | handler ... Case()] | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:14:19:21:3 | return of method requestHandler | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:16 | functio ... d(this) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:21:17:35 | routes[req.url] | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:40:17:50 | routes['*'] | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:32:34:57 | appServ ... ndler() | test_HeaderDefinition_getNameExpr | src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:7:17:7:19 | 302 | | src/http.js:13:3:13:44 | res.set ... /html') | src/http.js:13:17:13:30 | 'Content-Type' | @@ -163,6 +278,47 @@ test_HeaderDefinition_getNameExpr | src/https.js:7:3:7:42 | res.wri ... rget }) | src/https.js:7:17:7:19 | 302 | | src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:13:17:13:30 | 'Content-Type' | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:14:17:14:30 | 'Content-Type' | +test_RouteHandler_getARequestExpr +| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req | +| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req | +| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req | +| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:9:3:9:5 | req | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:28:12:30 | req | +| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:21:55:23 | req | +| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:23:60:25 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req | +| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82:5 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req | +| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req | +| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:24:28:26 | req | test_RouteHandler_getAResponseExpr | createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:35:2:37 | res | | createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res | @@ -224,6 +380,19 @@ test_RouteHandler_getAResponseExpr | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:29:5:29:7 | res | +test_HeaderDefinition_getAHeaderName +| src/http.js:7:3:7:42 | res.wri ... rget }) | location | +| src/http.js:13:3:13:44 | res.set ... /html') | content-type | +| src/https.js:7:3:7:42 | res.wri ... rget }) | location | +| src/https.js:13:3:13:44 | res.set ... /html') | content-type | +| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | +test_RouteHandler_getAResponseHeader +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | location | src/http.js:7:3:7:42 | res.wri ... rget }) | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | test_ServerDefinition_getARouteHandler | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | @@ -243,177 +412,9 @@ test_ServerDefinition_getARouteHandler | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -test_ResponseSendArgument -| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } | -| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:85:11:85:15 | "bla" | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/https.js:14:13:14:17 | "foo" | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/https.js:15:11:15:15 | "bar" | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect.js:26:13:26:17 | "foo" | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:29:13:29:17 | "bar" | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -test_RouteSetup_getARouteHandler -| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | -| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | -| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:54:1:56:1 | return of function getHandler | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:19:57:30 | getHandler() | -| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:14:60:32 | function(req,res){} | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:67:1:69:1 | return of function getArrowHandler | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:19:70:35 | getArrowHandler() | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:10:3:10:40 | handler ... Case()] | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:14:19:21:3 | return of method requestHandler | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:16 | functio ... d(this) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:21:17:35 | routes[req.url] | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:40:17:50 | routes['*'] | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:32:34:57 | appServ ... ndler() | -test_ClientRequest_getADataNode -| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:50:16:50:22 | 'stuff' | -| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:51:14:51:25 | 'more stuff' | -test_RemoteFlowSources -| createServer.js:7:24:7:27 | data | -| createServer.js:14:24:14:27 | data | -| src/http.js:6:26:6:32 | req.url | -| src/http.js:8:3:8:20 | req.headers.cookie | -| src/http.js:9:3:9:17 | req.headers.foo | -| src/http.js:29:26:29:33 | response | -| src/http.js:30:28:30:32 | chunk | -| src/http.js:40:23:40:30 | authInfo | -| src/http.js:45:23:45:27 | error | -| src/http.js:63:17:63:33 | req.query.myParam | -| src/http.js:73:18:73:22 | chunk | -| src/http.js:82:18:82:22 | chunk | -| src/https.js:6:26:6:32 | req.url | -| src/https.js:8:3:8:20 | req.headers.cookie | -| src/https.js:9:3:9:17 | req.headers.foo | -| src/indirect2.js:10:12:10:25 | req.params.key | -| src/indirect.js:17:28:17:34 | req.url | -test_RouteHandler -| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_RequestExpr -| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} | -| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} | -| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} | -| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } | -| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:9:3:9:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:12:28:12:30 | req | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:55:21:55:23 | req | src/http.js:55:12:55:30 | function(req,res){} | -| src/http.js:60:23:60:25 | req | src/http.js:60:14:60:32 | function(req,res){} | -| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() | -| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:28:24:28:26 | req | src/indirect.js:28:15:30:3 | functio ... ");\\n } | test_SystemCommandExecution_getAnArgumentForCommand | exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:21:3:33 | ["--version"] | | exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:23:4:46 | ["-c", ... rsion"] | | exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:16:5:22 | ["arg"] | | exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:18:6:23 | ["Hi"] | | exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:22:7:36 | ["Hi", "there"] | -test_Credentials -| src/http.js:18:22:18:27 | "auth" | credentials | -| src/https.js:18:23:18:28 | "auth" | credentials | -test_RouteHandler_getARequestExpr -| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req | -| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req | -| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req | -| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:9:3:9:5 | req | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:28:12:30 | req | -| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:21:55:23 | req | -| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:23:60:25 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req | -| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82:5 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req | -| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req | -| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:24:28:26 | req | From 344869f0d7605530a184c2088f449b000ad5609b Mon Sep 17 00:00:00 2001 From: amammad Date: Fri, 22 Sep 2023 19:37:17 +1000 Subject: [PATCH 02/14] change commandExecution sink to CodeInjection sink --- .../ql/lib/semmle/javascript/frameworks/NodeJSLib.qll | 11 ++--------- .../frameworks/NodeJSLib/CodeInjectionSink.qll | 4 ++++ .../library-tests/frameworks/NodeJSLib/tests.expected | 3 ++- .../test/library-tests/frameworks/NodeJSLib/tests.ql | 1 + 4 files changed, 9 insertions(+), 10 deletions(-) create mode 100644 javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 9996c4fe2261..4d7a549e3473 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -6,6 +6,7 @@ import javascript import semmle.javascript.frameworks.HTTP import semmle.javascript.security.SensitiveActions private import semmle.javascript.dataflow.internal.PreCallGraphStep +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations module NodeJSLib { private GlobalVariable processVariable() { variables(result, "process", any(GlobalScope sc)) } @@ -763,16 +764,8 @@ module NodeJSLib { /** * The dynamic import expression input can be a `data:` URL which loads any module from that data */ - class DynamicImport extends SystemCommandExecution, DataFlow::ExprNode { + class DynamicImport extends CodeInjection::Sink, DataFlow::ExprNode { DynamicImport() { this = any(DynamicImportExpr e).getAChildExpr().flow() } - - override DataFlow::Node getACommandArgument() { result = this } - - override predicate isShellInterpreted(DataFlow::Node arg) { arg = this } - - override predicate isSync() { none() } - - override DataFlow::Node getOptionsArg() { none() } } /** diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll new file mode 100644 index 000000000000..7d6aa0c51585 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll @@ -0,0 +1,4 @@ +import javascript +private import semmle.javascript.security.dataflow.CodeInjectionCustomizations + +query predicate test_CodeInjectionSink(CodeInjection::Sink cmd, DataFlow::Node res) { res = cmd } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index 8336e6f5a064..a833ae57a3de 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -230,7 +230,6 @@ test_SystemCommandExecution | exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:9:5:13 | "foo" | | exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:10:6:15 | "echo" | | exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:14:7:19 | "echo" | -| exec.js:10:14:10:58 | 'data:t ... lo!");' | exec.js:10:14:10:58 | 'data:t ... lo!");' | test_HeaderDefinition_defines | src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | | src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html | @@ -418,3 +417,5 @@ test_SystemCommandExecution_getAnArgumentForCommand | exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:16:5:22 | ["arg"] | | exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:18:6:23 | ["Hi"] | | exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:22:7:36 | ["Hi", "there"] | +test_CodeInjectionSink +| exec.js:10:14:10:58 | 'data:t ... lo!");' | exec.js:10:14:10:58 | 'data:t ... lo!");' | diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql index cfba5635a598..5b56102df403 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql @@ -22,3 +22,4 @@ import RequestExpr import SystemCommandExecution_getAnArgumentForCommand import Credentials import RouteHandler_getARequestExpr +import CodeInjectionSink From f6737b3d906e53ac03658df97ad73d008282064f Mon Sep 17 00:00:00 2001 From: amammad Date: Mon, 25 Sep 2023 21:09:19 +1000 Subject: [PATCH 03/14] fix FP --- javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 4d7a549e3473..f1186068b765 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -765,7 +765,7 @@ module NodeJSLib { * The dynamic import expression input can be a `data:` URL which loads any module from that data */ class DynamicImport extends CodeInjection::Sink, DataFlow::ExprNode { - DynamicImport() { this = any(DynamicImportExpr e).getAChildExpr().flow() } + DynamicImport() { this = any(DynamicImportExpr e).getSource().flow() } } /** From 921198ed307270159175afdd5bd3e30c7115d5f1 Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Thu, 28 Sep 2023 03:39:29 +1000 Subject: [PATCH 04/14] add separate query for sinks that accepts data: URL --- .vscode/settings.json | 5 - .../javascript/frameworks/NodeJSLib.qll | 7 - .../CWE-094-dataURL/CodeInjection.inc.qhelp | 48 ++ .../CWE-094-dataURL/CodeInjection.qhelp | 6 + .../Security/CWE-094-dataURL/CodeInjection.ql | 98 ++++ .../CWE-094-dataURL/examples/CodeInjection.js | 14 + .../CWE-094-dataURL/CodeInjection.expected | 14 + .../CWE-094-dataURL/CodeInjection.qlref | 1 + .../Security/CWE-094-dataURL/test.js | 26 + .../NodeJSLib/CodeInjectionSink.qll | 4 - .../frameworks/NodeJSLib/exec.js | 3 - .../frameworks/NodeJSLib/tests.expected | 484 +++++++++--------- .../frameworks/NodeJSLib/tests.ql | 1 - 13 files changed, 448 insertions(+), 263 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.inc.qhelp create mode 100644 javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.qhelp create mode 100644 javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql create mode 100644 javascript/ql/src/experimental/Security/CWE-094-dataURL/examples/CodeInjection.js create mode 100644 javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected create mode 100644 javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.qlref create mode 100644 javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js delete mode 100644 javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1050c79b825e..000000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "omnisharp.autoStart": false, - "cmake.sourceDirectory": "${workspaceFolder}/swift", - "cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build" -} diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index f1186068b765..ed00477a2366 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -761,13 +761,6 @@ module NodeJSLib { } } - /** - * The dynamic import expression input can be a `data:` URL which loads any module from that data - */ - class DynamicImport extends CodeInjection::Sink, DataFlow::ExprNode { - DynamicImport() { this = any(DynamicImportExpr e).getSource().flow() } - } - /** * A call to a method from module `child_process`. */ diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.inc.qhelp b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.inc.qhelp new file mode 100644 index 000000000000..39c02a629056 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.inc.qhelp @@ -0,0 +1,48 @@ + + + + +

+Directly evaluating user input (for example, an HTTP request parameter) as code without properly +sanitizing the input first allows an attacker arbitrary code execution. This can occur when user +input is treated as JavaScript, or passed to a framework which interprets it as an expression to be +evaluated. Examples include AngularJS expressions or JQuery selectors. +

+
+ + +

+Avoid including user input in any expression which may be dynamically evaluated. If user input must +be included, use context-specific escaping before +including it. It is important that the correct escaping is used for the type of evaluation that will +occur. +

+
+ + +

+The following example shows part of the page URL being evaluated as JavaScript code on the server. This allows an +attacker to provide JavaScript within the URL and send it to server. client side attacks need victim users interaction +like clicking on a attacker provided URL. +

+ + + +
+ + +
  • +OWASP: +Code Injection. +
  • +
  • +Wikipedia: Code Injection. +
  • +
  • +PortSwigger Research Blog: +Server-Side Template Injection. +
  • +
    +
    diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.qhelp b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.qhelp new file mode 100644 index 000000000000..784368354731 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.qhelp @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql new file mode 100644 index 000000000000..76907f6ea145 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -0,0 +1,98 @@ +/** + * @name Code injection + * @description Interpreting unsanitized user input as code allows a malicious user arbitrary + * code execution. + * @kind path-problem + * @problem.severity error + * @security-severity 9.3 + * @precision high + * @id js/code-injection + * @tags security + * external/cwe/cwe-094 + * external/cwe/cwe-095 + * external/cwe/cwe-079 + * external/cwe/cwe-116 + */ + +import javascript +import DataFlow +import DataFlow::PathGraph + +abstract class Sanitizer extends DataFlow::Node { } + +abstract class Sink extends DataFlow::Node { } + +/** A non-first leaf in a string-concatenation. Seen as a sanitizer for dynamic import code injection. */ +class NonFirstStringConcatLeaf extends Sanitizer { + NonFirstStringConcatLeaf() { + exists(StringOps::ConcatenationRoot root | + this = root.getALeaf() and + not this = root.getFirstLeaf() + ) + or + exists(DataFlow::CallNode join | + join = DataFlow::moduleMember("path", "join").getACall() and + this = join.getArgument([1 .. join.getNumArgument() - 1]) + ) + } +} + +/** + * The dynamic import expression input can be a `data:` URL which loads any module from that data + */ +class DynamicImport extends DataFlow::ExprNode { + DynamicImport() { this = any(DynamicImportExpr e).getSource().flow() } +} + +/** + * The dynamic import expression input can be a `data:` URL which loads any module from that data + */ +class WorkerThreads extends DataFlow::Node { + WorkerThreads() { + this = API::moduleImport("node:worker_threads").getMember("Worker").getParameter(0).asSink() + } +} + +class WorkerThreadsLabel extends FlowLabel { + WorkerThreadsLabel() { this = "worker_threads" } +} + +class DynamicImportLabel extends FlowLabel { + DynamicImportLabel() { this = "DynamicImport" } +} + +/** + * A taint-tracking configuration for reasoning about code injection vulnerabilities. + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "CodeInjection" } + + override predicate isSource(DataFlow::Node source, FlowLabel label) { + source instanceof RemoteFlowSource and + (label instanceof DynamicImportLabel or label instanceof WorkerThreadsLabel) + } + + override predicate isSink(DataFlow::Node sink, FlowLabel label) { + sink instanceof DynamicImport and label instanceof DynamicImportLabel + or + sink instanceof WorkerThreads and label instanceof WorkerThreadsLabel + } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + + override predicate isAdditionalFlowStep( + DataFlow::Node pred, DataFlow::Node succ, FlowLabel predlbl, FlowLabel succlbl + ) { + exists(DataFlow::NewNode newUrl | succ = newUrl | + newUrl = DataFlow::globalVarRef("URL").getAnInstantiation() and + pred = newUrl.getArgument(0) + ) and + predlbl instanceof WorkerThreadsLabel and + succlbl instanceof WorkerThreadsLabel + } +} + +from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink +where cfg.hasFlowPath(source, sink) +select sink.getNode(), source, sink, sink.getNode() + " depends on a $@.", source.getNode(), + "user-provided value" diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/examples/CodeInjection.js b/javascript/ql/src/experimental/Security/CWE-094-dataURL/examples/CodeInjection.js new file mode 100644 index 000000000000..743b4e0d65d0 --- /dev/null +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/examples/CodeInjection.js @@ -0,0 +1,14 @@ +const { Worker } = require('node:worker_threads'); +var app = require('express')(); + +app.post('/path', async function (req, res) { + const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' + const payloadURL = new URL(payload) + new Worker(payloadURL); +}); + +app.post('/path2', async function (req, res) { + const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' + await import(payload) +}); + diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected new file mode 100644 index 000000000000..62fd4fd296a2 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected @@ -0,0 +1,14 @@ +WARNING: Unused class Sink (/home/am/CodeQL-home/codeql-repo-amammad/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql:23,16-20) +nodes +| test.js:18:11:18:44 | payload | +| test.js:18:21:18:44 | req.que ... rameter | +| test.js:18:21:18:44 | req.que ... rameter | +| test.js:20:18:20:24 | payload | +| test.js:20:18:20:24 | payload | +edges +| test.js:18:11:18:44 | payload | test.js:20:18:20:24 | payload | +| test.js:18:11:18:44 | payload | test.js:20:18:20:24 | payload | +| test.js:18:21:18:44 | req.que ... rameter | test.js:18:11:18:44 | payload | +| test.js:18:21:18:44 | req.que ... rameter | test.js:18:11:18:44 | payload | +#select +| test.js:20:18:20:24 | payload | test.js:18:21:18:44 | req.que ... rameter | test.js:20:18:20:24 | payload | payload depends on a $@. | test.js:18:21:18:44 | req.que ... rameter | user-provided value | diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.qlref b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.qlref new file mode 100644 index 000000000000..3caf7ab7b43b --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.qlref @@ -0,0 +1 @@ +experimental/Security/CWE-094-dataURL/CodeInjection.ql \ No newline at end of file diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js b/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js new file mode 100644 index 000000000000..b0ead7aa9b51 --- /dev/null +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js @@ -0,0 +1,26 @@ +const { Worker } = require('node:worker_threads'); +var app = require('express')(); + +app.post('/path', async function (req, res) { + const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' + let payloadURL = new URL(payload + sth) + // NOT OK + new Worker(payloadURL); + // NOT OK + payloadURL = new URL(payload + sth) + new Worker(payloadURL); + // OK + payloadURL = new URL(sth + payload) + new Worker(payloadURL); +}); + +app.post('/path2', async function (req, res) { + const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' + // NOT OK + await import(payload) + // NOT OK + await import(payload + sth) + // OK + await import(sth + payload) +}); + diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll b/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll deleted file mode 100644 index 7d6aa0c51585..000000000000 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/CodeInjectionSink.qll +++ /dev/null @@ -1,4 +0,0 @@ -import javascript -private import semmle.javascript.security.dataflow.CodeInjectionCustomizations - -query predicate test_CodeInjectionSink(CodeInjection::Sink cmd, DataFlow::Node res) { res = cmd } diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js b/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js index 8a3bf9d6da47..d22f0bb760d8 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/exec.js @@ -5,6 +5,3 @@ cp.execFileSync("sh", ["-c", "node --version"]); cp.fork("foo", ["arg"]); cp.spawn("echo", ["Hi"], cb); cp.spawnSync("echo", ["Hi", "there"]); - -// dynamic import -await import('data:text/javascript,console.log("hello!");') \ No newline at end of file diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected index a833ae57a3de..78c2c35309ff 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.expected @@ -1,50 +1,45 @@ -test_Credentials -| src/http.js:18:22:18:27 | "auth" | credentials | -| src/https.js:18:23:18:28 | "auth" | credentials | -test_RequestExpr -| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} | -| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} | -| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} | -| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } | -| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:9:3:9:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:12:28:12:30 | req | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:55:21:55:23 | req | src/http.js:55:12:55:30 | function(req,res){} | -| src/http.js:60:23:60:25 | req | src/http.js:60:14:60:32 | function(req,res){} | -| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() | -| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:28:24:28:26 | req | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -test_HeaderAccess -| src/http.js:9:3:9:17 | req.headers.foo | foo | -| src/https.js:9:3:9:17 | req.headers.foo | foo | +test_isCreateServer +| createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | +test_RequestInputAccess +| src/http.js:6:26:6:32 | req.url | url | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:8:3:8:20 | req.headers.cookie | cookie | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:9:3:9:17 | req.headers.foo | header | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/https.js:6:26:6:32 | req.url | url | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:8:3:8:20 | req.headers.cookie | cookie | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:9:3:9:17 | req.headers.foo | header | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/indirect.js:17:28:17:34 | req.url | url | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +test_RouteHandler_getAResponseHeader +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | location | src/http.js:7:3:7:42 | res.wri ... rget }) | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | +test_HeaderDefinition_defines +| src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | +| src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html | +| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | application/json | +test_SystemCommandExecution +| es6-imported-exec.js:3:1:3:11 | exec("cmd") | es6-imported-exec.js:3:6:3:10 | "cmd" | +| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:13:3:18 | "node" | +| exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:17:4:20 | "sh" | +| exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:9:5:13 | "foo" | +| exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:10:6:15 | "echo" | +| exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:14:7:19 | "echo" | test_ResponseExpr | createServer.js:2:35:2:37 | res | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:38:3:40 | res | createServer.js:3:23:3:44 | functio ... res) {} | @@ -106,47 +101,6 @@ test_ResponseExpr | src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | | src/indirect.js:28:29:28:31 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | | src/indirect.js:29:5:29:7 | res | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -test_RouteHandler -| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_ClientRequest -| http.js:2:1:2:56 | http.re ... fined)) | -| src/http.js:18:1:18:30 | http.re ... uth" }) | -| src/http.js:21:15:26:6 | http.re ... \\n }) | -| src/http.js:27:16:27:73 | http.re ... POST'}) | -| src/https.js:18:1:18:31 | https.r ... uth" }) | -test_isCreateServer -| createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | test_HeaderDefinition | src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | | src/http.js:13:3:13:44 | res.set ... /html') | src/http.js:12:19:16:1 | functio ... ar");\\n} | @@ -155,58 +109,6 @@ test_HeaderDefinition | src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:12:20:16:1 | functio ... ar");\\n} | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -test_ServerDefinition -| createServer.js:2:1:2:42 | https.c ... es) {}) | -| createServer.js:3:1:3:45 | https.c ... es) {}) | -| createServer.js:4:1:4:47 | require ... => {}) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | -| src/http.js:57:1:57:31 | http.cr ... dler()) | -| src/http.js:60:1:60:33 | createS ... res){}) | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | -| src/http.js:70:1:70:36 | http.cr ... dler()) | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_RemoteFlowSources -| createServer.js:7:24:7:27 | data | -| createServer.js:14:24:14:27 | data | -| src/http.js:6:26:6:32 | req.url | -| src/http.js:8:3:8:20 | req.headers.cookie | -| src/http.js:9:3:9:17 | req.headers.foo | -| src/http.js:29:26:29:33 | response | -| src/http.js:30:28:30:32 | chunk | -| src/http.js:40:23:40:30 | authInfo | -| src/http.js:45:23:45:27 | error | -| src/http.js:63:17:63:33 | req.query.myParam | -| src/http.js:73:18:73:22 | chunk | -| src/http.js:82:18:82:22 | chunk | -| src/https.js:6:26:6:32 | req.url | -| src/https.js:8:3:8:20 | req.headers.cookie | -| src/https.js:9:3:9:17 | req.headers.foo | -| src/indirect2.js:10:12:10:25 | req.params.key | -| src/indirect.js:17:28:17:34 | req.url | -test_RequestInputAccess -| src/http.js:6:26:6:32 | req.url | url | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:8:3:8:20 | req.headers.cookie | cookie | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:9:3:9:17 | req.headers.foo | header | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/https.js:6:26:6:32 | req.url | url | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:8:3:8:20 | req.headers.cookie | cookie | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:9:3:9:17 | req.headers.foo | header | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/indirect.js:17:28:17:34 | req.url | url | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -test_ResponseSendArgument -| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } | -| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:85:11:85:15 | "bla" | src/http.js:81:22:86:1 | functio ... la");\\n} | -| src/https.js:14:13:14:17 | "foo" | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/https.js:15:11:15:15 | "bar" | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect.js:26:13:26:17 | "foo" | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:29:13:29:17 | "bar" | src/indirect.js:28:15:30:3 | functio ... ");\\n } | test_RouteSetup_getServer | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:1:2:42 | https.c ... es) {}) | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:1:3:45 | https.c ... es) {}) | @@ -223,53 +125,37 @@ test_RouteSetup_getServer | src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:1:16:2 | https.c ... r");\\n}) | | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:14:34:58 | http.cr ... dler()) | -test_SystemCommandExecution -| es6-imported-exec.js:3:1:3:11 | exec("cmd") | es6-imported-exec.js:3:6:3:10 | "cmd" | -| exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:13:3:18 | "node" | -| exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:17:4:20 | "sh" | -| exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:9:5:13 | "foo" | -| exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:10:6:15 | "echo" | -| exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:14:7:19 | "echo" | -test_HeaderDefinition_defines -| src/http.js:13:3:13:44 | res.set ... /html') | content-type | text/html | -| src/https.js:13:3:13:44 | res.set ... /html') | content-type | text/html | -| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | application/json | -test_ClientRequest_getADataNode -| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:50:16:50:22 | 'stuff' | -| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:51:14:51:25 | 'more stuff' | -test_RouteSetup_getARouteHandler -| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | -| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | -| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } | -| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() | -| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | -| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:54:1:56:1 | return of function getHandler | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | -| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:19:57:30 | getHandler() | -| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:14:60:32 | function(req,res){} | -| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:19:65:1 | functio ... r2");\\n} | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:67:1:69:1 | return of function getArrowHandler | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() | -| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:19:70:35 | getArrowHandler() | -| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} | -| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} | -| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:10:3:10:40 | handler ... Case()] | -| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:14:19:21:3 | return of method requestHandler | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:16 | functio ... d(this) | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:21:17:35 | routes[req.url] | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:40:17:50 | routes['*'] | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | -| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:32:34:57 | appServ ... ndler() | +test_ClientRequest +| http.js:2:1:2:56 | http.re ... fined)) | +| src/http.js:18:1:18:30 | http.re ... uth" }) | +| src/http.js:21:15:26:6 | http.re ... \\n }) | +| src/http.js:27:16:27:73 | http.re ... POST'}) | +| src/https.js:18:1:18:31 | https.r ... uth" }) | +test_HeaderDefinition_getAHeaderName +| src/http.js:7:3:7:42 | res.wri ... rget }) | location | +| src/http.js:13:3:13:44 | res.set ... /html') | content-type | +| src/https.js:7:3:7:42 | res.wri ... rget }) | location | +| src/https.js:13:3:13:44 | res.set ... /html') | content-type | +| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | +test_ServerDefinition +| createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | +test_HeaderAccess +| src/http.js:9:3:9:17 | req.headers.foo | foo | +| src/https.js:9:3:9:17 | req.headers.foo | foo | test_HeaderDefinition_getNameExpr | src/http.js:7:3:7:42 | res.wri ... rget }) | src/http.js:7:17:7:19 | 302 | | src/http.js:13:3:13:44 | res.set ... /html') | src/http.js:13:17:13:30 | 'Content-Type' | @@ -277,47 +163,6 @@ test_HeaderDefinition_getNameExpr | src/https.js:7:3:7:42 | res.wri ... rget }) | src/https.js:7:17:7:19 | 302 | | src/https.js:13:3:13:44 | res.set ... /html') | src/https.js:13:17:13:30 | 'Content-Type' | | src/indirect2.js:14:3:14:51 | res.set ... /json') | src/indirect2.js:14:17:14:30 | 'Content-Type' | -test_RouteHandler_getARequestExpr -| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req | -| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req | -| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req | -| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req | -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:9:3:9:5 | req | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:28:12:30 | req | -| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:21:55:23 | req | -| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:23:60:25 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | -| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req | -| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | -| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | -| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82:5 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | -| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req | -| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req | -| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:24:28:26 | req | test_RouteHandler_getAResponseExpr | createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:35:2:37 | res | | createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:38:3:40 | res | @@ -379,19 +224,6 @@ test_RouteHandler_getAResponseExpr | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:29:28:31 | res | | src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:29:5:29:7 | res | -test_HeaderDefinition_getAHeaderName -| src/http.js:7:3:7:42 | res.wri ... rget }) | location | -| src/http.js:13:3:13:44 | res.set ... /html') | content-type | -| src/https.js:7:3:7:42 | res.wri ... rget }) | location | -| src/https.js:13:3:13:44 | res.set ... /html') | content-type | -| src/indirect2.js:14:3:14:51 | res.set ... /json') | content-type | -test_RouteHandler_getAResponseHeader -| src/http.js:4:32:10:1 | functio ... .foo;\\n} | location | src/http.js:7:3:7:42 | res.wri ... rget }) | -| src/http.js:12:19:16:1 | functio ... ar");\\n} | content-type | src/http.js:13:3:13:44 | res.set ... /html') | -| src/https.js:4:33:10:1 | functio ... .foo;\\n} | location | src/https.js:7:3:7:42 | res.wri ... rget }) | -| src/https.js:12:20:16:1 | functio ... ar");\\n} | content-type | src/https.js:13:3:13:44 | res.set ... /html') | -| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | -| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | content-type | src/indirect2.js:14:3:14:51 | res.set ... /json') | test_ServerDefinition_getARouteHandler | createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | | createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | @@ -411,11 +243,177 @@ test_ServerDefinition_getARouteHandler | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | | src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +test_ResponseSendArgument +| createServer.js:26:17:26:25 | this.data | createServer.js:25:37:27:5 | functio ... ;\\n } | +| src/http.js:14:13:14:17 | "foo" | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:15:11:15:15 | "bar" | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:64:11:64:16 | "bar2" | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:85:11:85:15 | "bla" | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/https.js:14:13:14:17 | "foo" | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/https.js:15:11:15:15 | "bar" | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect.js:26:13:26:17 | "foo" | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:29:13:29:17 | "bar" | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +test_RouteSetup_getARouteHandler +| createServer.js:2:1:2:42 | https.c ... es) {}) | createServer.js:2:20:2:41 | functio ... res) {} | +| createServer.js:3:1:3:45 | https.c ... es) {}) | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:1:4:47 | require ... => {}) | createServer.js:4:31:4:46 | (req, res) => {} | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:22:41:24:5 | return of anonymous function | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:33 | this.handleRequest | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:23:16:23:44 | this.ha ... d(this) | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:25:37:27:5 | functio ... ;\\n } | +| createServer.js:31:17:31:58 | http.cr ... dler()) | createServer.js:31:35:31:57 | app.get ... ndler() | +| src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:12:1:16:2 | http.cr ... r");\\n}) | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:54:1:56:1 | return of function getHandler | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:55:12:55:30 | function(req,res){} | +| src/http.js:57:1:57:31 | http.cr ... dler()) | src/http.js:57:19:57:30 | getHandler() | +| src/http.js:60:1:60:33 | createS ... res){}) | src/http.js:60:14:60:32 | function(req,res){} | +| src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:67:1:69:1 | return of function getArrowHandler | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:68:12:68:27 | (req,res) => f() | +| src/http.js:70:1:70:36 | http.cr ... dler()) | src/http.js:70:19:70:35 | getArrowHandler() | +| src/http.js:72:1:76:2 | http.cr ... })\\n}) | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/https.js:4:14:10:2 | https.c ... foo;\\n}) | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:12:1:16:2 | https.c ... r");\\n}) | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:10:3:10:40 | handler ... Case()] | +| src/indirect2.js:18:14:18:35 | http.cr ... er(get) | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:14:19:21:3 | return of method requestHandler | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:16:12:20:16 | functio ... d(this) | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:21:17:35 | routes[req.url] | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:17:40:17:50 | routes['*'] | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:28:15:30:3 | functio ... ");\\n } | +| src/indirect.js:34:14:34:58 | http.cr ... dler()) | src/indirect.js:34:32:34:57 | appServ ... ndler() | +test_ClientRequest_getADataNode +| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:50:16:50:22 | 'stuff' | +| src/http.js:27:16:27:73 | http.re ... POST'}) | src/http.js:51:14:51:25 | 'more stuff' | +test_RemoteFlowSources +| createServer.js:7:24:7:27 | data | +| createServer.js:14:24:14:27 | data | +| src/http.js:6:26:6:32 | req.url | +| src/http.js:8:3:8:20 | req.headers.cookie | +| src/http.js:9:3:9:17 | req.headers.foo | +| src/http.js:29:26:29:33 | response | +| src/http.js:30:28:30:32 | chunk | +| src/http.js:40:23:40:30 | authInfo | +| src/http.js:45:23:45:27 | error | +| src/http.js:63:17:63:33 | req.query.myParam | +| src/http.js:73:18:73:22 | chunk | +| src/http.js:82:18:82:22 | chunk | +| src/https.js:6:26:6:32 | req.url | +| src/https.js:8:3:8:20 | req.headers.cookie | +| src/https.js:9:3:9:17 | req.headers.foo | +| src/indirect2.js:10:12:10:25 | req.params.key | +| src/indirect.js:17:28:17:34 | req.url | +test_RouteHandler +| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:1:2:42 | https.c ... es) {}) | +| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:1:3:45 | https.c ... es) {}) | +| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:1:4:47 | require ... => {}) | +| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:31:17:31:58 | http.cr ... dler()) | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:14:10:2 | http.cr ... foo;\\n}) | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:1:16:2 | http.cr ... r");\\n}) | +| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:57:1:57:31 | http.cr ... dler()) | +| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:1:60:33 | createS ... res){}) | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:1:65:2 | http.cr ... 2");\\n}) | +| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:70:1:70:36 | http.cr ... dler()) | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:1:76:2 | http.cr ... })\\n}) | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:14:10:2 | https.c ... foo;\\n}) | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:1:16:2 | https.c ... r");\\n}) | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:18:14:18:35 | http.cr ... er(get) | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:34:14:34:58 | http.cr ... dler()) | +test_RequestExpr +| createServer.js:2:30:2:32 | req | createServer.js:2:20:2:41 | functio ... res) {} | +| createServer.js:3:33:3:35 | req | createServer.js:3:23:3:44 | functio ... res) {} | +| createServer.js:4:32:4:34 | req | createServer.js:4:31:4:46 | (req, res) => {} | +| createServer.js:25:47:25:49 | req | createServer.js:25:37:27:5 | functio ... ;\\n } | +| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:4:41:4:43 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:6:26:6:28 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:8:3:8:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:9:3:9:5 | req | src/http.js:4:32:10:1 | functio ... .foo;\\n} | +| src/http.js:12:28:12:30 | req | src/http.js:12:19:16:1 | functio ... ar");\\n} | +| src/http.js:55:21:55:23 | req | src/http.js:55:12:55:30 | function(req,res){} | +| src/http.js:60:23:60:25 | req | src/http.js:60:14:60:32 | function(req,res){} | +| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:62:28:62:30 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:63:17:63:19 | req | src/http.js:62:19:65:1 | functio ... r2");\\n} | +| src/http.js:68:13:68:15 | req | src/http.js:68:12:68:27 | (req,res) => f() | +| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:72:29:72:31 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:73:3:73:5 | req | src/http.js:72:19:76:1 | functio ... \\n })\\n} | +| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:81:41:81:43 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/http.js:82:3:82:5 | req | src/http.js:81:22:86:1 | functio ... la");\\n} | +| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:4:42:4:44 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:6:26:6:28 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:8:3:8:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:9:3:9:5 | req | src/https.js:4:33:10:1 | functio ... .foo;\\n} | +| src/https.js:12:29:12:31 | req | src/https.js:12:20:16:1 | functio ... ar");\\n} | +| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:9:14:9:16 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:10:12:10:14 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:10:42:10:44 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:9:1:11:1 | functio ... res);\\n} | +| src/indirect2.js:13:28:13:30 | req | src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | +| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:16:21:16:23 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:17:28:17:30 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:19:33:19:35 | req | src/indirect.js:16:12:20:5 | functio ... ;\\n } | +| src/indirect.js:25:25:25:27 | req | src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | +| src/indirect.js:28:24:28:26 | req | src/indirect.js:28:15:30:3 | functio ... ");\\n } | test_SystemCommandExecution_getAnArgumentForCommand | exec.js:3:1:3:38 | cp.exec ... "], cb) | exec.js:3:21:3:33 | ["--version"] | | exec.js:4:1:4:47 | cp.exec ... sion"]) | exec.js:4:23:4:46 | ["-c", ... rsion"] | | exec.js:5:1:5:23 | cp.fork ... "arg"]) | exec.js:5:16:5:22 | ["arg"] | | exec.js:6:1:6:28 | cp.spaw ... "], cb) | exec.js:6:18:6:23 | ["Hi"] | | exec.js:7:1:7:37 | cp.spaw ... here"]) | exec.js:7:22:7:36 | ["Hi", "there"] | -test_CodeInjectionSink -| exec.js:10:14:10:58 | 'data:t ... lo!");' | exec.js:10:14:10:58 | 'data:t ... lo!");' | +test_Credentials +| src/http.js:18:22:18:27 | "auth" | credentials | +| src/https.js:18:23:18:28 | "auth" | credentials | +test_RouteHandler_getARequestExpr +| createServer.js:2:20:2:41 | functio ... res) {} | createServer.js:2:30:2:32 | req | +| createServer.js:3:23:3:44 | functio ... res) {} | createServer.js:3:33:3:35 | req | +| createServer.js:4:31:4:46 | (req, res) => {} | createServer.js:4:32:4:34 | req | +| createServer.js:25:37:27:5 | functio ... ;\\n } | createServer.js:25:47:25:49 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:4:41:4:43 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:6:26:6:28 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:8:3:8:5 | req | +| src/http.js:4:32:10:1 | functio ... .foo;\\n} | src/http.js:9:3:9:5 | req | +| src/http.js:12:19:16:1 | functio ... ar");\\n} | src/http.js:12:28:12:30 | req | +| src/http.js:55:12:55:30 | function(req,res){} | src/http.js:55:21:55:23 | req | +| src/http.js:60:14:60:32 | function(req,res){} | src/http.js:60:23:60:25 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:62:28:62:30 | req | +| src/http.js:62:19:65:1 | functio ... r2");\\n} | src/http.js:63:17:63:19 | req | +| src/http.js:68:12:68:27 | (req,res) => f() | src/http.js:68:13:68:15 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:72:29:72:31 | req | +| src/http.js:72:19:76:1 | functio ... \\n })\\n} | src/http.js:73:3:73:5 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:81:41:81:43 | req | +| src/http.js:81:22:86:1 | functio ... la");\\n} | src/http.js:82:3:82:5 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:4:42:4:44 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:6:26:6:28 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:8:3:8:5 | req | +| src/https.js:4:33:10:1 | functio ... .foo;\\n} | src/https.js:9:3:9:5 | req | +| src/https.js:12:20:16:1 | functio ... ar");\\n} | src/https.js:12:29:12:31 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:9:14:9:16 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:12:10:14 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:10:42:10:44 | req | +| src/indirect2.js:9:1:11:1 | functio ... res);\\n} | src/indirect2.js:13:28:13:30 | req | +| src/indirect2.js:13:1:16:1 | functio ... \\"");\\n} | src/indirect2.js:13:28:13:30 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:16:21:16:23 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:17:28:17:30 | req | +| src/indirect.js:16:12:20:5 | functio ... ;\\n } | src/indirect.js:19:33:19:35 | req | +| src/indirect.js:25:24:27:3 | (req, r ... ");\\n } | src/indirect.js:25:25:25:27 | req | +| src/indirect.js:28:15:30:3 | functio ... ");\\n } | src/indirect.js:28:24:28:26 | req | diff --git a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql index 5b56102df403..cfba5635a598 100644 --- a/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql +++ b/javascript/ql/test/library-tests/frameworks/NodeJSLib/tests.ql @@ -22,4 +22,3 @@ import RequestExpr import SystemCommandExecution_getAnArgumentForCommand import Credentials import RouteHandler_getARequestExpr -import CodeInjectionSink From 75f0fc4a986417c617bec2985959c6a07526a99e Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Thu, 28 Sep 2023 20:34:58 +1000 Subject: [PATCH 05/14] fix a mistake --- .vscode/settings.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000000..1050c79b825e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "omnisharp.autoStart": false, + "cmake.sourceDirectory": "${workspaceFolder}/swift", + "cmake.buildDirectory": "${workspaceFolder}/bazel-cmake-build" +} From f41bc1f631dabe12826c0bd865b7f27e37cbf6a6 Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Thu, 28 Sep 2023 20:37:21 +1000 Subject: [PATCH 06/14] revert nodeJSLib --- javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index ed00477a2366..258a583e1ca0 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -6,7 +6,6 @@ import javascript import semmle.javascript.frameworks.HTTP import semmle.javascript.security.SensitiveActions private import semmle.javascript.dataflow.internal.PreCallGraphStep -private import semmle.javascript.security.dataflow.CodeInjectionCustomizations module NodeJSLib { private GlobalVariable processVariable() { variables(result, "process", any(GlobalScope sc)) } From 41e7b91d78f3bba05f09cf12004b4795a9d4f0be Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Sun, 8 Oct 2023 11:00:07 +0200 Subject: [PATCH 07/14] fix flowLabels --- .../Security/CWE-094-dataURL/CodeInjection.ql | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index 76907f6ea145..ec9353e60d50 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -53,8 +53,8 @@ class WorkerThreads extends DataFlow::Node { } } -class WorkerThreadsLabel extends FlowLabel { - WorkerThreadsLabel() { this = "worker_threads" } +class URLConstructorLabel extends FlowLabel { + URLConstructorLabel() { this = "URLConstructorLabel" } } class DynamicImportLabel extends FlowLabel { @@ -67,15 +67,12 @@ class DynamicImportLabel extends FlowLabel { class Configuration extends TaintTracking::Configuration { Configuration() { this = "CodeInjection" } - override predicate isSource(DataFlow::Node source, FlowLabel label) { - source instanceof RemoteFlowSource and - (label instanceof DynamicImportLabel or label instanceof WorkerThreadsLabel) - } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport } override predicate isSink(DataFlow::Node sink, FlowLabel label) { - sink instanceof DynamicImport and label instanceof DynamicImportLabel - or - sink instanceof WorkerThreads and label instanceof WorkerThreadsLabel + sink instanceof WorkerThreads and label instanceof URLConstructorLabel } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } @@ -87,8 +84,8 @@ class Configuration extends TaintTracking::Configuration { newUrl = DataFlow::globalVarRef("URL").getAnInstantiation() and pred = newUrl.getArgument(0) ) and - predlbl instanceof WorkerThreadsLabel and - succlbl instanceof WorkerThreadsLabel + predlbl instanceof StandardFlowLabel and + succlbl instanceof URLConstructorLabel } } From 00b6e1f0b04cb5de4863a0a3b7c86c822c12b174 Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Sun, 8 Oct 2023 11:03:19 +0200 Subject: [PATCH 08/14] fix tests --- .../CWE-094-dataURL/CodeInjection.expected | 58 +++++++++++++++---- .../Security/CWE-094-dataURL/test.js | 20 +++---- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected index 62fd4fd296a2..e34e9760969d 100644 --- a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected @@ -1,14 +1,52 @@ WARNING: Unused class Sink (/home/am/CodeQL-home/codeql-repo-amammad/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql:23,16-20) nodes -| test.js:18:11:18:44 | payload | -| test.js:18:21:18:44 | req.que ... rameter | -| test.js:18:21:18:44 | req.que ... rameter | -| test.js:20:18:20:24 | payload | -| test.js:20:18:20:24 | payload | +| test.js:5:11:5:44 | payload | +| test.js:5:21:5:44 | req.que ... rameter | +| test.js:5:21:5:44 | req.que ... rameter | +| test.js:6:9:6:43 | payloadURL | +| test.js:6:22:6:43 | new URL ... + sth) | +| test.js:6:30:6:36 | payload | +| test.js:6:30:6:42 | payload + sth | +| test.js:7:16:7:25 | payloadURL | +| test.js:7:16:7:25 | payloadURL | +| test.js:9:5:9:39 | payloadURL | +| test.js:9:18:9:39 | new URL ... + sth) | +| test.js:9:26:9:32 | payload | +| test.js:9:26:9:38 | payload + sth | +| test.js:10:16:10:25 | payloadURL | +| test.js:10:16:10:25 | payloadURL | +| test.js:17:11:17:44 | payload | +| test.js:17:21:17:44 | req.que ... rameter | +| test.js:17:21:17:44 | req.que ... rameter | +| test.js:18:18:18:24 | payload | +| test.js:18:18:18:24 | payload | +| test.js:19:18:19:24 | payload | +| test.js:19:18:19:30 | payload + sth | +| test.js:19:18:19:30 | payload + sth | edges -| test.js:18:11:18:44 | payload | test.js:20:18:20:24 | payload | -| test.js:18:11:18:44 | payload | test.js:20:18:20:24 | payload | -| test.js:18:21:18:44 | req.que ... rameter | test.js:18:11:18:44 | payload | -| test.js:18:21:18:44 | req.que ... rameter | test.js:18:11:18:44 | payload | +| test.js:5:11:5:44 | payload | test.js:6:30:6:36 | payload | +| test.js:5:11:5:44 | payload | test.js:9:26:9:32 | payload | +| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | +| test.js:5:21:5:44 | req.que ... rameter | test.js:5:11:5:44 | payload | +| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | +| test.js:6:9:6:43 | payloadURL | test.js:7:16:7:25 | payloadURL | +| test.js:6:22:6:43 | new URL ... + sth) | test.js:6:9:6:43 | payloadURL | +| test.js:6:30:6:36 | payload | test.js:6:30:6:42 | payload + sth | +| test.js:6:30:6:42 | payload + sth | test.js:6:22:6:43 | new URL ... + sth) | +| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | +| test.js:9:5:9:39 | payloadURL | test.js:10:16:10:25 | payloadURL | +| test.js:9:18:9:39 | new URL ... + sth) | test.js:9:5:9:39 | payloadURL | +| test.js:9:26:9:32 | payload | test.js:9:26:9:38 | payload + sth | +| test.js:9:26:9:38 | payload + sth | test.js:9:18:9:39 | new URL ... + sth) | +| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | +| test.js:17:11:17:44 | payload | test.js:18:18:18:24 | payload | +| test.js:17:11:17:44 | payload | test.js:19:18:19:24 | payload | +| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | +| test.js:17:21:17:44 | req.que ... rameter | test.js:17:11:17:44 | payload | +| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | +| test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | #select -| test.js:20:18:20:24 | payload | test.js:18:21:18:44 | req.que ... rameter | test.js:20:18:20:24 | payload | payload depends on a $@. | test.js:18:21:18:44 | req.que ... rameter | user-provided value | +| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | payloadURL depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | +| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | payloadURL depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | +| test.js:18:18:18:24 | payload | test.js:17:21:17:44 | req.que ... rameter | test.js:18:18:18:24 | payload | payload depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | +| test.js:19:18:19:30 | payload + sth | test.js:17:21:17:44 | req.que ... rameter | test.js:19:18:19:30 | payload + sth | payload + sth depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js b/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js index b0ead7aa9b51..a5a2e76fa3c8 100644 --- a/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/test.js @@ -3,24 +3,20 @@ var app = require('express')(); app.post('/path', async function (req, res) { const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' - let payloadURL = new URL(payload + sth) - // NOT OK + let payloadURL = new URL(payload + sth) // NOT OK new Worker(payloadURL); - // NOT OK - payloadURL = new URL(payload + sth) + + payloadURL = new URL(payload + sth) // NOT OK new Worker(payloadURL); - // OK - payloadURL = new URL(sth + payload) + + payloadURL = new URL(sth + payload) // OK new Worker(payloadURL); }); app.post('/path2', async function (req, res) { const payload = req.query.queryParameter // like: payload = 'data:text/javascript,console.log("hello!");//' - // NOT OK - await import(payload) - // NOT OK - await import(payload + sth) - // OK - await import(sth + payload) + await import(payload) // NOT OK + await import(payload + sth) // NOT OK + await import(sth + payload) // OK }); From 15671682c518936c10e8c21ffa401b26edfb5d11 Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Sun, 8 Oct 2023 11:06:13 +0200 Subject: [PATCH 09/14] remove unused flowLable, update path query alert message --- .../experimental/Security/CWE-094-dataURL/CodeInjection.ql | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index ec9353e60d50..23b4d91083c4 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -57,10 +57,6 @@ class URLConstructorLabel extends FlowLabel { URLConstructorLabel() { this = "URLConstructorLabel" } } -class DynamicImportLabel extends FlowLabel { - DynamicImportLabel() { this = "DynamicImport" } -} - /** * A taint-tracking configuration for reasoning about code injection vulnerabilities. */ @@ -91,5 +87,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, sink.getNode() + " depends on a $@.", source.getNode(), +select sink.getNode(), source, sink, sink.getNode() + "This command line depends on a $@.", source.getNode(), "user-provided value" From 3f41a42c38d5df725014d8ebf35dece03950a56a Mon Sep 17 00:00:00 2001 From: amammad <77095239+amammad@users.noreply.github.com> Date: Sun, 8 Oct 2023 11:08:05 +0200 Subject: [PATCH 10/14] remove unused classes --- .../experimental/Security/CWE-094-dataURL/CodeInjection.ql | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index 23b4d91083c4..0c23109890fa 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -20,8 +20,6 @@ import DataFlow::PathGraph abstract class Sanitizer extends DataFlow::Node { } -abstract class Sink extends DataFlow::Node { } - /** A non-first leaf in a string-concatenation. Seen as a sanitizer for dynamic import code injection. */ class NonFirstStringConcatLeaf extends Sanitizer { NonFirstStringConcatLeaf() { @@ -87,5 +85,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, sink.getNode() + "This command line depends on a $@.", source.getNode(), - "user-provided value" +select sink.getNode(), source, sink, sink.getNode() + "This command line depends on a $@.", + source.getNode(), "user-provided value" From d27a37800884a479fe4a03da57c1ffd40ffe6a7d Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Thu, 6 Jun 2024 13:59:58 +0200 Subject: [PATCH 11/14] change query-id to avoid duplicate ids --- .../src/experimental/Security/CWE-094-dataURL/CodeInjection.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index 0c23109890fa..9f9dbe38e75f 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -6,7 +6,7 @@ * @problem.severity error * @security-severity 9.3 * @precision high - * @id js/code-injection + * @id js/code-injection-dynamic-import * @tags security * external/cwe/cwe-094 * external/cwe/cwe-095 From 8258e377dda0c03c0523eddddd50015cfe45222a Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Thu, 6 Jun 2024 14:00:56 +0200 Subject: [PATCH 12/14] use PascalCase for URLConstructorLabel --- .../Security/CWE-094-dataURL/CodeInjection.ql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index 9f9dbe38e75f..1734086aa2a5 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -51,8 +51,8 @@ class WorkerThreads extends DataFlow::Node { } } -class URLConstructorLabel extends FlowLabel { - URLConstructorLabel() { this = "URLConstructorLabel" } +class UrlConstructorLabel extends FlowLabel { + UrlConstructorLabel() { this = "UrlConstructorLabel" } } /** @@ -66,7 +66,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof DynamicImport } override predicate isSink(DataFlow::Node sink, FlowLabel label) { - sink instanceof WorkerThreads and label instanceof URLConstructorLabel + sink instanceof WorkerThreads and label instanceof UrlConstructorLabel } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } @@ -79,7 +79,7 @@ class Configuration extends TaintTracking::Configuration { pred = newUrl.getArgument(0) ) and predlbl instanceof StandardFlowLabel and - succlbl instanceof URLConstructorLabel + succlbl instanceof UrlConstructorLabel } } From 9db334d02f00bb9e8596f7955e02f4e5fbe90caa Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:26:16 +0200 Subject: [PATCH 13/14] update select statement, update test cases --- .../Security/CWE-094-dataURL/CodeInjection.ql | 2 +- .../Security/CWE-094-dataURL/CodeInjection.expected | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index 1734086aa2a5..c83a2708f7e9 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -85,5 +85,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, sink.getNode() + "This command line depends on a $@.", +select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), "user-provided value" diff --git a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected index e34e9760969d..3a5963b4094f 100644 --- a/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected +++ b/javascript/ql/test/experimental/Security/CWE-094-dataURL/CodeInjection.expected @@ -1,4 +1,3 @@ -WARNING: Unused class Sink (/home/am/CodeQL-home/codeql-repo-amammad/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql:23,16-20) nodes | test.js:5:11:5:44 | payload | | test.js:5:21:5:44 | req.que ... rameter | @@ -46,7 +45,7 @@ edges | test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | | test.js:19:18:19:24 | payload | test.js:19:18:19:30 | payload + sth | #select -| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | payloadURL depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | -| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | payloadURL depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | -| test.js:18:18:18:24 | payload | test.js:17:21:17:44 | req.que ... rameter | test.js:18:18:18:24 | payload | payload depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | -| test.js:19:18:19:30 | payload + sth | test.js:17:21:17:44 | req.que ... rameter | test.js:19:18:19:30 | payload + sth | payload + sth depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | +| test.js:7:16:7:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:7:16:7:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | +| test.js:10:16:10:25 | payloadURL | test.js:5:21:5:44 | req.que ... rameter | test.js:10:16:10:25 | payloadURL | This command line depends on a $@. | test.js:5:21:5:44 | req.que ... rameter | user-provided value | +| test.js:18:18:18:24 | payload | test.js:17:21:17:44 | req.que ... rameter | test.js:18:18:18:24 | payload | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | +| test.js:19:18:19:30 | payload + sth | test.js:17:21:17:44 | req.que ... rameter | test.js:19:18:19:30 | payload + sth | This command line depends on a $@. | test.js:17:21:17:44 | req.que ... rameter | user-provided value | From bb03a9fabaee6c623ecab164da1c8d5ff9e6a2e5 Mon Sep 17 00:00:00 2001 From: am0o0 <77095239+am0o0@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:54:29 +0200 Subject: [PATCH 14/14] format the query file --- .../experimental/Security/CWE-094-dataURL/CodeInjection.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql index c83a2708f7e9..b4b66293ee51 100644 --- a/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql +++ b/javascript/ql/src/experimental/Security/CWE-094-dataURL/CodeInjection.ql @@ -85,5 +85,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink where cfg.hasFlowPath(source, sink) -select sink.getNode(), source, sink, "This command line depends on a $@.", - source.getNode(), "user-provided value" +select sink.getNode(), source, sink, "This command line depends on a $@.", source.getNode(), + "user-provided value"