From 9acdd3b1ec3b8b5135e6b2768871241fa5ecf6c8 Mon Sep 17 00:00:00 2001 From: kingthorin Date: Fri, 4 Jul 2025 10:31:44 -0400 Subject: [PATCH] ascanrules: SQLi PostgreSQL rename scan rule (all time based) Signed-off-by: kingthorin # Conflicts: # addOns/ascanrules/CHANGELOG.md # addOns/ascanrules/src/main/resources/org/zaproxy/zap/extension/ascanrules/resources/Messages.properties --- addOns/ascanrules/CHANGELOG.md | 1 + ...SqlInjectionPostgreSqlTimingScanRule.java} | 40 ++++--------------- .../resources/help/contents/ascanrules.html | 2 +- .../ascanrules/resources/Messages.properties | 2 +- ...tionPostgreSqlTimingScanRuleUnitTest.java} | 9 +++-- 5 files changed, 16 insertions(+), 38 deletions(-) rename addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/{SqlInjectionPostgreScanRule.java => SqlInjectionPostgreSqlTimingScanRule.java} (89%) rename addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/{SqlInjectionPostgreScanRuleUnitTest.java => SqlInjectionPostgreSqlTimingScanRuleUnitTest.java} (95%) diff --git a/addOns/ascanrules/CHANGELOG.md b/addOns/ascanrules/CHANGELOG.md index 2853169579b..75c0390f91c 100644 --- a/addOns/ascanrules/CHANGELOG.md +++ b/addOns/ascanrules/CHANGELOG.md @@ -12,6 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - SQL Injection - MsSQL - SQL Injection - MySQL - SQL Injection - Hypersonic + - SQL Injection - PostgreSQL ### Added - Rules (as applicable) have been tagged in relation to HIPAA and PCI DSS. diff --git a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRule.java b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRule.java similarity index 89% rename from addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRule.java rename to addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRule.java index 7eb0bd51218..96a02eff0ad 100644 --- a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRule.java +++ b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRule.java @@ -23,7 +23,6 @@ import java.net.SocketException; import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.configuration.ConversionException; @@ -42,11 +41,11 @@ import org.zaproxy.zap.model.TechSet; /** - * The SqlInjectionPostgreScanRule identifies Postgresql specific SQL Injection vulnerabilities - * using Postgresql specific syntax. If it doesn't use Postgresql specific syntax, it belongs in the - * generic SQLInjection class! Note the ordering of checks, for efficiency is : 1) Error based (N/A) - * 2) Boolean Based (N/A - uses standard syntax) 3) UNION based (N/A - uses standard syntax) 4) - * Stacked (N/A - uses standard syntax) 5) Blind/Time Based (Yes) + * This scan rule identifies Postgresql specific SQL Injection vulnerabilities using Postgresql + * specific syntax. If it doesn't use Postgresql specific syntax, it belongs in the generic + * SQLInjection class! Note the ordering of checks, for efficiency is : 1) Error based (N/A) 2) + * Boolean Based (N/A - uses standard syntax) 3) UNION based (N/A - uses standard syntax) 4) Stacked + * (N/A - uses standard syntax) 5) Blind/Time Based (Yes) * *

See the following for some great specific tricks which could be integrated here * http://www.websec.ca/kb/sql_injection @@ -60,11 +59,9 @@ * * @author 70pointer */ -public class SqlInjectionPostgreScanRule extends AbstractAppParamPlugin +public class SqlInjectionPostgreSqlTimingScanRule extends AbstractAppParamPlugin implements CommonActiveScanRuleInfo { - private boolean doTimeBased = false; - private int doTimeMaxRequests = 0; private int sleepInSeconds; @@ -80,23 +77,6 @@ public class SqlInjectionPostgreScanRule extends AbstractAppParamPlugin private static final double TIME_CORRELATION_ERROR_RANGE = 0.15; private static final double TIME_SLOPE_ERROR_RANGE = 0.30; - /** - * create a map of SQL related error message fragments, and map them back to the RDBMS that they - * are associated with keep the ordering the same as the order in which the values are inserted, - * to allow the more (subjectively judged) common cases to be tested first Note: these should - * represent actual (driver level) error messages for things like syntax error, otherwise we are - * simply guessing that the string should/might occur. - */ - private static final Map SQL_ERROR_TO_DBMS = new LinkedHashMap<>(); - - static { - SQL_ERROR_TO_DBMS.put("org.postgresql.util.PSQLException", "PostgreSQL"); - SQL_ERROR_TO_DBMS.put("org.postgresql", "PostgreSQL"); - // Note: only Postgresql mappings here. - // TODO: is this all?? we need more error messages for Postgresql for different languages. - // PHP, ASP, JSP(JDBC), etc. - } - /** * The sleep function in Postgresql cast it back to an int, so we can use it in nested select * statements and stuff. @@ -209,7 +189,8 @@ public class SqlInjectionPostgreScanRule extends AbstractAppParamPlugin } /** for logging. */ - private static final Logger LOGGER = LogManager.getLogger(SqlInjectionPostgreScanRule.class); + private static final Logger LOGGER = + LogManager.getLogger(SqlInjectionPostgreSqlTimingScanRule.class); @Override public int getId() { @@ -252,16 +233,12 @@ public void init() { // set up what we are allowed to do, depending on the attack strength that was set. if (this.getAttackStrength() == AttackStrength.LOW) { - doTimeBased = true; doTimeMaxRequests = 3; } else if (this.getAttackStrength() == AttackStrength.MEDIUM) { - doTimeBased = true; doTimeMaxRequests = 5; } else if (this.getAttackStrength() == AttackStrength.HIGH) { - doTimeBased = true; doTimeMaxRequests = 10; } else if (this.getAttackStrength() == AttackStrength.INSANE) { - doTimeBased = true; doTimeMaxRequests = 100; } // Read the sleep value from the configs @@ -289,7 +266,6 @@ public void scan(HttpMessage originalMessage, String paramName, String paramValu int countTimeBasedRequests = 0; for (int timeBasedSQLindex = 0; timeBasedSQLindex < SQL_POSTGRES_TIME_REPLACEMENTS.length - && doTimeBased && countTimeBasedRequests < doTimeMaxRequests; timeBasedSQLindex++) { countTimeBasedRequests++; diff --git a/addOns/ascanrules/src/main/javahelp/org/zaproxy/zap/extension/ascanrules/resources/help/contents/ascanrules.html b/addOns/ascanrules/src/main/javahelp/org/zaproxy/zap/extension/ascanrules/resources/help/contents/ascanrules.html index cea91a96fb2..8b324974f66 100644 --- a/addOns/ascanrules/src/main/javahelp/org/zaproxy/zap/extension/ascanrules/resources/help/contents/ascanrules.html +++ b/addOns/ascanrules/src/main/javahelp/org/zaproxy/zap/extension/ascanrules/resources/help/contents/ascanrules.html @@ -422,7 +422,7 @@

