Skip to content

Commit 2d65aa1

Browse files
committed
recognize exported functions that use the arguments object
1 parent 7877423 commit 2d65aa1

File tree

5 files changed

+50
-6
lines changed

5 files changed

+50
-6
lines changed

javascript/ql/lib/semmle/javascript/PackageExports.qll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,18 @@ private import semmle.javascript.internal.CachedStages
1111
* Gets a parameter that is a library input to a top-level package.
1212
*/
1313
cached
14-
DataFlow::ParameterNode getALibraryInputParameter() {
14+
DataFlow::SourceNode getALibraryInputParameter() {
1515
Stages::Taint::ref() and
1616
exists(int bound, DataFlow::FunctionNode func |
17-
func = getAValueExportedByPackage().getABoundFunctionValue(bound) and
17+
func = getAValueExportedByPackage().getABoundFunctionValue(bound)
18+
|
1819
result = func.getParameter(any(int arg | arg >= bound))
20+
or
21+
exists(DataFlow::PropRead read |
22+
not read.getPropertyName() = "length" and
23+
result = read and
24+
read.getBase() = func.getFunction().getArgumentsVariable().getAnAccess().flow()
25+
)
1926
)
2027
}
2128

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,14 @@ module UnsafeShellCommandConstruction {
5050
/**
5151
* A parameter of an exported function, seen as a source for shell command constructed from library input.
5252
*/
53-
class ExternalInputSource extends Source, DataFlow::ParameterNode {
53+
class ExternalInputSource extends Source, DataFlow::SourceNode {
5454
ExternalInputSource() {
5555
this = Exports::getALibraryInputParameter() and
5656
not (
5757
// looks to be on purpose.
58-
this.getName() = ["cmd", "command"]
58+
this.(DataFlow::ParameterNode).getName() = ["cmd", "command"]
5959
or
60-
this.getName().regexpMatch(".*(Cmd|Command)$") // ends with "Cmd" or "Command"
60+
this.(DataFlow::ParameterNode).getName().regexpMatch(".*(Cmd|Command)$") // ends with "Cmd" or "Command"
6161
)
6262
}
6363
}

javascript/ql/lib/semmle/javascript/security/performance/PolynomialReDoSCustomizations.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ module PolynomialReDoS {
126126
/**
127127
* A parameter of an exported function, seen as a source for polynomial-redos.
128128
*/
129-
class ExternalInputSource extends Source, DataFlow::ParameterNode {
129+
class ExternalInputSource extends Source, DataFlow::SourceNode {
130130
ExternalInputSource() { this = Exports::getALibraryInputParameter() }
131131

132132
override string getKind() { result = "library" }

javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/PrototypePollutingAssignment.expected

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ nodes
1919
| lib.js:11:35:11:38 | path |
2020
| lib.js:11:35:11:47 | path.slice(1) |
2121
| lib.js:11:35:11:47 | path.slice(1) |
22+
| lib.js:14:38:14:41 | path |
23+
| lib.js:14:38:14:41 | path |
24+
| lib.js:15:3:15:14 | obj[path[0]] |
25+
| lib.js:15:3:15:14 | obj[path[0]] |
26+
| lib.js:15:7:15:10 | path |
27+
| lib.js:15:7:15:13 | path[0] |
28+
| lib.js:20:7:20:25 | path |
29+
| lib.js:20:14:20:25 | arguments[1] |
30+
| lib.js:20:14:20:25 | arguments[1] |
31+
| lib.js:22:3:22:14 | obj[path[0]] |
32+
| lib.js:22:3:22:14 | obj[path[0]] |
33+
| lib.js:22:7:22:10 | path |
34+
| lib.js:22:7:22:13 | path[0] |
2235
| tst.js:5:9:5:38 | taint |
2336
| tst.js:5:17:5:38 | String( ... y.data) |
2437
| tst.js:5:24:5:37 | req.query.data |
@@ -66,6 +79,17 @@ edges
6679
| lib.js:11:35:11:38 | path | lib.js:11:35:11:47 | path.slice(1) |
6780
| lib.js:11:35:11:47 | path.slice(1) | lib.js:1:43:1:46 | path |
6881
| lib.js:11:35:11:47 | path.slice(1) | lib.js:1:43:1:46 | path |
82+
| lib.js:14:38:14:41 | path | lib.js:15:7:15:10 | path |
83+
| lib.js:14:38:14:41 | path | lib.js:15:7:15:10 | path |
84+
| lib.js:15:7:15:10 | path | lib.js:15:7:15:13 | path[0] |
85+
| lib.js:15:7:15:13 | path[0] | lib.js:15:3:15:14 | obj[path[0]] |
86+
| lib.js:15:7:15:13 | path[0] | lib.js:15:3:15:14 | obj[path[0]] |
87+
| lib.js:20:7:20:25 | path | lib.js:22:7:22:10 | path |
88+
| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path |
89+
| lib.js:20:14:20:25 | arguments[1] | lib.js:20:7:20:25 | path |
90+
| lib.js:22:7:22:10 | path | lib.js:22:7:22:13 | path[0] |
91+
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
92+
| lib.js:22:7:22:13 | path[0] | lib.js:22:3:22:14 | obj[path[0]] |
6993
| tst.js:5:9:5:38 | taint | tst.js:8:12:8:16 | taint |
7094
| tst.js:5:9:5:38 | taint | tst.js:9:12:9:16 | taint |
7195
| tst.js:5:9:5:38 | taint | tst.js:12:25:12:29 | taint |
@@ -91,6 +115,8 @@ edges
91115
| tst.js:33:23:33:25 | obj | tst.js:48:9:48:11 | obj |
92116
#select
93117
| 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 | here |
118+
| 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 | here |
119+
| 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] | here |
94120
| 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 | here |
95121
| tst.js:9:5:9:17 | object[taint] | tst.js:5:24:5:37 | req.query.data | tst.js:9:5:9: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 | here |
96122
| tst.js:14:5:14:32 | unsafeG ... taint) | tst.js:5:24:5:37 | req.query.data | tst.js:14:5:14:32 | unsafeG ... taint) | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:5:24:5:37 | req.query.data | here |

javascript/ql/test/query-tests/Security/CWE-915/PrototypePollutingAssignment/lib.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,15 @@ module.exports.set = function recSet(obj, path, value) {
99
}
1010

1111
return recSet(obj[currentPath], path.slice(1), value);
12+
}
13+
14+
module.exports.set2 = function (obj, path, value) {
15+
obj[path[0]][path[1]] = value; // NOT OK
16+
}
17+
18+
module.exports.setWithArgs = function() {
19+
var obj = arguments[0];
20+
var path = arguments[1];
21+
var value = arguments[2];
22+
obj[path[0]][path[1]] = value; // NOT OK
1223
}

0 commit comments

Comments
 (0)