simplify getALibraryInputParameter by adding more general dataflow for the arguments object

This commit is contained in:
erik-krogh
2022-08-21 22:36:06 +02:00
parent 11b039c1f1
commit 2f11f3760e
7 changed files with 47 additions and 43 deletions

View File

@@ -344,6 +344,14 @@ private module ArrayLibraries {
result = DataFlow::globalVarRef("Array").getAMemberCall("from")
or
result = DataFlow::moduleImport("array-from").getACall()
or
// Array.prototype.slice.call acts the same as Array.from, and is sometimes used with e.g. the arguments object.
result =
DataFlow::globalVarRef("Array")
.getAPropertyRead("prototype")
.getAPropertyRead("slice")
.getAMethodCall("call") and
result.getNumArgument() = 1
}
/**

View File

@@ -18,34 +18,10 @@ DataFlow::Node getALibraryInputParameter() {
|
result = func.getParameter(any(int arg | arg >= bound))
or
result = getAnArgumentsRead(func.getFunction())
or
result = func.getFunction().getArgumentsVariable().getAnAccess().flow()
)
}
private DataFlow::SourceNode getAnArgumentsRead(Function func) {
exists(DataFlow::PropRead read |
not read.getPropertyName() = "length" and
result = read
|
read.getBase() = func.getArgumentsVariable().getAnAccess().flow()
or
exists(DataFlow::MethodCallNode call |
call =
DataFlow::globalVarRef("Array")
.getAPropertyRead("prototype")
.getAPropertyRead("slice")
.getAMethodCall("call")
or
call = DataFlow::globalVarRef("Array").getAMethodCall("from")
|
call.getArgument(0) = func.getArgumentsVariable().getAnAccess().flow() and
call.flowsTo(read.getBase())
)
)
}
private import NodeModuleResolutionImpl as NodeModule
/**

View File

@@ -1661,9 +1661,7 @@ module DataFlow {
)
}
/**
* A step from a reflective parameter node to each parameter.
*/
/** A load step from a reflective parameter node to each parameter. */
private class ReflectiveParamsStep extends PreCallGraphStep {
override predicate loadStep(DataFlow::Node obj, DataFlow::Node element, string prop) {
exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f, int i |
@@ -1675,6 +1673,17 @@ module DataFlow {
}
}
/** A taint step from the reflective parameters node to any parameter. */
private class ReflectiveParamsTaintStep extends TaintTracking::SharedTaintStep {
override predicate step(DataFlow::Node obj, DataFlow::Node element) {
exists(DataFlow::ReflectiveParametersNode params, DataFlow::FunctionNode f |
f.getFunction() = params.getFunction() and
obj = params and
element = f.getAParameter()
)
}
}
/**
* Holds if there is a step from `pred` to `succ` through a field accessed through `this` in a class.
*/

View File

@@ -6,6 +6,7 @@ typeInferenceMismatch
| call-apply.js:25:14:25:21 | source() | call-apply.js:21:1:23:1 | the arguments object of function foo1_sink |
| call-apply.js:25:14:25:21 | source() | call-apply.js:27:6:27:32 | reflective call |
| call-apply.js:25:14:25:21 | source() | call-apply.js:30:6:30:35 | reflective call |
| call-apply.js:25:14:25:21 | source() | call-apply.js:31:6:31:35 | reflective call |
| call-apply.js:25:14:25:21 | source() | call-apply.js:62:3:64:3 | the arguments object of function sinkArguments1 |
| call-apply.js:25:14:25:21 | source() | call-apply.js:65:3:67:3 | the arguments object of function sinkArguments0 |
| call-apply.js:25:14:25:21 | source() | call-apply.js:69:3:72:3 | the arguments object of function fowardArguments |
@@ -54,6 +55,8 @@ typeInferenceMismatch
| call-apply.js:25:14:25:21 | source() | call-apply.js:22:8:22:11 | arg1 |
| call-apply.js:25:14:25:21 | source() | call-apply.js:27:6:27:32 | foo1.ca ... ce, "") |
| call-apply.js:25:14:25:21 | source() | call-apply.js:30:6:30:35 | foo1.ap ... e, ""]) |
| call-apply.js:25:14:25:21 | source() | call-apply.js:31:6:31:35 | foo2.ap ... e, ""]) |
| call-apply.js:25:14:25:21 | source() | call-apply.js:38:6:38:29 | foo1_ap ... e, ""]) |
| call-apply.js:25:14:25:21 | source() | call-apply.js:44:6:44:28 | foo1_ca ... e, ""]) |
| call-apply.js:25:14:25:21 | source() | call-apply.js:45:6:45:28 | foo1_ca ... ource]) |
| call-apply.js:25:14:25:21 | source() | call-apply.js:63:10:63:21 | arguments[1] |

