Skip to content

Commit be548c1

Browse files
Jami CogswellJami Cogswell
authored andcommitted
switch sink to use csv models
1 parent 5dcd3b2 commit be548c1

File tree

4 files changed

+35
-65
lines changed

4 files changed

+35
-65
lines changed

java/ql/lib/semmle/code/java/frameworks/Regex.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ class TypeRegexPattern extends Class {
1111
class PatternQuoteMethod extends Method {
1212
PatternQuoteMethod() {
1313
this.getDeclaringType() instanceof TypeRegexPattern and
14-
this.hasName(["quote"])
14+
this.hasName("quote")
1515
}
1616
}
1717

1818
/** The `LITERAL` field of the `java.util.regex.Pattern` class. */
19-
class PatternLiteral extends Field {
20-
PatternLiteral() {
19+
class PatternLiteralField extends Field {
20+
PatternLiteralField() {
2121
this.getDeclaringType() instanceof TypeRegexPattern and
2222
this.hasName("LITERAL")
2323
}

java/ql/lib/semmle/code/java/frameworks/apache/Lang.qll

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,3 @@ class TypeApacheSystemUtils extends Class {
4646
this.hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], "SystemUtils")
4747
}
4848
}
49-
50-
/** The class `org.apache.commons.lang3.RegExUtils`. */
51-
class TypeApacheRegExUtils extends Class {
52-
TypeApacheRegExUtils() { this.hasQualifiedName("org.apache.commons.lang3", "RegExUtils") }
53-
}

java/ql/lib/semmle/code/java/regex/RegexFlowModels.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ private class RegexSinkCsv extends SinkModelCsv {
2727
"com.google.common.base;Splitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual",
2828
"com.google.common.base;Splitter;false;splitToList;(CharSequence);;Argument[-1];regex-use[0];manual",
2929
"com.google.common.base;Splitter$MapSplitter;false;split;(CharSequence);;Argument[-1];regex-use[0];manual",
30+
"org.apache.commons.lang3;RegExUtils;false;removeAll;(String,String);;Argument[1];regex-use[0];manual",
31+
"org.apache.commons.lang3;RegExUtils;false;removeFirst;(String,String);;Argument[1];regex-use[0];manual",
32+
"org.apache.commons.lang3;RegExUtils;false;removePattern;(String,String);;Argument[1];regex-use[0];manual",
33+
"org.apache.commons.lang3;RegExUtils;false;replaceAll;(String,String,String);;Argument[1];regex-use[0];manual",
34+
"org.apache.commons.lang3;RegExUtils;false;replaceFirst;(String,String,String);;Argument[1];regex-use[0];manual",
35+
"org.apache.commons.lang3;RegExUtils;false;replacePattern;(String,String,String);;Argument[1];regex-use[0];manual",
3036
]
3137
}
3238
}

java/ql/lib/semmle/code/java/security/RegexInjection.qll

Lines changed: 26 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import java
44
private import semmle.code.java.dataflow.DataFlow
55
private 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. */
910
abstract 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. */
1516
private 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. */
3128
private 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
*/
4955
private 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
*/
6268
private 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

Comments
 (0)