Skip to content

Commit 13655b5

Browse files
author
edvraa
committed
Add RegExUtils
1 parent 29e3206 commit 13655b5

File tree

4 files changed

+138
-43
lines changed

4 files changed

+138
-43
lines changed

java/ql/src/experimental/Security/CWE/CWE-730/RegexInjection.ql

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,39 @@ class RegexSink extends DataFlow::ExprNode {
2121
RegexSink() {
2222
exists(MethodAccess ma, Method m | m = ma.getMethod() |
2323
(
24-
ma.getArgument(0) = this.asExpr() and
24+
m.getDeclaringType().hasQualifiedName("java.lang", "String") and
2525
(
26-
m.getDeclaringType().hasQualifiedName("java.lang", "String") and
26+
ma.getArgument(0) = this.asExpr() and
2727
(
2828
m.hasName("matches") or
2929
m.hasName("split") or
3030
m.hasName("replaceFirst") or
3131
m.hasName("replaceAll")
3232
)
33-
or
34-
m.getDeclaringType().hasQualifiedName("java.util.regex", "Pattern") and
33+
)
34+
or
35+
m.getDeclaringType().hasQualifiedName("java.util.regex", "Pattern") and
36+
(
37+
ma.getArgument(0) = this.asExpr() and
3538
(
3639
m.hasName("compile") or
3740
m.hasName("matches")
3841
)
3942
)
43+
or
44+
m.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "RegExUtils") and
45+
(
46+
ma.getArgument(1) = this.asExpr() and
47+
m.getParameterType(1).(Class).hasQualifiedName("java.lang", "String") and
48+
(
49+
m.hasName("removeAll") or
50+
m.hasName("removeFirst") or
51+
m.hasName("removePattern") or
52+
m.hasName("replaceAll") or
53+
m.hasName("replaceFirst") or
54+
m.hasName("replacePattern")
55+
)
56+
)
4057
)
4158
)
4259
}
@@ -51,7 +68,9 @@ class RegExpSanitizationCall extends Sanitizer {
5168
sanitize = "(?:escape|saniti[sz]e)" and
5269
regexp = "regexp?"
5370
|
54-
calleeName.regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize + ".*)")
71+
calleeName
72+
.regexpMatch("(?i)(" + sanitize + ".*" + regexp + ".*)" + "|(" + regexp + ".*" + sanitize +
73+
".*)")
5574
)
5675
}
5776
}
Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,63 @@
11
edges
2-
| RegexInjection.java:11:22:11:52 | getParameter(...) : String | RegexInjection.java:14:26:14:47 | ... + ... |
3-
| RegexInjection.java:18:22:18:52 | getParameter(...) : String | RegexInjection.java:21:24:21:30 | pattern |
4-
| RegexInjection.java:25:22:25:52 | getParameter(...) : String | RegexInjection.java:28:31:28:37 | pattern |
5-
| RegexInjection.java:32:22:32:52 | getParameter(...) : String | RegexInjection.java:35:29:35:35 | pattern |
6-
| RegexInjection.java:39:22:39:52 | getParameter(...) : String | RegexInjection.java:42:34:42:40 | pattern |
7-
| RegexInjection.java:49:22:49:52 | getParameter(...) : String | RegexInjection.java:52:28:52:34 | pattern |
8-
| RegexInjection.java:56:22:56:52 | getParameter(...) : String | RegexInjection.java:59:28:59:34 | pattern |
9-
| RegexInjection.java:63:22:63:52 | getParameter(...) : String | RegexInjection.java:66:36:66:42 | pattern : String |
10-
| RegexInjection.java:66:32:66:43 | foo(...) : String | RegexInjection.java:66:26:66:52 | ... + ... |
11-
| RegexInjection.java:66:36:66:42 | pattern : String | RegexInjection.java:66:32:66:43 | foo(...) : String |
2+
| RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... |
3+
| RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern |
4+
| RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern |
5+
| RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern |
6+
| RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern |
7+
| RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern |
8+
| RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern |
9+
| RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:36:68:42 | pattern : String |
10+
| RegexInjection.java:68:32:68:43 | foo(...) : String | RegexInjection.java:68:26:68:52 | ... + ... |
11+
| RegexInjection.java:68:36:68:42 | pattern : String | RegexInjection.java:68:32:68:43 | foo(...) : String |
12+
| RegexInjection.java:90:22:90:52 | getParameter(...) : String | RegexInjection.java:93:40:93:46 | pattern |
13+
| RegexInjection.java:97:22:97:52 | getParameter(...) : String | RegexInjection.java:100:42:100:48 | pattern |
14+
| RegexInjection.java:104:22:104:52 | getParameter(...) : String | RegexInjection.java:107:44:107:50 | pattern |
15+
| RegexInjection.java:111:22:111:52 | getParameter(...) : String | RegexInjection.java:114:41:114:47 | pattern |
16+
| RegexInjection.java:118:22:118:52 | getParameter(...) : String | RegexInjection.java:121:43:121:49 | pattern |
17+
| RegexInjection.java:133:22:133:52 | getParameter(...) : String | RegexInjection.java:136:45:136:51 | pattern |
1218
nodes
13-
| RegexInjection.java:11:22:11:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
14-
| RegexInjection.java:14:26:14:47 | ... + ... | semmle.label | ... + ... |
15-
| RegexInjection.java:18:22:18:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
16-
| RegexInjection.java:21:24:21:30 | pattern | semmle.label | pattern |
17-
| RegexInjection.java:25:22:25:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
18-
| RegexInjection.java:28:31:28:37 | pattern | semmle.label | pattern |
19-
| RegexInjection.java:32:22:32:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
20-
| RegexInjection.java:35:29:35:35 | pattern | semmle.label | pattern |
21-
| RegexInjection.java:39:22:39:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
22-
| RegexInjection.java:42:34:42:40 | pattern | semmle.label | pattern |
23-
| RegexInjection.java:49:22:49:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
24-
| RegexInjection.java:52:28:52:34 | pattern | semmle.label | pattern |
25-
| RegexInjection.java:56:22:56:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
26-
| RegexInjection.java:59:28:59:34 | pattern | semmle.label | pattern |
27-
| RegexInjection.java:63:22:63:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
28-
| RegexInjection.java:66:26:66:52 | ... + ... | semmle.label | ... + ... |
29-
| RegexInjection.java:66:32:66:43 | foo(...) : String | semmle.label | foo(...) : String |
30-
| RegexInjection.java:66:36:66:42 | pattern : String | semmle.label | pattern : String |
19+
| RegexInjection.java:13:22:13:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
20+
| RegexInjection.java:16:26:16:47 | ... + ... | semmle.label | ... + ... |
21+
| RegexInjection.java:20:22:20:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
22+
| RegexInjection.java:23:24:23:30 | pattern | semmle.label | pattern |
23+
| RegexInjection.java:27:22:27:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
24+
| RegexInjection.java:30:31:30:37 | pattern | semmle.label | pattern |
25+
| RegexInjection.java:34:22:34:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
26+
| RegexInjection.java:37:29:37:35 | pattern | semmle.label | pattern |
27+
| RegexInjection.java:41:22:41:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
28+
| RegexInjection.java:44:34:44:40 | pattern | semmle.label | pattern |
29+
| RegexInjection.java:51:22:51:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
30+
| RegexInjection.java:54:28:54:34 | pattern | semmle.label | pattern |
31+
| RegexInjection.java:58:22:58:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
32+
| RegexInjection.java:61:28:61:34 | pattern | semmle.label | pattern |
33+
| RegexInjection.java:65:22:65:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
34+
| RegexInjection.java:68:26:68:52 | ... + ... | semmle.label | ... + ... |
35+
| RegexInjection.java:68:32:68:43 | foo(...) : String | semmle.label | foo(...) : String |
36+
| RegexInjection.java:68:36:68:42 | pattern : String | semmle.label | pattern : String |
37+
| RegexInjection.java:90:22:90:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
38+
| RegexInjection.java:93:40:93:46 | pattern | semmle.label | pattern |
39+
| RegexInjection.java:97:22:97:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
40+
| RegexInjection.java:100:42:100:48 | pattern | semmle.label | pattern |
41+
| RegexInjection.java:104:22:104:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
42+
| RegexInjection.java:107:44:107:50 | pattern | semmle.label | pattern |
43+
| RegexInjection.java:111:22:111:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
44+
| RegexInjection.java:114:41:114:47 | pattern | semmle.label | pattern |
45+
| RegexInjection.java:118:22:118:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
46+
| RegexInjection.java:121:43:121:49 | pattern | semmle.label | pattern |
47+
| RegexInjection.java:133:22:133:52 | getParameter(...) : String | semmle.label | getParameter(...) : String |
48+
| RegexInjection.java:136:45:136:51 | pattern | semmle.label | pattern |
3149
#select
32-
| RegexInjection.java:14:26:14:47 | ... + ... | RegexInjection.java:11:22:11:52 | getParameter(...) : String | RegexInjection.java:14:26:14:47 | ... + ... | $@ is user controlled. | RegexInjection.java:11:22:11:52 | getParameter(...) | This regular expression pattern |
33-
| RegexInjection.java:21:24:21:30 | pattern | RegexInjection.java:18:22:18:52 | getParameter(...) : String | RegexInjection.java:21:24:21:30 | pattern | $@ is user controlled. | RegexInjection.java:18:22:18:52 | getParameter(...) | This regular expression pattern |
34-
| RegexInjection.java:28:31:28:37 | pattern | RegexInjection.java:25:22:25:52 | getParameter(...) : String | RegexInjection.java:28:31:28:37 | pattern | $@ is user controlled. | RegexInjection.java:25:22:25:52 | getParameter(...) | This regular expression pattern |
35-
| RegexInjection.java:35:29:35:35 | pattern | RegexInjection.java:32:22:32:52 | getParameter(...) : String | RegexInjection.java:35:29:35:35 | pattern | $@ is user controlled. | RegexInjection.java:32:22:32:52 | getParameter(...) | This regular expression pattern |
36-
| RegexInjection.java:42:34:42:40 | pattern | RegexInjection.java:39:22:39:52 | getParameter(...) : String | RegexInjection.java:42:34:42:40 | pattern | $@ is user controlled. | RegexInjection.java:39:22:39:52 | getParameter(...) | This regular expression pattern |
37-
| RegexInjection.java:52:28:52:34 | pattern | RegexInjection.java:49:22:49:52 | getParameter(...) : String | RegexInjection.java:52:28:52:34 | pattern | $@ is user controlled. | RegexInjection.java:49:22:49:52 | getParameter(...) | This regular expression pattern |
38-
| RegexInjection.java:59:28:59:34 | pattern | RegexInjection.java:56:22:56:52 | getParameter(...) : String | RegexInjection.java:59:28:59:34 | pattern | $@ is user controlled. | RegexInjection.java:56:22:56:52 | getParameter(...) | This regular expression pattern |
39-
| RegexInjection.java:66:26:66:52 | ... + ... | RegexInjection.java:63:22:63:52 | getParameter(...) : String | RegexInjection.java:66:26:66:52 | ... + ... | $@ is user controlled. | RegexInjection.java:63:22:63:52 | getParameter(...) | This regular expression pattern |
50+
| RegexInjection.java:16:26:16:47 | ... + ... | RegexInjection.java:13:22:13:52 | getParameter(...) : String | RegexInjection.java:16:26:16:47 | ... + ... | $@ is user controlled. | RegexInjection.java:13:22:13:52 | getParameter(...) | This regular expression pattern |
51+
| RegexInjection.java:23:24:23:30 | pattern | RegexInjection.java:20:22:20:52 | getParameter(...) : String | RegexInjection.java:23:24:23:30 | pattern | $@ is user controlled. | RegexInjection.java:20:22:20:52 | getParameter(...) | This regular expression pattern |
52+
| RegexInjection.java:30:31:30:37 | pattern | RegexInjection.java:27:22:27:52 | getParameter(...) : String | RegexInjection.java:30:31:30:37 | pattern | $@ is user controlled. | RegexInjection.java:27:22:27:52 | getParameter(...) | This regular expression pattern |
53+
| RegexInjection.java:37:29:37:35 | pattern | RegexInjection.java:34:22:34:52 | getParameter(...) : String | RegexInjection.java:37:29:37:35 | pattern | $@ is user controlled. | RegexInjection.java:34:22:34:52 | getParameter(...) | This regular expression pattern |
54+
| RegexInjection.java:44:34:44:40 | pattern | RegexInjection.java:41:22:41:52 | getParameter(...) : String | RegexInjection.java:44:34:44:40 | pattern | $@ is user controlled. | RegexInjection.java:41:22:41:52 | getParameter(...) | This regular expression pattern |
55+
| RegexInjection.java:54:28:54:34 | pattern | RegexInjection.java:51:22:51:52 | getParameter(...) : String | RegexInjection.java:54:28:54:34 | pattern | $@ is user controlled. | RegexInjection.java:51:22:51:52 | getParameter(...) | This regular expression pattern |
56+
| RegexInjection.java:61:28:61:34 | pattern | RegexInjection.java:58:22:58:52 | getParameter(...) : String | RegexInjection.java:61:28:61:34 | pattern | $@ is user controlled. | RegexInjection.java:58:22:58:52 | getParameter(...) | This regular expression pattern |
57+
| RegexInjection.java:68:26:68:52 | ... + ... | RegexInjection.java:65:22:65:52 | getParameter(...) : String | RegexInjection.java:68:26:68:52 | ... + ... | $@ is user controlled. | RegexInjection.java:65:22:65:52 | getParameter(...) | This regular expression pattern |
58+
| RegexInjection.java:93:40:93:46 | pattern | RegexInjection.java:90:22:90:52 | getParameter(...) : String | RegexInjection.java:93:40:93:46 | pattern | $@ is user controlled. | RegexInjection.java:90:22:90:52 | getParameter(...) | This regular expression pattern |
59+
| RegexInjection.java:100:42:100:48 | pattern | RegexInjection.java:97:22:97:52 | getParameter(...) : String | RegexInjection.java:100:42:100:48 | pattern | $@ is user controlled. | RegexInjection.java:97:22:97:52 | getParameter(...) | This regular expression pattern |
60+
| RegexInjection.java:107:44:107:50 | pattern | RegexInjection.java:104:22:104:52 | getParameter(...) : String | RegexInjection.java:107:44:107:50 | pattern | $@ is user controlled. | RegexInjection.java:104:22:104:52 | getParameter(...) | This regular expression pattern |
61+
| RegexInjection.java:114:41:114:47 | pattern | RegexInjection.java:111:22:111:52 | getParameter(...) : String | RegexInjection.java:114:41:114:47 | pattern | $@ is user controlled. | RegexInjection.java:111:22:111:52 | getParameter(...) | This regular expression pattern |
62+
| RegexInjection.java:121:43:121:49 | pattern | RegexInjection.java:118:22:118:52 | getParameter(...) : String | RegexInjection.java:121:43:121:49 | pattern | $@ is user controlled. | RegexInjection.java:118:22:118:52 | getParameter(...) | This regular expression pattern |
63+
| RegexInjection.java:136:45:136:51 | pattern | RegexInjection.java:133:22:133:52 | getParameter(...) : String | RegexInjection.java:136:45:136:51 | pattern | $@ is user controlled. | RegexInjection.java:133:22:133:52 | getParameter(...) | This regular expression pattern |