View File

@@ -22,6 +22,12 @@ nodes
| lib/lib.js:27:10:27:19 | id("safe") |
| lib/lib.js:28:13:28:13 | y |
| lib/lib.js:28:13:28:13 | y |
| lib/lib.js:32:32:32:40 | arguments |
| lib/lib.js:32:32:32:40 | arguments |
| lib/lib.js:35:1:37:1 | the arguments object of function usedWithArguments |
| lib/lib.js:35:28:35:31 | name |
| lib/lib.js:36:13:36:16 | name |
| lib/lib.js:36:13:36:16 | name |
| lib/moduleLib/moduleLib.js:1:28:1:31 | name |
| lib/moduleLib/moduleLib.js:1:28:1:31 | name |
| lib/moduleLib/moduleLib.js:2:13:2:16 | name |
@@ -238,6 +244,11 @@ edges
| lib/lib.js:27:6:27:19 | y | lib/lib.js:28:13:28:13 | y |
| lib/lib.js:27:6:27:19 | y | lib/lib.js:28:13:28:13 | y |
| lib/lib.js:27:10:27:19 | id("safe") | lib/lib.js:27:6:27:19 | y |
| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | the arguments object of function usedWithArguments |
| lib/lib.js:32:32:32:40 | arguments | lib/lib.js:35:1:37:1 | the arguments object of function usedWithArguments |
| lib/lib.js:35:1:37:1 | the arguments object of function usedWithArguments | lib/lib.js:35:28:35:31 | name |
| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name |
| lib/lib.js:35:28:35:31 | name | lib/lib.js:36:13:36:16 | name |
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
| lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name |
@@ -428,6 +439,7 @@ edges
| lib/indirect.js:2:5:2:17 | /k*h/.test(x) | lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x | This $@ that depends on $@ may run slow on strings with many repetitions of 'k'. | lib/indirect.js:2:6:2:7 | k* | regular expression | lib/indirect.js:1:32:1:32 | x | library input |
| lib/lib.js:4:2:4:18 | regexp.test(name) | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/lib.js:1:15:1:16 | a* | regular expression | lib/lib.js:3:28:3:31 | name | library input |
| lib/lib.js:8:2:8:17 | /f*g/.test(name) | lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:8:3:8:4 | f* | regular expression | lib/lib.js:7:19:7:22 | name | library input |
| lib/lib.js:36:2:36:17 | /f*g/.test(name) | lib/lib.js:32:32:32:40 | arguments | lib/lib.js:36:13:36:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/lib.js:36:3:36:4 | f* | regular expression | lib/lib.js:32:32:32:40 | arguments | library input |
| lib/moduleLib/moduleLib.js:2:2:2:17 | /a*b/.test(name) | lib/moduleLib/moduleLib.js:1:28:1:31 | name | lib/moduleLib/moduleLib.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/moduleLib/moduleLib.js:2:3:2:4 | a* | regular expression | lib/moduleLib/moduleLib.js:1:28:1:31 | name | library input |
| lib/otherLib/js/src/index.js:2:2:2:17 | /a*b/.test(name) | lib/otherLib/js/src/index.js:1:28:1:31 | name | lib/otherLib/js/src/index.js:2:13:2:16 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'a'. | lib/otherLib/js/src/index.js:2:3:2:4 | a* | regular expression | lib/otherLib/js/src/index.js:1:28:1:31 | name | library input |
| lib/snapdragon.js:7:15:7:32 | this.match(/aa*$/) | lib/snapdragon.js:3:34:3:38 | input | lib/snapdragon.js:7:15:7:18 | this | This $@ that depends on $@ may run slow on strings starting with 'a' and with many repetitions of 'a'. | lib/snapdragon.js:7:28:7:29 | a* | regular expression | lib/snapdragon.js:3:34:3:38 | input | library input |

View File

@@ -33,7 +33,7 @@ module.exports.useArguments = function () {
}
function usedWithArguments(name) {
/f*g/.test(name); // NOT OK - bit not yet recognized [INCONSITENCY]
/f*g/.test(name); // NOT OK
}
module.exports.snapdragon = require("./snapdragon")

