Skip to content

Commit 7a37a47

Browse files
committed
FINERACT-1870: Run reports fix for 1.8.x
1 parent 8cede8d commit 7a37a47

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

fineract-provider/src/main/java/org/apache/fineract/infrastructure/security/utils/SQLInjectionValidator.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.apache.fineract.infrastructure.security.utils;
2020

21+
import java.util.List;
2122
import java.util.StringTokenizer;
2223
import java.util.regex.Matcher;
2324
import java.util.regex.Pattern;
@@ -37,23 +38,32 @@ private SQLInjectionValidator() {
3738

3839
private static final String SQL_PATTERN = "[a-zA-Z_=,\\-'!><.?\"`% ()0-9*\n\r]*";
3940

41+
// TODO: see here https://rails-sqli.org for and
42+
// https://larrysteinle.com/2011/02/20/use-regular-expressions-to-detect-sql-code-injection more examples
43+
private static final List<String> INJECTION_PATTERNS = List.of("(?i).*[or|and]\s*[\"']?-1[\"']?\\s*(-*).*",
44+
"(?i).*\\s+[\"']?(\\d+)[\"']?\\s*=\\s*[\"']?(\\1)[\"']?\\s*(-*).*");
45+
4046
public static void validateSQLInput(final String sqlSearch) {
4147
if (StringUtils.isBlank(sqlSearch)) {
4248
return;
4349
}
50+
51+
// TODO: this should be replaced by INJECTION_PATTERNS
4452
String lowerCaseSQL = sqlSearch.toLowerCase();
4553
for (String ddl : DDL_COMMANDS) {
4654
if (lowerCaseSQL.contains(ddl)) {
4755
throw new SQLInjectionException();
4856
}
4957
}
5058

59+
// TODO: this should be replaced by INJECTION_PATTERNS
5160
for (String dml : DML_COMMANDS) {
5261
if (lowerCaseSQL.contains(dml)) {
5362
throw new SQLInjectionException();
5463
}
5564
}
5665

66+
// TODO: this should be replaced by INJECTION_PATTERNS
5767
for (String comments : COMMENTS) {
5868
if (lowerCaseSQL.contains(comments)) {
5969
throw new SQLInjectionException();
@@ -63,17 +73,10 @@ public static void validateSQLInput(final String sqlSearch) {
6373
// Removing the space before and after '=' operator
6474
// String s = " \" OR 1 = 1"; For the cases like this
6575
boolean injectionFound = false;
66-
String inputSqlString = lowerCaseSQL;
67-
while (inputSqlString.indexOf(" =") > 0) { // Don't remove space before
68-
// = operator
69-
inputSqlString = inputSqlString.replaceAll(" =", "=");
70-
}
7176

72-
while (inputSqlString.indexOf("= ") > 0) { // Don't remove space after =
73-
// operator
74-
inputSqlString = inputSqlString.replaceAll("= ", "=");
75-
}
77+
String inputSqlString = lowerCaseSQL.replaceAll("\\s*=\\s*", "=");
7678

79+
// TODO: this should be replaced by INJECTION_PATTERNS
7780
StringTokenizer tokenizer = new StringTokenizer(inputSqlString, " ");
7881
while (tokenizer.hasMoreTokens()) {
7982
String token = tokenizer.nextToken().trim();
@@ -118,6 +121,14 @@ public static void validateSQLInput(final String sqlSearch) {
118121
throw new SQLInjectionException();
119122
}
120123

124+
for (String injectionPattern : INJECTION_PATTERNS) {
125+
Pattern pattern = Pattern.compile(injectionPattern);
126+
Matcher matcher = pattern.matcher(sqlSearch);
127+
if (matcher.matches()) {
128+
throw new SQLInjectionException();
129+
}
130+
}
131+
121132
Pattern pattern = Pattern.compile(SQL_PATTERN);
122133
Matcher matcher = pattern.matcher(sqlSearch);
123134
if (!matcher.matches()) {
@@ -129,13 +140,16 @@ public static void validateAdhocQuery(final String sqlSearch) {
129140
if (StringUtils.isBlank(sqlSearch)) {
130141
return;
131142
}
143+
144+
// TODO: this should be replaced by INJECTION_PATTERNS
132145
String lowerCaseSQL = sqlSearch.toLowerCase().trim();
133146
for (String ddl : DDL_COMMANDS) {
134147
if (lowerCaseSQL.startsWith(ddl)) {
135148
throw new SQLInjectionException();
136149
}
137150
}
138151

152+
// TODO: this should be replaced by INJECTION_PATTERNS
139153
for (String comments : COMMENTS) {
140154
if (lowerCaseSQL.contains(comments)) {
141155
throw new SQLInjectionException();
@@ -145,16 +159,8 @@ public static void validateAdhocQuery(final String sqlSearch) {
145159
// Removing the space before and after '=' operator
146160
// String s = " \" OR 1 = 1"; For the cases like this
147161
boolean injectionFound = false;
148-
String inputSqlString = lowerCaseSQL;
149-
while (inputSqlString.indexOf(" =") > 0) { // Don't remove space before
150-
// = operator
151-
inputSqlString = inputSqlString.replaceAll(" =", "=");
152-
}
153162

154-
while (inputSqlString.indexOf("= ") > 0) { // Don't remove space after =
155-
// operator
156-
inputSqlString = inputSqlString.replaceAll("= ", "=");
157-
}
163+
String inputSqlString = lowerCaseSQL.replaceAll("\\s*=\\s*", "=");
158164

159165
StringTokenizer tokenizer = new StringTokenizer(inputSqlString, " ");
160166
while (tokenizer.hasMoreTokens()) {
@@ -200,6 +206,14 @@ public static void validateAdhocQuery(final String sqlSearch) {
200206
throw new SQLInjectionException();
201207
}
202208

209+
for (String injectionPattern : INJECTION_PATTERNS) {
210+
Pattern pattern = Pattern.compile(injectionPattern);
211+
Matcher matcher = pattern.matcher(sqlSearch);
212+
if (matcher.matches()) {
213+
throw new SQLInjectionException();
214+
}
215+
}
216+
203217
Pattern pattern = Pattern.compile(SQL_PATTERN);
204218
Matcher matcher = pattern.matcher(sqlSearch);
205219
if (!matcher.matches()) {

0 commit comments

Comments
 (0)