SQL Injection - PostgreSQL (Time Based)


Post 2.5.0 you can change the length of time used for the attack by changing the rules.common.sleep parameter via the Options 'Rule configuration' panel.

-Latest code: SqlInjectionPostgreScanRule.java +Latest code: SqlInjectionPostgreSqlTimingScanRule.java
Alert ID: 40022. diff --git a/addOns/ascanrules/src/main/resources/org/zaproxy/zap/extension/ascanrules/resources/Messages.properties b/addOns/ascanrules/src/main/resources/org/zaproxy/zap/extension/ascanrules/resources/Messages.properties index 0ad2921f0d5..8ff45296919 100644 --- a/addOns/ascanrules/src/main/resources/org/zaproxy/zap/extension/ascanrules/resources/Messages.properties +++ b/addOns/ascanrules/src/main/resources/org/zaproxy/zap/extension/ascanrules/resources/Messages.properties @@ -186,7 +186,7 @@ ascanrules.sqlinjection.mssql.name = SQL Injection - MsSQL (Time Based) ascanrules.sqlinjection.mysql.name = SQL Injection - MySQL (Time Based) ascanrules.sqlinjection.name = SQL Injection ascanrules.sqlinjection.oracle.name = SQL Injection - Oracle (Time Based) -ascanrules.sqlinjection.postgres.name = SQL Injection - PostgreSQL +ascanrules.sqlinjection.postgres.name = SQL Injection - PostgreSQL (Time Based) ascanrules.sqlinjection.refs = https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html ascanrules.sqlinjection.soln = Do not trust client side input, even if there is client side validation in place.\nIn general, type check all data on the server side.\nIf the application uses JDBC, use PreparedStatement or CallableStatement, with parameters passed by '?'\nIf the application uses ASP, use ADO Command Objects with strong type checking and parameterized queries.\nIf database Stored Procedures can be used, use them.\nDo *not* concatenate strings into queries in the stored procedure, or use 'exec', 'exec immediate', or equivalent functionality!\nDo not create dynamic SQL queries using simple string concatenation.\nEscape all data received from the client.\nApply an 'allow list' of allowed characters, or a 'deny list' of disallowed characters in user input.\nApply the principle of least privilege by using the least privileged database user possible.\nIn particular, avoid using the 'sa' or 'db-owner' database users. This does not eliminate SQL injection, but minimizes its impact.\nGrant the minimum database access that is necessary for the application. ascanrules.sqlinjection.sqlite.alert.errorbased.extrainfo = The following known SQLite error message was provoked: [{0}]. diff --git a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRuleUnitTest.java b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRuleUnitTest.java similarity index 95% rename from addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRuleUnitTest.java rename to addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRuleUnitTest.java index 96ada840ede..7c2a156a1d6 100644 --- a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreScanRuleUnitTest.java +++ b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionPostgreSqlTimingScanRuleUnitTest.java @@ -41,12 +41,13 @@ import org.zaproxy.zap.model.TechSet; import org.zaproxy.zap.testutils.NanoServerHandler; -/** Unit test for {@link SqlInjectionPostgreScanRule}. */ -class SqlInjectionPostgreScanRuleUnitTest extends ActiveScannerTest { +/** Unit test for {@link SqlInjectionPostgreSqlTimingScanRule}. */ +class SqlInjectionPostgreSqlTimingScanRuleUnitTest + extends ActiveScannerTest { @Override - protected SqlInjectionPostgreScanRule createScanner() { - return new SqlInjectionPostgreScanRule(); + protected SqlInjectionPostgreSqlTimingScanRule createScanner() { + return new SqlInjectionPostgreSqlTimingScanRule(); } @Test