@@ -38,10 +38,16 @@ private SQLInjectionValidator() {
3838
3939 private static final String SQL_PATTERN = "[a-zA-Z_=,\\ -:'!><.?\" `% ()0-9*\n \r ]*" ;
4040
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+
4146 public static void validateSQLInput (final String sqlSearch ) {
4247 if (StringUtils .isBlank (sqlSearch )) {
4348 return ;
4449 }
50+
4551 String lowerCaseSQL = sqlSearch .toLowerCase ();
4652 List <String []> commandsList = List .of (DDL_COMMANDS , DML_COMMANDS , COMMENTS );
4753 validateSQLCommands (lowerCaseSQL , commandsList , String ::contains );
@@ -53,6 +59,7 @@ public static void validateAdhocQuery(final String sqlSearch) {
5359 if (StringUtils .isBlank (sqlSearch )) {
5460 return ;
5561 }
62+
5663 String lowerCaseSQL = sqlSearch .toLowerCase ().trim ();
5764 validateSQLCommand (lowerCaseSQL , DDL_COMMANDS , String ::startsWith );
5865 validateSQLCommand (lowerCaseSQL , COMMENTS , String ::contains );
@@ -80,16 +87,8 @@ private static void patternMatchSqlInjection(String sqlSearch, String lowerCaseS
8087 // Removing the space before and after '=' operator
8188 // String s = " \" OR 1 = 1"; For the cases like this
8289 boolean injectionFound = false ;
83- String inputSqlString = lowerCaseSQL ;
84- while (inputSqlString .indexOf (" =" ) > 0 ) { // Don't remove space before
85- // = operator
86- inputSqlString = inputSqlString .replaceAll (" =" , "=" );
87- }
8890
89- while (inputSqlString .indexOf ("= " ) > 0 ) { // Don't remove space after =
90- // operator
91- inputSqlString = inputSqlString .replaceAll ("= " , "=" );
92- }
91+ String inputSqlString = lowerCaseSQL .replaceAll ("\\ s*=\\ s*" , "=" );
9392
9493 StringTokenizer tokenizer = new StringTokenizer (inputSqlString , " " );
9594 while (tokenizer .hasMoreTokens ()) {
@@ -131,10 +130,19 @@ private static void patternMatchSqlInjection(String sqlSearch, String lowerCaseS
131130 }
132131 }
133132 }
133+
134134 if (injectionFound ) {
135135 throw new SQLInjectionException ();
136136 }
137137
138+ for (String injectionPattern : INJECTION_PATTERNS ) {
139+ Pattern pattern = Pattern .compile (injectionPattern );
140+ Matcher matcher = pattern .matcher (sqlSearch );
141+ if (matcher .matches ()) {
142+ throw new SQLInjectionException ();
143+ }
144+ }
145+
138146 Pattern pattern = Pattern .compile (SQL_PATTERN );
139147 Matcher matcher = pattern .matcher (sqlSearch );
140148 if (!matcher .matches ()) {
0 commit comments