Skip to content

Commit aaf754e

Browse files
committed
recognize more library input
1 parent 6931d9a commit aaf754e

File tree

5 files changed

+58
-0
lines changed

5 files changed

+58
-0
lines changed

javascript/ql/src/semmle/javascript/PackageExports.qll

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,32 @@ private DataFlow::Node getAValueExportedByPackage() {
5050
result = cla.getConstructor()
5151
)
5252
or
53+
// One shot closures that define a "factory" function.
54+
// Recognizes the following pattern:
55+
// ```Javascript
56+
// (function (root, factory) {
57+
// if (typeof define === 'function' && define.amd) {
58+
// define('library-name', factory);
59+
// } else if (typeof exports === 'object') {
60+
// module.exports = factory();
61+
// } else {
62+
// root.libraryName = factory();
63+
// }
64+
// }(this, function () {
65+
// ....
66+
// }));
67+
// ```
68+
exists(ImmediatelyInvokedFunctionExpr func, DataFlow::ParameterNode prev, int i |
69+
prev.getName() = "factory" and
70+
func.getParameter(i) = prev.getParameter() and
71+
result = func.getInvocation().getArgument(i).flow().getAFunctionValue().getAReturn()
72+
)
73+
or
74+
// the exported value is a call to a unique callee
75+
exists(DataFlow::CallNode call | call = getAValueExportedByPackage() |
76+
result = unique( | | call.getCalleeNode().getAFunctionValue()).getAReturn()
77+
)
78+
or
5379
// *****
5480
// Common styles of transforming exported objects.
5581
// *****

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
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 |
3131
| 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 |
3232
| 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 |
33+
| lib/sublib/factory.js:13:14:13:15 | f* | Strings with many repetitions of 'f' can start matching anywhere after the start of the preceeding f*g |
3334
| polynomial-redos.js:7:24:7:26 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
3435
| polynomial-redos.js:8:17:8:18 | * | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding *, * |
3536
| polynomial-redos.js:9:19:9:21 | \\s* | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s*\\n\\s* |

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ nodes
1111
| lib/lib.js:7:19:7:22 | name |
1212
| lib/lib.js:8:13:8:16 | name |
1313
| lib/lib.js:8:13:8:16 | name |
14+
| lib/sublib/factory.js:12:26:12:29 | name |
15+
| lib/sublib/factory.js:12:26:12:29 | name |
16+
| lib/sublib/factory.js:13:24:13:27 | name |
17+
| lib/sublib/factory.js:13:24:13:27 | name |
1418
| polynomial-redos.js:5:6:5:32 | tainted |
1519
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
1620
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
@@ -166,6 +170,10 @@ edges
166170
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
167171
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
168172
| lib/lib.js:7:19:7:22 | name | lib/lib.js:8:13:8:16 | name |
173+
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
174+
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
175+
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
176+
| lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name |
169177
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
170178
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
171179
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted |
@@ -307,6 +315,7 @@ edges
307315
| 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 |
308316
| 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 |
309317
| 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 |
318+
| lib/sublib/factory.js:13:13:13:28 | /f*g/.test(name) | lib/sublib/factory.js:12:26:12:29 | name | lib/sublib/factory.js:13:24:13:27 | name | This $@ that depends on $@ may run slow on strings with many repetitions of 'f'. | lib/sublib/factory.js:13:14:13:15 | f* | regular expression | lib/sublib/factory.js:12:26:12:29 | name | library input |
310319
| polynomial-redos.js:7:2:7:34 | tainted ... /g, '') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:7:2:7:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:7:24:7:26 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
311320
| polynomial-redos.js:8:2:8:23 | tainted ... *, */) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:8:2:8:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:8:17:8:18 | * | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
312321
| polynomial-redos.js:9:2:9:34 | tainted ... g, ' ') | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:9:2:9:8 | tainted | This $@ that depends on $@ may run slow on strings with many repetitions of ' '. | polynomial-redos.js:9:19:9:21 | \\s* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
(function (root, factory) {
3+
if (typeof define === 'function' && define.amd) {
4+
define('my-sub-library', factory);
5+
} else if (typeof exports === 'object') {
6+
module.exports = factory();
7+
} else {
8+
root.mySubLibrary = factory();
9+
}
10+
}(this, function () {
11+
function create() {
12+
return function (name) {
13+
/f*g/.test(name); // NOT OK
14+
}
15+
}
16+
return create()
17+
}));
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "my-sub-lib",
3+
"version": "0.0.7",
4+
"main": "./my-file.js"
5+
}

0 commit comments

Comments
 (0)