mirror of
https://github.com/github/codeql.git
synced 2026-05-03 04:39:29 +02:00
recognize sanitizing string replace call for regexp-injection
This commit is contained in:
@@ -55,4 +55,27 @@ module RegExpInjection {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A global regexp replacement involving the `{`, `[`, or `+` meta-character, viewed as a sanitizer for
|
||||
* regexp-injection vulnerabilities.
|
||||
*/
|
||||
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
|
||||
MetacharEscapeSanitizer() {
|
||||
isGlobal() and
|
||||
(
|
||||
RegExp::alwaysMatchesMetaCharacter(getRegExp().getRoot(), ["{", "[", "+"])
|
||||
or
|
||||
// or it's like a wild-card.
|
||||
RegExp::isWildcardLike(getRegExp().getRoot())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Meta characters used in the above sanitizer.
|
||||
*/
|
||||
private class RegexpMetaChars extends RegExp::MetaCharacter {
|
||||
RegexpMetaChars() { this = ["{", "[", "+"] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,18 @@ nodes
|
||||
| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) |
|
||||
| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") |
|
||||
| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") |
|
||||
| RegExpInjection.js:60:31:60:56 | input |
|
||||
| RegExpInjection.js:60:39:60:56 | req.param("input") |
|
||||
| RegExpInjection.js:60:39:60:56 | req.param("input") |
|
||||
| RegExpInjection.js:64:14:64:18 | input |
|
||||
| RegExpInjection.js:64:14:64:18 | input |
|
||||
| RegExpInjection.js:82:7:82:32 | input |
|
||||
| RegExpInjection.js:82:15:82:32 | req.param("input") |
|
||||
| RegExpInjection.js:82:15:82:32 | req.param("input") |
|
||||
| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" |
|
||||
| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" |
|
||||
| RegExpInjection.js:87:25:87:29 | input |
|
||||
| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") |
|
||||
| tst.js:1:46:1:46 | e |
|
||||
| tst.js:1:46:1:46 | e |
|
||||
| tst.js:2:9:2:21 | data |
|
||||
@@ -99,6 +111,16 @@ edges
|
||||
| RegExpInjection.js:54:14:54:27 | key.split(".") | RegExpInjection.js:54:14:54:42 | key.spl ... x => x) |
|
||||
| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") |
|
||||
| RegExpInjection.js:54:14:54:42 | key.spl ... x => x) | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") |
|
||||
| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input |
|
||||
| RegExpInjection.js:60:31:60:56 | input | RegExpInjection.js:64:14:64:18 | input |
|
||||
| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input |
|
||||
| RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:60:31:60:56 | input |
|
||||
| RegExpInjection.js:82:7:82:32 | input | RegExpInjection.js:87:25:87:29 | input |
|
||||
| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input |
|
||||
| RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:82:7:82:32 | input |
|
||||
| RegExpInjection.js:87:25:87:29 | input | RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") |
|
||||
| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" |
|
||||
| RegExpInjection.js:87:25:87:48 | input.r ... g, "\|") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" |
|
||||
| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e |
|
||||
| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e |
|
||||
| tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data |
|
||||
@@ -122,4 +144,6 @@ edges
|
||||
| RegExpInjection.js:47:22:47:26 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:47:22:47:26 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
|
||||
| RegExpInjection.js:50:46:50:50 | input | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:50:46:50:50 | input | This regular expression is constructed from a $@. | RegExpInjection.js:5:39:5:56 | req.param("input") | user-provided value |
|
||||
| RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:54:14:54:52 | key.spl ... in("-") | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value |
|
||||
| RegExpInjection.js:64:14:64:18 | input | RegExpInjection.js:60:39:60:56 | req.param("input") | RegExpInjection.js:64:14:64:18 | input | This regular expression is constructed from a $@. | RegExpInjection.js:60:39:60:56 | req.param("input") | user-provided value |
|
||||
| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | This regular expression is constructed from a $@. | RegExpInjection.js:82:15:82:32 | req.param("input") | user-provided value |
|
||||
| tst.js:3:16:3:35 | "^"+ data.name + "$" | tst.js:1:46:1:46 | e | tst.js:3:16:3:35 | "^"+ data.name + "$" | This regular expression is constructed from a $@. | tst.js:1:46:1:46 | e | user-provided value |
|
||||
|
||||
@@ -60,4 +60,29 @@ app.get('/findKey', function(req, res) {
|
||||
var key = req.param("key"), input = req.param("input");
|
||||
|
||||
Search.search(input); // OK!
|
||||
|
||||
new RegExp(input); // NOT OK
|
||||
|
||||
var sanitized = input.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||||
new RegExp(sanitized); // OK
|
||||
});
|
||||
|
||||
function escape1(pattern) {
|
||||
return pattern.replace(/[\x00-\x7f]/g,
|
||||
function(s) { return '\\x' + ('00' + s.charCodeAt().toString(16)).substr(-2); });
|
||||
}
|
||||
|
||||
function escape2(str){
|
||||
return str.replace(/([\.$?*|{}\(\)\[\]\\\/\+\-^])/g, function(ch){
|
||||
return "\\" + ch;
|
||||
});
|
||||
};
|
||||
|
||||
app.get('/has-sanitizer', function(req, res) {
|
||||
var input = req.param("input");
|
||||
|
||||
new RegExp(escape1(input)); // OK
|
||||
new RegExp(escape2(input)); // OK
|
||||
|
||||
new RegExp("^.*\.(" + input.replace(/,/g, "|") + ")$"); // NOT OK
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user