split sanitizer into three

This commit is contained in:
Jami Cogswell
2022-11-01 11:02:36 -04:00
parent 91491d9a7b
commit 5b089bbb9c
3 changed files with 25 additions and 13 deletions

View File

@@ -9,7 +9,7 @@ private import semmle.code.java.frameworks.apache.Lang
abstract class Sink extends DataFlow::ExprNode { }
/** A sanitizer for untrusted user input used to construct regular expressions. */
abstract class Sanitizer extends DataFlow::ExprNode { }
abstract class RegexInjectionSanitizer extends DataFlow::ExprNode { }
private class RegexInjectionSink extends Sink {
RegexInjectionSink() {
@@ -26,10 +26,9 @@ private class RegexInjectionSink extends Sink {
}
}
/** A call to a function which escapes regular expression meta-characters. */
private class RegexInjectionSanitizer extends Sanitizer {
RegexInjectionSanitizer() {
// a function whose name suggests that it escapes regular expression meta-characters
/** A call to a function whose name suggests that it escapes regular expression meta-characters. */
private class RegexSanitizationCall extends RegexInjectionSanitizer {
RegexSanitizationCall() {
exists(string calleeName, string sanitize, string regexp |
calleeName = this.asExpr().(Call).getCallee().getName() and
sanitize = "(?:escape|saniti[sz]e)" and
@@ -39,19 +38,32 @@ private class RegexInjectionSanitizer extends Sanitizer {
.regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
".*)")
)
or
// a call to the `Pattern.quote` method, which gives metacharacters or escape sequences no special meaning
}
}
/**
* A call to the `Pattern.quote` method, which gives metacharacters or escape sequences
* no special meaning.
*/
private class PatternQuoteCall extends RegexInjectionSanitizer {
PatternQuoteCall() {
exists(MethodAccess ma, Method m | m = ma.getMethod() |
ma.getArgument(0) = this.asExpr() and
m instanceof PatternQuoteMethod
)
or
// use of Pattern.LITERAL flag with `Pattern.compile` which gives metacharacters or escape sequences no special meaning
}
}
/**
* Use of the `Pattern.LITERAL` flag with `Pattern.compile`, which gives metacharacters
* or escape sequences no special meaning.
*/
private class PatternLiteralFlag extends RegexInjectionSanitizer {
PatternLiteralFlag() {
exists(MethodAccess ma, Method m, Field field | m = ma.getMethod() |
ma.getArgument(0) = this.asExpr() and
m instanceof PatternRegexMethod and
m.hasName("compile") and
//ma.getArgument(1).toString() = "Pattern.LITERAL" and
field instanceof PatternLiteral and
ma.getArgument(1) = field.getAnAccess()
)

View File

@@ -13,5 +13,5 @@ class RegexInjectionConfiguration extends TaintTracking::Configuration {
override predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer }
override predicate isSanitizer(DataFlow::Node node) { node instanceof RegexInjectionSanitizer }
}

View File

@@ -183,7 +183,7 @@ public class RegexInjectionTest extends HttpServlet {
return RegExUtils.replacePattern(input, pattern, "").length() > 0; // $ hasRegexInjection
}
// test `Pattern.quote` as safe
// test `Pattern.quote` sanitizer
public boolean quoteTest(javax.servlet.http.HttpServletRequest request) {
String regex = request.getParameter("regex");
String input = request.getParameter("input");
@@ -191,7 +191,7 @@ public class RegexInjectionTest extends HttpServlet {
return input.matches(Pattern.quote(regex)); // Safe
}
// test `Pattern.LITERAL` as safe
// test `Pattern.LITERAL` sanitizer
public boolean literalTest(javax.servlet.http.HttpServletRequest request) {
String pattern = request.getParameter("pattern");
String input = request.getParameter("input");