Skip to content

Commit b945466

Browse files
authored
Merge pull request #18892 from asgerf/js/membership-regexp-test
JS: Sharpen up EnumerationRegExp
2 parents 79e0615 + 2e32e44 commit b945466

File tree

5 files changed

+21
-11
lines changed

5 files changed

+21
-11
lines changed

javascript/ql/lib/semmle/javascript/MembershipCandidates.qll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,17 @@ module MembershipCandidate {
140140
EnumerationRegExp() {
141141
this.isRootTerm() and
142142
RegExp::isFullyAnchoredTerm(this) and
143-
exists(RegExpTerm child | this.getAChild*() = child |
144-
child instanceof RegExpSequence or
145-
child instanceof RegExpCaret or
146-
child instanceof RegExpDollar or
147-
child instanceof RegExpConstant or
148-
child instanceof RegExpAlt or
149-
child instanceof RegExpGroup
150-
) and
151-
// exclude "length matches" that match every string
152-
not this.getAChild*() instanceof RegExpDot
143+
not exists(RegExpTerm child | child.getRootTerm() = this |
144+
child instanceof RegExpDot or
145+
child instanceof RegExpCharacterClass or
146+
child instanceof RegExpUnicodePropertyEscape
147+
)
153148
}
154149

155150
/**
156151
* Gets a string matched by this regular expression.
157152
*/
158-
string getAMember() { result = this.getAChild*().getAMatchedString() }
153+
string getAMember() { result = any(RegExpTerm t | t.getRootTerm() = this).getAMatchedString() }
159154
}
160155

161156
/**
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
category: fix
3+
---
4+
* Fixed a bug that would in rare cases cause some regexp-based checks
5+
to be seen as generic taint sanitisers, even though the underlying regexp
6+
is not restrictive enough. The regexps are now analysed more precisely,
7+
and unrestrictive regexp checks will no longer block taint flow.

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ flow
238238
| promise.js:18:22:18:29 | source() | promise.js:24:10:24:10 | e |
239239
| promise.js:33:21:33:28 | source() | promise.js:38:10:38:10 | e |
240240
| promise.js:43:20:43:27 | source() | promise.js:43:8:43:28 | Promise ... urce()) |
241+
| regexp-sanitiser.js:2:19:2:26 | source() | regexp-sanitiser.js:4:14:4:18 | taint |
241242
| rxjs.js:3:1:3:8 | source() | rxjs.js:10:14:10:17 | data |
242243
| rxjs.js:13:1:13:8 | source() | rxjs.js:17:23:17:23 | x |
243244
| rxjs.js:13:1:13:8 | source() | rxjs.js:18:23:18:23 | x |

javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ flow
161161
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value |
162162
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:41:10:41:18 | id(taint) |
163163
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:51:14:51:14 | x |
164+
| regexp-sanitiser.js:2:19:2:26 | source() | regexp-sanitiser.js:4:14:4:18 | taint |
164165
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint |
165166
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:17:14:17:18 | taint |
166167
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:21:14:21:18 | taint |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function foo() {
2+
const taint = source();
3+
if (/^asd[\s\S]*$/.test(taint)) {
4+
sink(taint); // NOT OK
5+
}
6+
}

0 commit comments

Comments
 (0)