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