diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java index 44f61be4f..868d9a047 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBCrossSiteScripting/DBCrossSiteScripting.java @@ -251,7 +251,9 @@ public class DBCrossSiteScripting extends GoatHillsFinancial @Override protected boolean getDefaultHidden() { - return ! getWebgoatContext().getDatabaseDriver().contains("oracle"); + String driver = getWebgoatContext().getDatabaseDriver(); + boolean hidden = ! (driver.contains("oracle") || driver.contains("jtds")); + return hidden; } - + } \ No newline at end of file diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/DBSQLInjection.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/DBSQLInjection.java index 33ddcdf43..5d86f373d 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/DBSQLInjection.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/DBSQLInjection.java @@ -252,8 +252,9 @@ public class DBSQLInjection extends GoatHillsFinancial @Override protected boolean getDefaultHidden() { - return ! getWebgoatContext().getDatabaseDriver().contains("oracle"); + String driver = getWebgoatContext().getDatabaseDriver(); + boolean hidden = ! (driver.contains("oracle") || driver.contains("jtds")); + return hidden; } - } \ No newline at end of file diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java index 7c5deb678..d94953ce9 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/DBSQLInjection/Login.java @@ -4,6 +4,7 @@ import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Types; import java.util.List; import java.util.Vector; @@ -132,52 +133,61 @@ public class Login extends DefaultLessonAction public boolean login(WebSession s, String userId, String password) { - System.out.println("Using \"" + password + "\""); boolean authenticated = false; try { - String call = "{ CALL EMPLOYEE_LOGIN(?,?) }"; + String call = "{ ? = call EMPLOYEE_LOGIN(?,?) }"; // NB: "call", not "CALL"! Doh! + try { CallableStatement statement = WebSession.getConnection(s) .prepareCall(call, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - statement.setInt(1, Integer.parseInt(userId)); - statement.setString(2, password); - // if this executes successfully, we are authenticated + statement.registerOutParameter(1, Types.INTEGER); + statement.setInt(2, Integer.parseInt(userId)); + statement.setString(3, password); statement.execute(); - - setSessionAttribute(s, - getLessonName() + ".isAuthenticated", Boolean.TRUE); - setSessionAttribute(s, getLessonName() + "." - + DBSQLInjection.USER_ID, userId); - authenticated = true; - if (DBSQLInjection.STAGE1.equals(getStage(s)) && - DBSQLInjection.PRIZE_EMPLOYEE_ID == Integer.parseInt(userId)) - { - setStageComplete(s, DBSQLInjection.STAGE1); - } + + int rows = statement.getInt(1); + if (rows > 0) { + setSessionAttribute(s, + getLessonName() + ".isAuthenticated", Boolean.TRUE); + setSessionAttribute(s, getLessonName() + "." + + DBSQLInjection.USER_ID, userId); + authenticated = true; + if (DBSQLInjection.STAGE1.equals(getStage(s)) && + DBSQLInjection.PRIZE_EMPLOYEE_ID == Integer.parseInt(userId)) + { + setStageComplete(s, DBSQLInjection.STAGE1); + } + } else { + + if (DBSQLInjection.STAGE2.equals(getStage(s))) + { + try + { + String call2 = "{ ? = call EMPLOYEE_LOGIN_BACKUP(?,?) }"; + statement = WebSession.getConnection(s) + .prepareCall(call2, ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + statement.registerOutParameter(1, Types.INTEGER); + statement.setInt(2, Integer.parseInt(userId)); + statement.setString(3, password); + statement.execute(); + + rows = statement.getInt(1); + if (rows > 0) + setStageComplete(s, DBSQLInjection.STAGE2); + } + catch (SQLException sqle2){} + } + } } catch (SQLException sqle) { s.setMessage("Error logging in: " + sqle.getLocalizedMessage()); sqle.printStackTrace(); - if (DBSQLInjection.STAGE2.equals(getStage(s))) - { - try - { - String call2 = "{ CALL EMPLOYEE_LOGIN_BACKUP(?,?) }"; - CallableStatement statement = WebSession.getConnection(s) - .prepareCall(call2, ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_READ_ONLY); - statement.setInt(1, Integer.parseInt(userId)); - statement.setString(2, password); - statement.execute(); - setStageComplete(s, DBSQLInjection.STAGE2); - } - catch (SQLException sqle2){} - } } } catch (Exception e) diff --git a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/DBSQLInjection/Login_i.java b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/DBSQLInjection/Login_i.java index 0b46b80b4..68bdc6df5 100755 --- a/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/DBSQLInjection/Login_i.java +++ b/ webgoat/main/project/JavaSource/org/owasp/webgoat/lessons/instructor/DBSQLInjection/Login_i.java @@ -2,27 +2,28 @@ package org.owasp.webgoat.lessons.instructor.DBSQLInjection; /* * The solution is to choose Neville's userid, and enter a password like: - * ' OR userid=112 OR password=' + * ' OR '1'='1 * Modify the Stored procedure LOGIN_EMPLOYEE to use fixed statements or bind variables * * -CREATE OR REPLACE PROCEDURE EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) AS - v_userid NUMBER; +CREATE OR REPLACE FUNCTION WEBGOAT_guest.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) RETURN NUMBER AS + cnt NUMBER; BEGIN - SELECT USERID INTO v_userid FROM EMPLOYEE + SELECT COUNT(*) INTO cnt FROM EMPLOYEE WHERE USERID = v_id AND PASSWORD = v_password; + RETURN cnt; END; / * OR -CREATE OR REPLACE PROCEDURE EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) AS - stmt VARCHAR(1000); - v_userid NUMBER; +CREATE OR REPLACE FUNCTION WEBGOAT_guest.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) RETURN NUMBER AS + stmt VARCHAR(32767); cnt NUMBER; BEGIN - stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = :1 AND PASSWORD = :2'; - EXECUTE IMMEDIATE stmt INTO v_userid USING v_id, v_password; + stmt := 'SELECT COUNT (*) FROM EMPLOYEE WHERE USERID = :1 AND PASSWORD = :2'; + EXECUTE IMMEDIATE stmt INTO cnt USING v_id, v_password; + RETURN cnt; END; / diff --git a/ webgoat/main/project/WebContent/WEB-INF/webgoat_oracle.sql b/ webgoat/main/project/WebContent/WEB-INF/webgoat_oracle.sql index 0e6d26568..9894eb2a7 100755 --- a/ webgoat/main/project/WebContent/WEB-INF/webgoat_oracle.sql +++ b/ webgoat/main/project/WebContent/WEB-INF/webgoat_oracle.sql @@ -24,19 +24,21 @@ CREATE TABLE WEBGOAT_guest.EMPLOYEE ( ); -CREATE OR REPLACE PROCEDURE WEBGOAT_guest.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) AS - stmt VARCHAR(32767);v_userid NUMBER; +CREATE OR REPLACE FUNCTION WEBGOAT_guest.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) RETURN NUMBER AS + stmt VARCHAR(32767);cnt NUMBER; BEGIN - stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || ''''; - EXECUTE IMMEDIATE stmt INTO v_userid; + stmt := 'SELECT COUNT (*) FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || ''''; + EXECUTE IMMEDIATE stmt INTO cnt; + RETURN cnt; END; / -CREATE OR REPLACE PROCEDURE WEBGOAT_guest.EMPLOYEE_LOGIN_BACKUP(v_id NUMBER, v_password VARCHAR) AS - stmt VARCHAR(32767);v_userid NUMBER; +CREATE OR REPLACE FUNCTION WEBGOAT_guest.EMPLOYEE_LOGIN_BACKUP(v_id NUMBER, v_password VARCHAR) RETURN NUMBER AS + stmt VARCHAR(32767);cnt NUMBER; BEGIN - stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || ''''; - EXECUTE IMMEDIATE stmt INTO v_userid; + stmt := 'SELECT COUNT (*) FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || ''''; + EXECUTE IMMEDIATE stmt INTO cnt; + RETURN cnt; END; /