diff --git a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java index 288a4952..156ec272 100644 --- a/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java +++ b/agent_api/src/main/java/dev/aikido/agent_api/vulnerabilities/sql_injection/SqlDetector.java @@ -35,11 +35,11 @@ public DetectorResult run(String userInput, String[] arguments) { } public static boolean detectSqlInjection(String query, String userInput, Dialect dialect) { String queryLower = query.toLowerCase(); - String userInputLower = userInput.toLowerCase(); - if (shouldReturnEarly(queryLower, userInputLower)) { + String userInputNormalized = userInput.toLowerCase().trim(); + if (shouldReturnEarly(queryLower, userInputNormalized)) { return false; } - return RustSQLInterface.detectSqlInjection(queryLower, userInputLower, dialect); + return RustSQLInterface.detectSqlInjection(queryLower, userInputNormalized, dialect); } /** * Input : Lowercased query and user_input. diff --git a/agent_api/src/test/java/vulnerabilities/SqlInjectionTest.java b/agent_api/src/test/java/vulnerabilities/SqlInjectionTest.java index f1593eba..15a4d777 100644 --- a/agent_api/src/test/java/vulnerabilities/SqlInjectionTest.java +++ b/agent_api/src/test/java/vulnerabilities/SqlInjectionTest.java @@ -356,6 +356,17 @@ public void testMultilineQueries() { "1' OR 1=1", "all" ); } + @Test + public void testTrimmedUserInputBypass() { + // Attacker pads payload with trailing spaces; app trims before DB execution. + // The trimmed payload must still be detected (AIKIDO-OR0E0082). + isSqlInjection( + "INSERT INTO pets (name, owner) VALUES ('x', 'dummy'), ('injected', 'hacker'); --', 'owner')", + "x', 'dummy'), ('injected', 'hacker'); -- ", + "all" + ); + } + @Test public void testLowercasedInputSqlInjection() { String sql = """