33import java
44private import semmle.code.java.dataflow.DataFlow
55private import semmle.code.java.frameworks.Regex
6- private import semmle.code.java.frameworks.apache.Lang
6+ //private import semmle.code.java.frameworks.apache.Lang
7+ private import semmle.code.java.regex.RegexFlowModels
78
89/** A data flow sink for untrusted user input used to construct regular expressions. */
910abstract class RegexInjectionSink extends DataFlow::ExprNode { }
@@ -14,36 +15,41 @@ abstract class RegexInjectionSanitizer extends DataFlow::ExprNode { }
1415/** A method call that takes a regular expression as an argument. */
1516private class DefaultRegexInjectionSink extends RegexInjectionSink {
1617 DefaultRegexInjectionSink() {
17- exists(MethodAccess ma, Method m | m = ma.getMethod() |
18- ma.getArgument(0) = this.asExpr() and
19- (
20- m instanceof StringRegexMethod or
21- m instanceof PatternRegexMethod
22- )
23- or
24- ma.getArgument(1) = this.asExpr() and
25- m instanceof ApacheRegExUtilsMethod
18+ exists(string kind |
19+ kind.matches([
20+ "regex-use[]", "regex-use[f1]", "regex-use[f-1]", "regex-use[-1]", "regex-use[0]"
21+ ]) and
22+ sinkNode(this, kind)
2623 )
2724 }
2825}
2926
3027/** A call to a function whose name suggests that it escapes regular expression meta-characters. */
3128private class RegexSanitizationCall extends RegexInjectionSanitizer {
3229 RegexSanitizationCall() {
33- exists(string calleeName, string sanitize, string regexp |
30+ // original
31+ // exists(string calleeName, string sanitize, string regexp |
32+ // calleeName = this.asExpr().(Call).getCallee().getName() and
33+ // sanitize = "(?:escape|saniti[sz]e)" and
34+ // regexp = "regexp?"
35+ // |
36+ // calleeName
37+ // .regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
38+ // ".*)")
39+ // )
40+ // without regexp
41+ exists(string calleeName, string sanitize |
3442 calleeName = this.asExpr().(Call).getCallee().getName() and
35- sanitize = "(?:escape|saniti[sz]e)" and
36- regexp = "regexp?"
43+ sanitize = "(?:escape|saniti[sz]e)"
3744 |
38- calleeName
39- .regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
40- ".*)")
45+ calleeName.regexpMatch("(?i)(.*" + sanitize + ".*)")
46+ //calleeName.matches("handleEscapes")
4147 )
4248 }
4349}
4450
4551/**
46- * A call to the `Pattern.quote` method, which gives meta-characters or escape sequences
52+ * A call to the `Pattern.quote` method, which gives metacharacters or escape sequences
4753 * no special meaning.
4854 */
4955private class PatternQuoteCall extends RegexInjectionSanitizer {
@@ -56,54 +62,17 @@ private class PatternQuoteCall extends RegexInjectionSanitizer {
5662}
5763
5864/**
59- * Use of the `Pattern.LITERAL` flag with `Pattern.compile`, which gives meta-characters
65+ * Use of the `Pattern.LITERAL` flag with `Pattern.compile`, which gives metacharacters
6066 * or escape sequences no special meaning.
6167 */
6268private class PatternLiteralFlag extends RegexInjectionSanitizer {
6369 PatternLiteralFlag() {
6470 exists(MethodAccess ma, Method m, Field field | m = ma.getMethod() |
6571 ma.getArgument(0) = this.asExpr() and
66- m instanceof PatternRegexMethod and
72+ m.getDeclaringType() instanceof TypeRegexPattern and
6773 m.hasName("compile") and
68- field instanceof PatternLiteral and
74+ field instanceof PatternLiteralField and
6975 ma.getArgument(1) = field.getAnAccess()
7076 )
7177 }
7278}
73-
74- /**
75- * A method of the class `java.lang.String` that takes a regular expression
76- * as a parameter.
77- */
78- private class StringRegexMethod extends Method {
79- StringRegexMethod() {
80- this.getDeclaringType() instanceof TypeString and
81- this.hasName(["matches", "split", "replaceFirst", "replaceAll"])
82- }
83- }
84-
85- /**
86- * A method of the class `java.util.regex.Pattern` that takes a regular
87- * expression as a parameter.
88- */
89- private class PatternRegexMethod extends Method {
90- PatternRegexMethod() {
91- this.getDeclaringType() instanceof TypeRegexPattern and
92- this.hasName(["compile", "matches"])
93- }
94- }
95-
96- /**
97- * A methods of the class `org.apache.commons.lang3.RegExUtils` that takes
98- * a regular expression of type `String` as a parameter.
99- */
100- private class ApacheRegExUtilsMethod extends Method {
101- ApacheRegExUtilsMethod() {
102- this.getDeclaringType() instanceof TypeApacheRegExUtils and
103- // only handles String param here because the other param option, Pattern, is already handled by `java.util.regex.Pattern`
104- this.getParameterType(1) instanceof TypeString and
105- this.hasName([
106- "removeAll", "removeFirst", "removePattern", "replaceAll", "replaceFirst", "replacePattern"
107- ])
108- }
109- }
0 commit comments