diff --git a/addOns/ascanrules/CHANGELOG.md b/addOns/ascanrules/CHANGELOG.md index 7ed91f12f27..cdda72c0384 100644 --- a/addOns/ascanrules/CHANGELOG.md +++ b/addOns/ascanrules/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Maintenance changes. - Depends on an updated version of the Common Library add-on. - The following scan rules and their alerts have been renamed to clarify that they're time based (Issue 7341). + - SQL Injection - Oracle - SQL Injection - MsSQL - SQL Injection - Hypersonic diff --git a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRule.java b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRule.java similarity index 84% rename from addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRule.java rename to addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRule.java index a4996c02aa3..5499d321ee9 100644 --- a/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRule.java +++ b/addOns/ascanrules/src/main/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRule.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -38,11 +37,11 @@ /** * TODO: maybe implement a more specific UNION based check for Oracle (with table names) * - *

The SqlInjectionOracleScanRule identifies Oracle specific SQL Injection vulnerabilities using - * Oracle specific syntax. If it doesn't use Oracle 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 (TODO) 4) Stacked (N/A - uses standard - * syntax) 5) Blind/Time Based (Yes) + *

This scan rule identifies Oracle specific SQL Injection vulnerabilities using Oracle specific + * syntax. If it doesn't use Oracle 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 (TODO) 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,44 +59,16 @@ * * @author 70pointer */ -public class SqlInjectionOracleScanRule extends AbstractAppParamPlugin +public class SqlInjectionOracleTimingScanRule extends AbstractAppParamPlugin implements CommonActiveScanRuleInfo { private int expectedDelayInMs = 5000; - private boolean doUnionBased = false; // TODO: use in Union based, when we implement it - private boolean doTimeBased = false; - - private int doUnionMaxRequests = 0; // TODO: use in Union based, when we implement it private int doTimeMaxRequests = 0; /** Oracle one-line comment */ public static final String SQL_ONE_LINE_COMMENT = " -- "; - /** - * 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("oracle.jdbc", "Oracle"); - SQL_ERROR_TO_DBMS.put("SQLSTATE[HY", "Oracle"); - SQL_ERROR_TO_DBMS.put("ORA-00933", "Oracle"); - SQL_ERROR_TO_DBMS.put("ORA-06512", "Oracle"); // indicates the line number of an error - SQL_ERROR_TO_DBMS.put("SQL command not properly ended", "Oracle"); - SQL_ERROR_TO_DBMS.put("ORA-00942", "Oracle"); // table or view does not exist - SQL_ERROR_TO_DBMS.put("ORA-29257", "Oracle"); // host unknown - SQL_ERROR_TO_DBMS.put("ORA-00932", "Oracle"); // inconsistent datatypes - - // Note: only Oracle mappings here. - // TODO: is this all?? we need more error messages for Oracle for different languages. PHP - // (oci8), ASP, JSP(JDBC), etc - } - /** the 5 second sleep function in Oracle SQL */ private static String SQL_ORACLE_TIME_SELECT = "SELECT UTL_INADDR.get_host_name('10.0.0.1') from dual union SELECT UTL_INADDR.get_host_name('10.0.0.2') from dual union SELECT UTL_INADDR.get_host_name('10.0.0.3') from dual union SELECT UTL_INADDR.get_host_name('10.0.0.4') from dual union SELECT UTL_INADDR.get_host_name('10.0.0.5') from dual"; @@ -167,7 +138,8 @@ public class SqlInjectionOracleScanRule extends AbstractAppParamPlugin } /** for logging. */ - private static final Logger LOGGER = LogManager.getLogger(SqlInjectionOracleScanRule.class); + private static final Logger LOGGER = + LogManager.getLogger(SqlInjectionOracleTimingScanRule.class); @Override public int getId() { @@ -210,25 +182,13 @@ 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; - doUnionBased = true; - doUnionMaxRequests = 3; } else if (this.getAttackStrength() == AttackStrength.MEDIUM) { - doTimeBased = true; doTimeMaxRequests = 5; - doUnionBased = true; - doUnionMaxRequests = 5; } else if (this.getAttackStrength() == AttackStrength.HIGH) { - doTimeBased = true; doTimeMaxRequests = 10; - doUnionBased = true; - doUnionMaxRequests = 10; } else if (this.getAttackStrength() == AttackStrength.INSANE) { - doTimeBased = true; doTimeMaxRequests = 100; - doUnionBased = true; - doUnionMaxRequests = 100; } } @@ -256,7 +216,6 @@ public void scan(HttpMessage originalMessage, String paramName, String paramValu long originalTimeUsed = msgTimeBaseline.getTimeElapsedMillis(); // end of timing baseline check - int countUnionBasedRequests = 0; int countTimeBasedRequests = 0; LOGGER.debug( @@ -269,7 +228,6 @@ public void scan(HttpMessage originalMessage, String paramName, String paramValu // Check for time based SQL Injection, using Oracle specific syntax for (int timeBasedSQLindex = 0; timeBasedSQLindex < SQL_ORACLE_TIME_REPLACEMENTS.length - && doTimeBased && countTimeBasedRequests < doTimeMaxRequests; timeBasedSQLindex++) { HttpMessage msgAttack = getNewMsg(); 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 4d849957b70..9a18da9dd1d 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 @@ -404,7 +404,7 @@

SQL Injection - Oracle (Time Based)


Note that this rule does not currently allow you to change the length of time used for the timing attacks due to the way the delay is caused.

-Latest code: SqlInjectionOracleScanRule.java +Latest code: SqlInjectionOracleTimingScanRule.java
Alert ID: 40021. 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 921c22b5ac6..c6ccb97616a 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 @@ -185,7 +185,7 @@ ascanrules.sqlinjection.mssql.alert.timebased.extrainfo = The query time is cont ascanrules.sqlinjection.mssql.name = SQL Injection - MsSQL (Time Based) ascanrules.sqlinjection.mysql.name = SQL Injection - MySQL ascanrules.sqlinjection.name = SQL Injection -ascanrules.sqlinjection.oracle.name = SQL Injection - Oracle +ascanrules.sqlinjection.oracle.name = SQL Injection - Oracle (Time Based) ascanrules.sqlinjection.postgres.name = SQL Injection - PostgreSQL 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. diff --git a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRuleUnitTest.java b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRuleUnitTest.java similarity index 95% rename from addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRuleUnitTest.java rename to addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRuleUnitTest.java index 12a70fa1025..a4073c5f4da 100644 --- a/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleScanRuleUnitTest.java +++ b/addOns/ascanrules/src/test/java/org/zaproxy/zap/extension/ascanrules/SqlInjectionOracleTimingScanRuleUnitTest.java @@ -36,12 +36,13 @@ import org.zaproxy.zap.model.TechSet; import org.zaproxy.zap.testutils.NanoServerHandler; -/** Unit test for {@link SqlInjectionOracleScanRule}. */ -class SqlInjectionOracleScanRuleUnitTest extends ActiveScannerTest { +/** Unit test for {@link SqlInjectionOracleTimingScanRule}. */ +class SqlInjectionOracleTimingScanRuleUnitTest + extends ActiveScannerTest { @Override - protected SqlInjectionOracleScanRule createScanner() { - return new SqlInjectionOracleScanRule(); + protected SqlInjectionOracleTimingScanRule createScanner() { + return new SqlInjectionOracleTimingScanRule(); } @Test