Skip to content

Commit 474c808

Browse files
authored
Merge pull request #7137 from erik-krogh/functionExport
JS: recognize library inputs when the library exports "through" a function
2 parents 7cfc696 + b9ea4a8 commit 474c808

File tree

5 files changed

+31
-1
lines changed

5 files changed

+31
-1
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,19 @@ private DataFlow::Node getAValueExportedByPackage() {
141141
result = unique( | | call.getCalleeNode().getAFunctionValue()).getAReturn()
142142
)
143143
or
144+
// the exported value is a function that returns another import.
145+
// ```JavaScript
146+
// module.exports = function foo() {
147+
// return require("./other-module.js");
148+
// }
149+
// ```
150+
exists(DataFlow::FunctionNode func, Module mod |
151+
func = getAValueExportedByPackage().getABoundFunctionValue(_)
152+
|
153+
mod = func.getAReturn().getALocalSource().getEnclosingExpr().(Import).getImportedModule() and
154+
result = getAnExportFromModule(mod)
155+
)
156+
or
144157
// *****
145158
// Common styles of transforming exported objects.
146159
// *****

javascript/ql/test/query-tests/Performance/ReDoS/PolynomialBackTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
| jsonschema.js:15:23:15:29 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b |
2929
| jsonschema.js:20:18:20:24 | (a?a?)* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding (a?a?)*b |
3030
| lib/closure.js:4:6:4:7 | u* | Strings with many repetitions of 'u' can start matching anywhere after the start of the preceeding u*o |
31+
| lib/indirect.js:2:6:2:7 | k* | Strings with many repetitions of 'k' can start matching anywhere after the start of the preceeding k*h |
3132
| lib/lib.js:1:15:1:16 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |
3233
| lib/lib.js:8:3:8:4 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
3334
| lib/moduleLib/moduleLib.js:2:3:2:4 | a* | Strings with many repetitions of 'a' can start matching anywhere after the start of the preceeding a*b |

javascript/ql/test/query-tests/Performance/ReDoS/PolynomialReDoS.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ nodes
33
| lib/closure.js:3:21:3:21 | x |
44
| lib/closure.js:4:16:4:16 | x |
55
| lib/closure.js:4:16:4:16 | x |
6+
| lib/indirect.js:1:32:1:32 | x |
7+
| lib/indirect.js:1:32:1:32 | x |
8+
| lib/indirect.js:2:16:2:16 | x |
9+
| lib/indirect.js:2:16:2:16 | x |
610
| lib/lib.js:3:28:3:31 | name |
711
| lib/lib.js:3:28:3:31 | name |
812
| lib/lib.js:4:14:4:17 | name |
@@ -170,6 +174,10 @@ edges
170174
| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x |
171175
| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x |
172176
| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x |
177+
| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x |
178+
| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x |
179+
| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x |
180+
| lib/indirect.js:1:32:1:32 | x | lib/indirect.js:2:16:2:16 | x |
173181
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
174182
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
175183
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
@@ -329,6 +337,7 @@ edges
329337
| polynomial-redos.js:123:13:123:20 | replaced | polynomial-redos.js:123:3:123:20 | result |
330338
#select
331339
| lib/closure.js:4:5:4:17 | /u*o/.test(x) | lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x | This $@ that depends on $@ may run slow on strings with many repetitions of 'u'. | lib/closure.js:4:6:4:7 | u* | regular expression | lib/closure.js:3:21:3:21 | x | library input |
340+
| 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 |
332341
| 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 |
333342
| 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 |
334343
| 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 |
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports.foo = function (x) {
2+
/k*h/.test(x); // NOT OK
3+
}

javascript/ql/test/query-tests/Performance/ReDoS/lib/lib.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ if (typeof define !== 'undefined' && define.amd) { // AMD
1212
define([], function () {return bar});
1313
}
1414

15-
module.exports.closure = require("./closure")
15+
module.exports.closure = require("./closure")
16+
17+
module.exports.func = function (conf) {
18+
return require("./indirect")
19+
}

0 commit comments

Comments
 (0)