diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java index d881875d9..44a9a8012 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/SolutionConstants.java @@ -10,5 +10,6 @@ public interface SolutionConstants { String PASSWORD = "!!webgoat_admin_1234!!"; String SUPER_COUPON_CODE = "get_it_for_free"; + String PASSWORD_TOM = "thisisasecretfortomonly"; } diff --git a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge4/Assignment4.java b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge4/Assignment4.java index b0c288f4e..4c3447aa8 100644 --- a/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge4/Assignment4.java +++ b/webgoat-lessons/challenge/src/main/java/org/owasp/webgoat/plugin/challenge4/Assignment4.java @@ -1,11 +1,23 @@ package org.owasp.webgoat.plugin.challenge4; -import org.apache.commons.lang3.StringUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.RandomStringUtils; import org.owasp.webgoat.assignments.AssignmentEndpoint; import org.owasp.webgoat.assignments.AssignmentPath; import org.owasp.webgoat.assignments.AttackResult; -import org.springframework.web.bind.annotation.*; +import org.owasp.webgoat.plugin.Flag; +import org.owasp.webgoat.session.DatabaseUtilities; +import org.owasp.webgoat.session.WebSession; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import java.sql.*; + +import static org.owasp.webgoat.plugin.SolutionConstants.PASSWORD_TOM; import static org.springframework.web.bind.annotation.RequestMethod.POST; /** @@ -13,21 +25,107 @@ import static org.springframework.web.bind.annotation.RequestMethod.POST; * @since 4/8/17. */ @AssignmentPath("/challenge/4") +@Slf4j public class Assignment4 extends AssignmentEndpoint { + private static final String USERS_TABLE_NAME = "challenge_users_" + RandomStringUtils.randomAlphabetic(6); + + @Autowired + private WebSession webSession; + @PutMapping //assignment path is bounded to class so we use different http method :-) @ResponseBody - public AttackResult test() { - return success().build(); + public AttackResult registerNewUser(@RequestParam String username_reg, @RequestParam String email_reg, @RequestParam String password_reg) throws Exception { + AttackResult attackResult = checkArguments(username_reg, email_reg, password_reg); + + if (attackResult == null) { + Connection connection = DatabaseUtilities.getConnection(webSession); + checkDatabase(connection); + + String checkUserQuery = "select userid from " + USERS_TABLE_NAME + " where userid = '" + username_reg + "'"; + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery(checkUserQuery); + + if (resultSet.next()) { + attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build(); + } else { + PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO " + USERS_TABLE_NAME + " VALUES (?, ?, ?)"); + preparedStatement.setString(1, username_reg); + preparedStatement.setString(2, email_reg); + preparedStatement.setString(3, password_reg); + preparedStatement.execute(); + attackResult = success().feedback("user.created").feedbackArgs(username_reg).build(); + } + } + return attackResult; + } + + private AttackResult checkArguments(String username_reg, String email_reg, String password_reg) { + if (StringUtils.isEmpty(username_reg) || StringUtils.isEmpty(email_reg) || StringUtils.isEmpty(password_reg)) { + return failed().feedback("input.invalid").build(); + } + if (username_reg.length() > 30 || email_reg.length() > 30 || password_reg.length() > 30) { + return failed().feedback("input.invalid").build(); + } + return null; } @RequestMapping(method = POST) @ResponseBody - public AttackResult login(@RequestParam String username, @RequestParam String password) throws Exception { - if (StringUtils.isAlphanumeric(username) && StringUtils.isAlphanumeric(password)) { - return success().build(); - } else { - return failed().build(); + public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception { + Connection connection = DatabaseUtilities.getConnection(webSession); + checkDatabase(connection); + + if ("tom".equals(username_login)) { + PreparedStatement statement = connection.prepareStatement("select password from " + USERS_TABLE_NAME + " where userid = ? and password = ?"); + statement.setString(1, username_login); + statement.setString(2, password_login); + ResultSet resultSet = statement.executeQuery(); + + if (resultSet.next()) { + return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(4)).build(); + } + } + return failed().build(); + } + + private void checkDatabase(Connection connection) throws SQLException { + try { + Statement statement = connection.createStatement(); + statement.execute("select 1 from " + USERS_TABLE_NAME); + } catch (SQLException e) { + createChallengeTable(connection); + } + } + + private void createChallengeTable(Connection connection) { + Statement statement = null; + try { + statement = connection.createStatement(); + String dropTable = "DROP TABLE " + USERS_TABLE_NAME; + statement.executeUpdate(dropTable); + } catch (SQLException e) { + log.info("Delete failed, this does not point to an error table might not have been present..."); + } + + try { + String createTableStatement = "CREATE TABLE " + USERS_TABLE_NAME + + " (" + "userid varchar(30)," + + "email varchar(30)," + + "password varchar(30)" + + ")"; + statement.executeUpdate(createTableStatement); + + String insertData1 = "INSERT INTO " + USERS_TABLE_NAME + " VALUES ('larry', 'larry@webgoat.org', 'larryknows')"; + String insertData2 = "INSERT INTO " + USERS_TABLE_NAME + " VALUES ('tom', 'tom@webgoat.org', '" + PASSWORD_TOM + "')"; + String insertData3 = "INSERT INTO " + USERS_TABLE_NAME + " VALUES ('alice', 'alice@webgoat.org', 'rt*(KJ()LP())$#**')"; + String insertData4 = "INSERT INTO " + USERS_TABLE_NAME + " VALUES ('eve', 'eve@webgoat.org', '**********')"; + statement.executeUpdate(insertData1); + statement.executeUpdate(insertData2); + statement.executeUpdate(insertData3); + statement.executeUpdate(insertData4); + } catch (SQLException e) { + log.error("Unable create table", e); } } diff --git a/webgoat-lessons/challenge/src/main/resources/html/Challenge4.html b/webgoat-lessons/challenge/src/main/resources/html/Challenge4.html index 2ae38ce0e..d7fbb8590 100644 --- a/webgoat-lessons/challenge/src/main/resources/html/Challenge4.html +++ b/webgoat-lessons/challenge/src/main/resources/html/Challenge4.html @@ -32,10 +32,10 @@ action="/WebGoat/challenge/4" enctype="application/json;charset=UTF-8" role="form">