java/ql/test/experimental/query-tests/security/CWE-730/RegexInjection.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import javax.servlet.http.HttpServletResponse;
77
import javax.servlet.ServletException;
88

9+
import org.apache.commons.lang3.RegExUtils;
10+
911
public class RegexInjection extends HttpServlet {
1012
public boolean string1(javax.servlet.http.HttpServletRequest request) {
1113
String pattern = request.getParameter("pattern");
@@ -83,4 +85,54 @@ public boolean pattern5(javax.servlet.http.HttpServletRequest request) {
8385
String escapeSpecialRegexChars(String str) {
8486
return SPECIAL_REGEX_CHARS.matcher(str).replaceAll("\\\\$0");
8587
}
86-
}
88+
89+
public boolean apache1(javax.servlet.http.HttpServletRequest request) {
90+
String pattern = request.getParameter("pattern");
91+
String input = request.getParameter("input");
92+
93+
return RegExUtils.removeAll(input, pattern).length() > 0; // BAD
94+
}
95+
96+
public boolean apache2(javax.servlet.http.HttpServletRequest request) {
97+
String pattern = request.getParameter("pattern");
98+
String input = request.getParameter("input");
99+
100+
return RegExUtils.removeFirst(input, pattern).length() > 0; // BAD
101+
}
102+
103+
public boolean apache3(javax.servlet.http.HttpServletRequest request) {
104+
String pattern = request.getParameter("pattern");
105+
String input = request.getParameter("input");
106+
107+
return RegExUtils.removePattern(input, pattern).length() > 0; // BAD
108+
}
109+
110+
public boolean apache4(javax.servlet.http.HttpServletRequest request) {
111+
String pattern = request.getParameter("pattern");
112+
String input = request.getParameter("input");
113+
114+
return RegExUtils.replaceAll(input, pattern, "").length() > 0; // BAD
115+
}
116+
117+
public boolean apache5(javax.servlet.http.HttpServletRequest request) {
118+
String pattern = request.getParameter("pattern");
119+
String input = request.getParameter("input");
120+
121+
return RegExUtils.replaceFirst(input, pattern, "").length() > 0; // BAD
122+
}
123+
124+
public boolean apache6(javax.servlet.http.HttpServletRequest request) {
125+
String pattern = request.getParameter("pattern");
126+
String input = request.getParameter("input");
127+
128+
Pattern pt = (Pattern)(Object) pattern;
129+
return RegExUtils.replaceFirst(input, pt, "").length() > 0; // GOOD, Pattern compile is the sink instead
130+
}
131+
132+
public boolean apache7(javax.servlet.http.HttpServletRequest request) {
133+
String pattern = request.getParameter("pattern");
134+
String input = request.getParameter("input");
135+
136+
return RegExUtils.replacePattern(input, pattern, "").length() > 0; // BAD
137+
}
138+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4
1+
// semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/servlet-api-2.4:${testdir}/../../../../stubs/apache-commons-lang3-3.7

0 commit comments

Comments
 (0)