Skip to content

Commit f5702f5

Browse files
committed
Address review comment
Handle more regex cases that cover line breaks
1 parent e167d3c commit f5702f5

File tree

2 files changed

+64
-6
lines changed

2 files changed

+64
-6
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ private predicate logInjectionSanitizer(MethodAccess ma) {
6868
(
6969
// Replace anything not in an allow list
7070
target.getStringValue().matches("[^%]") and
71-
not target.getStringValue().matches(["%\n%", "%\r%"])
71+
not target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%")
7272
or
7373
// Replace line breaks
74-
target.getStringValue() = ["\n", "\r"]
74+
target.getStringValue() = ["\n", "\r", "\\n", "\\r", "\\R"]
7575
)
7676
)
7777
}
@@ -103,17 +103,17 @@ private predicate logInjectionGuard(Guard g, Expr e, boolean branch) {
103103
// Allow anything except line breaks
104104
(
105105
not target.getStringValue().matches("%[^%]%") and
106-
not target.getStringValue().matches(["%\n%", "%\r%"])
106+
not target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%")
107107
or
108-
target.getStringValue().matches(["%[^%\n%]%", "%[^%\r%]%"])
108+
target.getStringValue().matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%")
109109
) and
110110
branch = true
111111
or
112112
// Disallow line breaks
113113
(
114-
not target.getStringValue().matches(["%[^%\n%]%", "%[^%\r%]%"]) and
114+
not target.getStringValue().matches("%[^%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%]%") and
115115
// Assuming a regex containing line breaks is correctly matching line breaks in a string
116-
target.getStringValue().matches(["%\n%", "%\r%"])
116+
target.getStringValue().matches("%" + ["\n", "\r", "\\n", "\\r", "\\R"] + "%")
117117
) and
118118
branch = false
119119
)

java/ql/test/query-tests/security/CWE-117/LogInjectionTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,21 @@ public void testSanitizers() {
4343
logger.debug(source.replaceAll("\r", "")); // Safe
4444
logger.debug(source.replaceAll("\r", "\n")); // $ hasTaintFlow
4545
logger.debug(source.replaceAll("\r", "\r")); // $ hasTaintFlow
46+
logger.debug(source.replaceAll("\\n", "")); // Safe
47+
logger.debug(source.replaceAll("\\n", "\n")); // $ hasTaintFlow
48+
logger.debug(source.replaceAll("\\n", "\r")); // $ hasTaintFlow
49+
logger.debug(source.replaceAll("\\r", "")); // Safe
50+
logger.debug(source.replaceAll("\\r", "\n")); // $ hasTaintFlow
51+
logger.debug(source.replaceAll("\\r", "\r")); // $ hasTaintFlow
52+
logger.debug(source.replaceAll("\\R", "")); // Safe
53+
logger.debug(source.replaceAll("\\R", "\n")); // $ hasTaintFlow
54+
logger.debug(source.replaceAll("\\R", "\r")); // $ hasTaintFlow
4655
logger.debug(source.replaceAll("[^a-zA-Z]", "")); // Safe
4756
logger.debug(source.replaceAll("[^a-zA-Z]", "\n")); // $ hasTaintFlow
4857
logger.debug(source.replaceAll("[^a-zA-Z]", "\r")); // $ hasTaintFlow
4958
logger.debug(source.replaceAll("[^a-zA-Z\n]", "")); // $ hasTaintFlow
5059
logger.debug(source.replaceAll("[^a-zA-Z\r]", "")); // $ hasTaintFlow
60+
logger.debug(source.replaceAll("[^a-zA-Z\\R]", "")); // $ hasTaintFlow
5161
}
5262

5363
public void testGuards() {
@@ -66,6 +76,18 @@ public void testGuards() {
6676
logger.debug(source); // Safe
6777
}
6878

79+
if (source.matches(".*\\n.*")) {
80+
logger.debug(source); // $ hasTaintFlow
81+
} else {
82+
logger.debug(source); // Safe
83+
}
84+
85+
if (Pattern.matches(".*\\n.*", source)) {
86+
logger.debug(source); // $ hasTaintFlow
87+
} else {
88+
logger.debug(source); // Safe
89+
}
90+
6991
if (source.matches(".*\r.*")) {
7092
logger.debug(source); // $ hasTaintFlow
7193
} else {
@@ -78,6 +100,30 @@ public void testGuards() {
78100
logger.debug(source); // Safe
79101
}
80102

103+
if (source.matches(".*\\r.*")) {
104+
logger.debug(source); // $ hasTaintFlow
105+
} else {
106+
logger.debug(source); // Safe
107+
}
108+
109+
if (Pattern.matches(".*\\r.*", source)) {
110+
logger.debug(source); // $ hasTaintFlow
111+
} else {
112+
logger.debug(source); // Safe
113+
}
114+
115+
if (source.matches(".*\\R.*")) {
116+
logger.debug(source); // $ hasTaintFlow
117+
} else {
118+
logger.debug(source); // Safe
119+
}
120+
121+
if (Pattern.matches(".*\\R.*", source)) {
122+
logger.debug(source); // $ hasTaintFlow
123+
} else {
124+
logger.debug(source); // Safe
125+
}
126+
81127
if (source.matches(".*")) {
82128
logger.debug(source); // Safe (assuming not DOTALL)
83129
} else {
@@ -102,6 +148,18 @@ public void testGuards() {
102148
logger.debug(source); // $ hasTaintFlow
103149
}
104150

151+
if (source.matches("[^\\R]*")) {
152+
logger.debug(source); // Safe
153+
} else {
154+
logger.debug(source); // $ hasTaintFlow
155+
}
156+
157+
if (Pattern.matches("[^\\R]*", source)) {
158+
logger.debug(source); // Safe
159+
} else {
160+
logger.debug(source); // $ hasTaintFlow
161+
}
162+
105163
if (source.matches("[^a-zA-Z]*")) {
106164
logger.debug(source); // $ hasTaintFlow
107165
} else {

0 commit comments

Comments
 (0)