Merge pull request #10343 from erik-krogh/spreadFunction

JS: recognize calls to `Function` when spread arguments are used
This commit is contained in:
Erik Krogh Kristensen
2022-09-08 09:25:10 +02:00
committed by GitHub
4 changed files with 68 additions and 7 deletions

View File

@@ -170,7 +170,7 @@ module CodeInjection {
exists(string callName | c = DataFlow::globalVarRef(callName).getAnInvocation() |
callName = "eval" and index = 0
or
callName = "Function"
callName = "Function" and index = -1
or
callName = "execScript" and index = 0
or
@@ -185,14 +185,13 @@ module CodeInjection {
callName = "setImmediate" and index = 0
)
or
exists(DataFlow::GlobalVarRefNode wasm, string methodName |
wasm.getName() = "WebAssembly" and c = wasm.getAMemberCall(methodName)
|
methodName = "compile" or
methodName = "compileStreaming"
)
c = DataFlow::globalVarRef("WebAssembly").getAMemberCall(["compile", "compileStreaming"]) and
index = -1
|
this = c.getArgument(index)
or
index = -1 and
this = c.getAnArgument()
)
or
// node-serialize is not intended to be safe for untrusted inputs

View File

@@ -157,6 +157,18 @@ nodes
| tst.js:26:26:26:40 | location.search |
| tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:29:9:29:82 | source |
| tst.js:29:18:29:41 | documen ... .search |
| tst.js:29:18:29:41 | documen ... .search |
| tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:31:18:31:23 | source |
| tst.js:31:18:31:23 | source |
| tst.js:33:14:33:19 | source |
| tst.js:33:14:33:19 | source |
| tst.js:35:28:35:33 | source |
| tst.js:35:28:35:33 | source |
| tst.js:37:33:37:38 | source |
| tst.js:37:33:37:38 | source |
edges
| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query |
| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query |
@@ -262,6 +274,17 @@ edges
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source |
| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source |
| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source |
| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source |
| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source |
| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source |
| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source |
| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source |
| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source |
#select
| NoSQLCodeInjection.js:18:24:18:37 | req.body.query | NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query | $@ flows to here and is interpreted as code. | NoSQLCodeInjection.js:18:24:18:31 | req.body | User-provided value |
| NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | NoSQLCodeInjection.js:19:36:19:43 | req.body | NoSQLCodeInjection.js:19:24:19:48 | "name = ... dy.name | $@ flows to here and is interpreted as code. | NoSQLCodeInjection.js:19:36:19:43 | req.body | User-provided value |
@@ -314,3 +337,7 @@ edges
| tst.js:20:30:20:51 | documen ... on.hash | tst.js:20:30:20:51 | documen ... on.hash | tst.js:20:30:20:51 | documen ... on.hash | $@ flows to here and is interpreted as code. | tst.js:20:30:20:51 | documen ... on.hash | User-provided value |
| tst.js:23:6:23:46 | atob(do ... ing(1)) | tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:6:23:46 | atob(do ... ing(1)) | $@ flows to here and is interpreted as code. | tst.js:23:11:23:32 | documen ... on.hash | User-provided value |
| tst.js:26:26:26:53 | locatio ... ring(1) | tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | $@ flows to here and is interpreted as code. | tst.js:26:26:26:40 | location.search | User-provided value |
| tst.js:31:18:31:23 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:31:18:31:23 | source | $@ flows to here and is interpreted as code. | tst.js:29:18:29:41 | documen ... .search | User-provided value |
| tst.js:33:14:33:19 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:33:14:33:19 | source | $@ flows to here and is interpreted as code. | tst.js:29:18:29:41 | documen ... .search | User-provided value |
| tst.js:35:28:35:33 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:35:28:35:33 | source | $@ flows to here and is interpreted as code. | tst.js:29:18:29:41 | documen ... .search | User-provided value |
| tst.js:37:33:37:38 | source | tst.js:29:18:29:41 | documen ... .search | tst.js:37:33:37:38 | source | $@ flows to here and is interpreted as code. | tst.js:29:18:29:41 | documen ... .search | User-provided value |

View File

@@ -161,6 +161,18 @@ nodes
| tst.js:26:26:26:40 | location.search |
| tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:29:9:29:82 | source |
| tst.js:29:18:29:41 | documen ... .search |
| tst.js:29:18:29:41 | documen ... .search |
| tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:31:18:31:23 | source |
| tst.js:31:18:31:23 | source |
| tst.js:33:14:33:19 | source |
| tst.js:33:14:33:19 | source |
| tst.js:35:28:35:33 | source |
| tst.js:35:28:35:33 | source |
| tst.js:37:33:37:38 | source |
| tst.js:37:33:37:38 | source |
edges
| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query |
| NoSQLCodeInjection.js:18:24:18:31 | req.body | NoSQLCodeInjection.js:18:24:18:37 | req.body.query |
@@ -270,5 +282,16 @@ edges
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) |
| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source |
| tst.js:29:9:29:82 | source | tst.js:31:18:31:23 | source |
| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source |
| tst.js:29:9:29:82 | source | tst.js:33:14:33:19 | source |
| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source |
| tst.js:29:9:29:82 | source | tst.js:35:28:35:33 | source |
| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source |
| tst.js:29:9:29:82 | source | tst.js:37:33:37:38 | source |
| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:29:18:29:41 | documen ... .search | tst.js:29:18:29:82 | documen ... , "$1") |
| tst.js:29:18:29:82 | documen ... , "$1") | tst.js:29:9:29:82 | source |
#select
| eslint-escope-build.js:21:16:21:16 | c | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | $@ flows to here and is interpreted as code. | eslint-escope-build.js:20:22:20:22 | c | User-provided value |

View File

@@ -24,3 +24,15 @@ eval(atob(document.location.hash.substring(1)));
// NOT OK
$('<a>').attr("onclick", location.search.substring(1));
(function test() {
var source = document.location.search.replace(/.*\bfoo\s*=\s*([^;]*).*/, "$1");
new Function(source); // NOT OK
Function(source); // NOT OK
new Function("a", "b", source); // NOT OK
new Function(...["a", "b"], source); // NOT OK
})();