Skip to content

Commit eaee5c2

Browse files
committed
add library input as source for js/polynomial-redos
1 parent 1c8547c commit eaee5c2

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

javascript/ql/src/Performance/PolynomialReDoS.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,5 @@ where
2525
sink.getNode().(Sink).getRegExp().(PolynomialBackTrackingTerm).isAtEndLine()
2626
)
2727
select sink.getNode(), source, sink, "This expensive $@ use depends on $@.",
28-
sink.getNode().(Sink).getRegExp(), "regular expression", source.getNode(), "a user-provided value"
28+
sink.getNode().(Sink).getRegExp(), "regular expression", source.getNode(),
29+
source.getNode().(Source).describe()

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,17 @@ module PolynomialReDoS {
1313
*/
1414
abstract class Source extends DataFlow::Node {
1515
/**
16-
* Gets the kind of source that is being accesed. See `HTTP::RequestInputAccess::getKind()`.
17-
* Can be one of "parameter", "header", "body", "url", "cookie".
16+
* Gets the kind of source that is being accesed.
17+
*
18+
* Is either a kind from `HTTP::RequestInputAccess::getKind()`, or "library".
1819
*/
1920
abstract string getKind();
21+
22+
/**
23+
* Gets a string that describes the source.
24+
* For use in the alert message
25+
*/
26+
string describe() { result = "a user-provided value" }
2027
}
2128

2229
/**
@@ -108,4 +115,24 @@ module PolynomialReDoS {
108115
e = input.asExpr()
109116
}
110117
}
118+
119+
private import semmle.javascript.PackageExports as Exports
120+
121+
/**
122+
* A parameter of an exported function, seen as a source for polynomial-redos.
123+
*/
124+
class ExternalInputSource extends Source, DataFlow::ParameterNode {
125+
ExternalInputSource() {
126+
exists(int bound, DataFlow::FunctionNode func |
127+
func =
128+
Exports::getAValueExportedBy(Exports::getTopmostPackageJSON())
129+
.getABoundFunctionValue(bound) and
130+
this = func.getParameter(any(int arg | arg >= bound))
131+
)
132+
}
133+
134+
override string getKind() { result = "library" }
135+
136+
override string describe() { result = "library input" }
137+
}
111138
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
| highlight.js:38:54:38:59 | [^()]* | Strings starting with 'A((' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* |
2525
| highlight.js:38:64:38:69 | [^()]* | Strings starting with 'A(' and with many repetitions of ''' can start matching anywhere after the start of the preceeding [^()]* |
2626
| highlight.js:39:22:39:24 | \\w* | Strings starting with 'A' and with many repetitions of 'A' can start matching anywhere after the start of the preceeding [a-zA-Z_]\\w*\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{ |
27+
| 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 |
2728
| polynomial-redos.js:7:24:7:26 | \\s+ | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding \\s+$ |
2829
| polynomial-redos.js:8:17:8:18 | * | Strings with many repetitions of ' ' can start matching anywhere after the start of the preceeding *, * |
2930
| 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
@@ -1,4 +1,8 @@
11
nodes
2+
| lib/lib.js:3:28:3:31 | name |
3+
| lib/lib.js:3:28:3:31 | name |
4+
| lib/lib.js:4:14:4:17 | name |
5+
| lib/lib.js:4:14:4:17 | name |
26
| polynomial-redos.js:5:6:5:32 | tainted |
37
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
48
| polynomial-redos.js:5:16:5:32 | req.query.tainted |
@@ -135,6 +139,10 @@ nodes
135139
| polynomial-redos.js:118:2:118:8 | tainted |
136140
| polynomial-redos.js:118:2:118:8 | tainted |
137141
edges
142+
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
143+
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
144+
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
145+
| lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name |
138146
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
139147
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:7:2:7:8 | tainted |
140148
| polynomial-redos.js:5:6:5:32 | tainted | polynomial-redos.js:8:2:8:8 | tainted |
@@ -266,6 +274,7 @@ edges
266274
| polynomial-redos.js:68:18:68:24 | req.url | polynomial-redos.js:68:18:68:24 | req.url |
267275
| polynomial-redos.js:69:18:69:25 | req.body | polynomial-redos.js:69:18:69:25 | req.body |
268276
#select
277+
| lib/lib.js:4:14:4:17 | name | lib/lib.js:3:28:3:31 | name | lib/lib.js:4:14:4:17 | name | This expensive $@ use depends on $@. | lib/lib.js:1:15:1:16 | a* | regular expression | lib/lib.js:3:28:3:31 | name | library input |
269278
| polynomial-redos.js:7:2:7:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:7:2:7:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:7:24:7:26 | \\s+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
270279
| polynomial-redos.js:8:2:8:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:8:2:8:8 | tainted | This expensive $@ use depends on $@. | polynomial-redos.js:8:17:8:18 | * | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
271280
| polynomial-redos.js:9:2:9:8 | tainted | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:9:2:9:8 | tainted | This expensive $@ use depends on $@. | 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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
var regexp = /a*b/;
2+
3+
module.exports = function (name) {
4+
regexp.test(name); // NOT OK
5+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "myLib",
3+
"version": "0.0.7",
4+
"main": "./lib/lib.js"
5+
}

0 commit comments

Comments
 (0)