|
7 | 7 | import static dev.aikido.agent_api.vulnerabilities.sql_injection.SqlDetector.detectSqlInjection; |
8 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; |
9 | 9 | import static org.junit.jupiter.api.Assertions.assertFalse; |
10 | | -import static org.junit.jupiter.api.Assertions.assertNotEquals; |
11 | 10 | import static org.junit.jupiter.api.Assertions.assertTrue; |
12 | 11 |
|
13 | 12 | public class SqlInjectionTest { |
14 | 13 | private void isNotSqlInjection(String sql, String input, String dialect) { |
15 | | - int result; |
16 | 14 | if ("mysql".equals(dialect) || "all".equals(dialect)) { |
17 | | - result = detectSqlInjection(sql, input, new Dialect("mysql")); |
18 | | - assertNotEquals(1, result, String.format("Expected no SQL injection for SQL: %s and input: %s", sql, input)); |
| 15 | + int result = detectSqlInjection(sql, input, new Dialect("mysql")); |
| 16 | + assertEquals(0, result, String.format("Expected no SQL injection for SQL: %s and input: %s", sql, input)); |
19 | 17 | } |
20 | 18 | if ("postgresql".equals(dialect) || "all".equals(dialect)) { |
21 | | - result = detectSqlInjection(sql, input, new Dialect("postgresql")); |
22 | | - assertNotEquals(1, result, String.format("Expected no SQL injection for SQL: %s and input: %s", sql, input)); |
| 19 | + int result = detectSqlInjection(sql, input, new Dialect("postgresql")); |
| 20 | + assertEquals(0, result, String.format("Expected no SQL injection for SQL: %s and input: %s", sql, input)); |
23 | 21 | } |
24 | 22 | } |
25 | 23 | private void isSqlInjection(String sql, String input, String dialect) { |
26 | | - int result; |
27 | 24 | if ("mysql".equals(dialect) || "all".equals(dialect)) { |
28 | | - result = detectSqlInjection(sql, input, new Dialect("mysql")); |
| 25 | + int result = detectSqlInjection(sql, input, new Dialect("mysql")); |
29 | 26 | assertEquals(1, result, String.format("Expected SQL injection for SQL: %s and input: %s", sql, input)); |
30 | 27 | } |
31 | 28 | if ("postgresql".equals(dialect) || "all".equals(dialect)) { |
32 | | - result = detectSqlInjection(sql, input, new Dialect("postgresql")); |
| 29 | + int result = detectSqlInjection(sql, input, new Dialect("postgresql")); |
33 | 30 | assertEquals(1, result, String.format("Expected SQL injection for SQL: %s and input: %s", sql, input)); |
34 | 31 | } |
35 | 32 | } |
| 33 | + private void isSqlTokenizeError(String sql, String input, String dialect) { |
| 34 | + if ("mysql".equals(dialect) || "all".equals(dialect)) { |
| 35 | + int result = detectSqlInjection(sql, input, new Dialect("mysql")); |
| 36 | + assertEquals(3, result, String.format("Expected SQL tokenize error for SQL: %s and input: %s", sql, input)); |
| 37 | + } |
| 38 | + if ("postgresql".equals(dialect) || "all".equals(dialect)) { |
| 39 | + int result = detectSqlInjection(sql, input, new Dialect("postgresql")); |
| 40 | + assertEquals(3, result, String.format("Expected SQL tokenize error for SQL: %s and input: %s", sql, input)); |
| 41 | + } |
| 42 | + } |
36 | 43 |
|
37 | 44 |
|
38 | 45 | /** |
@@ -166,17 +173,8 @@ public void testShouldReturnEarly() { |
166 | 173 | assertFalse(SqlDetector.shouldReturnEarly("SELECT * FROM users; DROP TABLE", "users; DROP TABLE")); |
167 | 174 | } |
168 | 175 |
|
169 | | - /** |
170 | | - * Moved : |
171 | | - * is_sql_injection("SELECT * FROM users WHERE id = 'users\\'", "users\\") |
172 | | - * is_sql_injection("SELECT * FROM users WHERE id = 'users\\\\'", "users\\\\") |
173 | | - * to is_not_sql_injection. Reason : Invalid SQL. |
174 | | - */ |
175 | 176 | @Test |
176 | 177 | public void testAllowEscapeSequences() { |
177 | | - // Invalid queries: |
178 | | - isNotSqlInjection("SELECT * FROM users WHERE id = 'users\\'", "users\\", "all"); |
179 | | - isNotSqlInjection("SELECT * FROM users WHERE id = 'users\\\\'", "users\\\\", "all"); |
180 | 178 | isNotSqlInjection("SELECT * FROM users WHERE id = '\nusers'", "\nusers", "all"); |
181 | 179 | isNotSqlInjection("SELECT * FROM users WHERE id = '\rusers'", "\rusers", "all"); |
182 | 180 | isNotSqlInjection("SELECT * FROM users WHERE id = '\tusers'", "\tusers", "all"); |
@@ -220,8 +218,7 @@ public void testCheckStringSafelyEscaped() { |
220 | 218 | "SELECT * FROM comments WHERE comment = \"I\\`m writing you\"", "I`m writing you", "all" |
221 | 219 | ); |
222 | 220 |
|
223 | | - // Invalid query (strings don't terminate) |
224 | | - isNotSqlInjection( |
| 221 | + isSqlTokenizeError( |
225 | 222 | "SELECT * FROM comments WHERE comment = 'I'm writing you'", "I'm writing you", "all" |
226 | 223 | ); |
227 | 224 |
|
@@ -375,6 +372,12 @@ public void testLowercasedInputSqlInjection() { |
375 | 372 | isSqlInjection(sql, expectedSqlInjection, "all"); |
376 | 373 | } |
377 | 374 |
|
| 375 | + @Test |
| 376 | + public void testUnterminatedStrings() { |
| 377 | + isSqlTokenizeError("SELECT * FROM users WHERE id = 'users\\'", "users\\", "all"); |
| 378 | + isSqlTokenizeError("SELECT * FROM users WHERE id = 'users\\\\'", "users\\\\", "all"); |
| 379 | + } |
| 380 | + |
378 | 381 | /** |
379 | 382 | * Marked the following as SQL injection since this would result in 2 or more tokens becoming one : |
380 | 383 | * is_not_sql_injection("foobar)", "foobar)") |
|
0 commit comments