View File

@@ -29,7 +29,6 @@ nodes
| lib.js:20:14:20:22 | arguments |
| lib.js:20:14:20:22 | arguments |
| lib.js:20:14:20:25 | arguments[1] |
| lib.js:20:14:20:25 | arguments[1] |
| lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:7:22:10 | path |
@@ -40,8 +39,12 @@ nodes
| lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:26:14:26:17 | path |
| lib.js:26:14:26:20 | path[0] |
| lib.js:30:9:30:52 | args |
| lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:43:30:51 | arguments |
| lib.js:30:43:30:51 | arguments |
| lib.js:32:7:32:20 | path |
| lib.js:32:14:32:20 | args[1] |
| lib.js:32:14:32:17 | args |
| lib.js:32:14:32:20 | args[1] |
| lib.js:34:3:34:14 | obj[path[0]] |
| lib.js:34:3:34:14 | obj[path[0]] |
@@ -54,7 +57,6 @@ nodes
| lib.js:40:7:40:20 | path |
| lib.js:40:14:40:17 | args |
| lib.js:40:14:40:20 | args[1] |
| lib.js:40:14:40:20 | args[1] |
| lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:7:42:10 | path |
@@ -81,7 +83,6 @@ nodes
| lib.js:83:14:83:22 | arguments |
| lib.js:83:14:83:22 | arguments |
| lib.js:83:14:83:25 | arguments[1] |
| lib.js:83:14:83:25 | arguments[1] |
| lib.js:86:7:86:26 | proto |
| lib.js:86:15:86:26 | obj[path[0]] |
| lib.js:86:19:86:22 | path |
@@ -101,7 +102,6 @@ nodes
| lib.js:104:13:104:21 | arguments |
| lib.js:104:13:104:21 | arguments |
| lib.js:104:13:104:24 | arguments[1] |
| lib.js:104:13:104:24 | arguments[1] |
| lib.js:108:3:108:10 | obj[one] |
| lib.js:108:3:108:10 | obj[one] |
| lib.js:108:7:108:9 | one |
@@ -197,7 +197,6 @@ edges
| lib.js:20:14:20:22 | arguments | lib.js:20:14:20:25 | arguments[1] |
| lib.js:20:14:20:22 | arguments | lib.js:20:14:20:25 | arguments[1] |
| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path |
| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path |
| lib.js:22:7:22:10 | path | lib.js:22:7:22:13 | path[0] |
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
@@ -206,8 +205,12 @@ edges
| lib.js:26:14:26:17 | path | lib.js:26:14:26:20 | path[0] |
| lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:26:14:26:20 | path[0] | lib.js:26:10:26:21 | obj[path[0]] |
| lib.js:30:9:30:52 | args | lib.js:32:14:32:17 | args |
| lib.js:30:16:30:52 | Array.p ... uments) | lib.js:30:9:30:52 | args |
| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:30:43:30:51 | arguments | lib.js:30:16:30:52 | Array.p ... uments) |
| lib.js:32:7:32:20 | path | lib.js:34:7:34:10 | path |
| lib.js:32:14:32:20 | args[1] | lib.js:32:7:32:20 | path |
| lib.js:32:14:32:17 | args | lib.js:32:14:32:20 | args[1] |
| lib.js:32:14:32:20 | args[1] | lib.js:32:7:32:20 | path |
| lib.js:34:7:34:10 | path | lib.js:34:7:34:13 | path[0] |
| lib.js:34:7:34:13 | path[0] | lib.js:34:3:34:14 | obj[path[0]] |
@@ -219,7 +222,6 @@ edges
| lib.js:40:7:40:20 | path | lib.js:42:7:42:10 | path |
| lib.js:40:14:40:17 | args | lib.js:40:14:40:20 | args[1] |
| lib.js:40:14:40:20 | args[1] | lib.js:40:7:40:20 | path |
| lib.js:40:14:40:20 | args[1] | lib.js:40:7:40:20 | path |
| lib.js:42:7:42:10 | path | lib.js:42:7:42:13 | path[0] |
| lib.js:42:7:42:13 | path[0] | lib.js:42:3:42:14 | obj[path[0]] |
| lib.js:42:7:42:13 | path[0] | lib.js:42:3:42:14 | obj[path[0]] |
@@ -243,7 +245,6 @@ edges
| lib.js:83:14:83:22 | arguments | lib.js:83:14:83:25 | arguments[1] |
| lib.js:83:14:83:22 | arguments | lib.js:83:14:83:25 | arguments[1] |
| lib.js:83:14:83:25 | arguments[1] | lib.js:83:7:83:25 | path |
| lib.js:83:14:83:25 | arguments[1] | lib.js:83:7:83:25 | path |
| lib.js:86:7:86:26 | proto | lib.js:87:10:87:14 | proto |
| lib.js:86:7:86:26 | proto | lib.js:87:10:87:14 | proto |
| lib.js:86:15:86:26 | obj[path[0]] | lib.js:86:7:86:26 | proto |
@@ -261,7 +262,6 @@ edges
| lib.js:104:13:104:21 | arguments | lib.js:104:13:104:24 | arguments[1] |
| lib.js:104:13:104:21 | arguments | lib.js:104:13:104:24 | arguments[1] |
| lib.js:104:13:104:24 | arguments[1] | lib.js:104:7:104:24 | one |
| lib.js:104:13:104:24 | arguments[1] | lib.js:104:7:104:24 | one |
| lib.js:108:7:108:9 | one | lib.js:108:3:108:10 | obj[one] |
| lib.js:108:7:108:9 | one | lib.js:108:3:108:10 | obj[one] |
| lib.js:118:29:118:32 | path | lib.js:119:17:119:20 | path |
@@ -322,16 +322,12 @@ edges
| lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | library input |
| lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | library input |
| lib.js:22:3:22:14 | obj[path[0]] | lib.js:20:14:20:22 | arguments | lib.js:22:3:22:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:20:14:20:22 | arguments | library input |
| lib.js:22:3:22:14 | obj[path[0]] | lib.js:20:14:20:25 | arguments[1] | lib.js:22:3:22:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:20:14:20:25 | arguments[1] | library input |
| lib.js:26:10:26:21 | obj[path[0]] | lib.js:25:44:25:47 | path | lib.js:26:10:26:21 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:25:44:25:47 | path | library input |
| lib.js:34:3:34:14 | obj[path[0]] | lib.js:32:14:32:20 | args[1] | lib.js:34:3:34:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:32:14:32:20 | args[1] | library input |
| lib.js:34:3:34:14 | obj[path[0]] | lib.js:30:43:30:51 | arguments | lib.js:34:3:34:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:30:43:30:51 | arguments | library input |
| lib.js:42:3:42:14 | obj[path[0]] | lib.js:38:27:38:35 | arguments | lib.js:42:3:42:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:38:27:38:35 | arguments | library input |
| lib.js:42:3:42:14 | obj[path[0]] | lib.js:40:14:40:20 | args[1] | lib.js:42:3:42:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:40:14:40:20 | args[1] | library input |
| lib.js:70:13:70:24 | obj[path[0]] | lib.js:59:18:59:18 | s | lib.js:70:13:70:24 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:59:18:59:18 | s | library input |
| lib.js:87:10:87:14 | proto | lib.js:83:14:83:22 | arguments | lib.js:87:10:87:14 | proto | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:83:14:83:22 | arguments | library input |
| lib.js:87:10:87:14 | proto | lib.js:83:14:83:25 | arguments[1] | lib.js:87:10:87:14 | proto | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:83:14:83:25 | arguments[1] | library input |
| lib.js:108:3:108:10 | obj[one] | lib.js:104:13:104:21 | arguments | lib.js:108:3:108:10 | obj[one] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:104:13:104:21 | arguments | library input |
| lib.js:108:3:108:10 | obj[one] | lib.js:104:13:104:24 | arguments[1] | lib.js:108:3:108:10 | obj[one] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:104:13:104:24 | arguments[1] | library input |
| lib.js:119:13:119:24 | obj[path[0]] | lib.js:118:29:118:32 | path | lib.js:119:13:119:24 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:118:29:118:32 | path | library input |
| sublib/sub.js:2:3:2:14 | obj[path[0]] | sublib/sub.js:1:37:1:40 | path | sublib/sub.js:2:3:2:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | sublib/sub.js:1:37:1:40 | path | library input |
| tst.js:8:5:8:17 | object[taint] | tst.js:5:24:5:37 | req.query.data | tst.js:8:5:8:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | user controlled input |