Merge pull request #5901 from erik-krogh/regFP

Approved by asgerf
This commit is contained in:
CodeQL CI
2021-06-08 04:14:06 -07:00
committed by GitHub
4 changed files with 77 additions and 2 deletions

View File

@@ -1237,8 +1237,18 @@ module RegExp {
}
}
private class DefaultMetaCharacter extends MetaCharacter {
DefaultMetaCharacter() { this = ["<", "'", "\""] }
/**
* A meta character used by HTML.
*/
private class HTMLMetaCharacter extends MetaCharacter {
HTMLMetaCharacter() { this = ["<", "'", "\""] }
}
/**
* A meta character used by regular expressions.
*/
private class RegexpMetaChars extends RegExp::MetaCharacter {
RegexpMetaChars() { this = ["{", "[", "+"] }
}
/**

View File

@@ -55,4 +55,20 @@ 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())
)
}
}
}

View File

@@ -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 |

View File

@@ -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
});