Fix merge request
This commit is contained in:
@ -92,6 +92,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctorj</artifactId>
|
||||
@ -100,6 +104,12 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<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.WebSession;
|
||||
import org.owasp.webgoat.session.WebgoatContext;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.annotation.ScopedProxyMode;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@SpringBootApplication
|
||||
@Configuration
|
||||
public class WebGoat {
|
||||
|
||||
@Bean(name = "pluginTargetDirectory")
|
||||
@ -52,8 +51,8 @@ public class WebGoat {
|
||||
|
||||
@Bean
|
||||
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public WebSession webSession(WebgoatContext webgoatContext) {
|
||||
return new WebSession(webgoatContext);
|
||||
public WebSession webSession() {
|
||||
return new WebSession();
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
@ -25,6 +25,7 @@ package org.owasp.webgoat.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.owasp.webgoat.lessons.Lesson;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
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.ResponseStatus;
|
||||
|
||||
/**
|
||||
* <p>RestartLessonService class.</p>
|
||||
*
|
||||
* @author rlawson
|
||||
* @version $Id: $Id
|
||||
*/
|
||||
@Controller
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class RestartLessonService {
|
||||
|
||||
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")
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public void restartLesson() {
|
||||
@ -62,5 +53,8 @@ public class RestartLessonService {
|
||||
UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName());
|
||||
userTracker.reset(al);
|
||||
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 final WebGoatUser currentUser;
|
||||
private final WebgoatContext webgoatContext;
|
||||
private Lesson currentLesson;
|
||||
|
||||
/**
|
||||
* Constructor for the WebSession object
|
||||
*
|
||||
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
|
||||
*/
|
||||
public WebSession(WebgoatContext webgoatContext) {
|
||||
this.webgoatContext = webgoatContext;
|
||||
public WebSession() {
|
||||
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>
|
||||
*
|
||||
@ -100,13 +73,4 @@ public class WebSession implements Serializable {
|
||||
public String 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.path=/error.html
|
||||
server.session.timeout=600
|
||||
server.servlet.context-path=/WebGoat
|
||||
server.port=${WEBGOAT_PORT:8080}
|
||||
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-alias=${WEBGOAT_KEY_ALIAS:goat}
|
||||
server.ssl.enabled=${WEBGOAT_SSLENABLED:false}
|
||||
security.require-ssl=${WEBGOAT_SSLENABLED:false}
|
||||
|
||||
hsqldb.port=${WEBGOAT_HSQLPORT:9001}
|
||||
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.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||
spring.jpa.properties.hibernate.default_schema=CONTAINER
|
||||
|
||||
logging.level.org.thymeleaf=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.feedback.address=webgoat@owasp.org
|
||||
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.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.PluginMessages;
|
||||
import org.owasp.webgoat.session.WebSession;
|
||||
import org.owasp.webgoat.session.WebgoatContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
@ -34,8 +33,7 @@ public abstract class LessonTest {
|
||||
protected PluginMessages messages;
|
||||
@MockBean
|
||||
protected WebSession webSession;
|
||||
@Autowired
|
||||
private WebgoatContext context;
|
||||
|
||||
@MockBean
|
||||
private Language language;
|
||||
|
||||
@ -43,7 +41,6 @@ public abstract class LessonTest {
|
||||
public void init() {
|
||||
when(webSession.getUserName()).thenReturn("unit-test");
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles({"test", "webgoat"})
|
||||
public class UserRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
@ -24,6 +26,4 @@ public class UserRepositoryTest {
|
||||
Assertions.assertThat(user.getUsername()).isEqualTo("test");
|
||||
Assertions.assertThat(user.getPassword()).isEqualTo("password");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -9,12 +9,14 @@ import org.owasp.webgoat.lessons.Category;
|
||||
import org.owasp.webgoat.lessons.Lesson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@DataJpaTest
|
||||
@RunWith(SpringRunner.class)
|
||||
@ActiveProfiles({"test", "webgoat"})
|
||||
public class UserTrackerRepositoryTest {
|
||||
|
||||
private class TestLesson extends Lesson {
|
||||
@ -44,7 +46,6 @@ public class UserTrackerRepositoryTest {
|
||||
@Autowired
|
||||
private UserTrackerRepository userTrackerRepository;
|
||||
|
||||
|
||||
@Test
|
||||
public void saveUserTracker() {
|
||||
UserTracker userTracker = new UserTracker("test");
|
||||
|
@ -1,4 +1,5 @@
|
||||
webgoat.user.directory=${java.io.tmpdir}
|
||||
|
||||
spring.datasource.url=jdbc:hsqldb:mem:test
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
webgoat.start.hsqldb=false
|
||||
spring.flyway.locations=classpath:/db/container
|
||||
|
@ -37,11 +37,9 @@ public abstract class IntegrationTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeAll() {
|
||||
|
||||
if (WG_SSL) {
|
||||
if (WG_SSL) {
|
||||
WEBGOAT_URL = WEBGOAT_URL.replace("http:","https:");
|
||||
}
|
||||
|
||||
if (!started) {
|
||||
started = true;
|
||||
if (!isAlreadyRunning(WG_PORT)) {
|
||||
@ -238,8 +236,7 @@ public abstract class IntegrationTest {
|
||||
.statusCode(200)
|
||||
.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(
|
||||
RestAssured.given()
|
||||
.when()
|
||||
|
@ -39,14 +39,14 @@ public class SqlInjectionLessonTest extends IntegrationTest {
|
||||
params.put("query", sql_3);
|
||||
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.put("query", sql_4_add);
|
||||
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.put("query", sql_5);
|
||||
checkAssignment(url("/WebGoat/SqlInjection/attack5"), params, true);
|
||||
|
@ -20,37 +20,28 @@ public class XXETest extends IntegrationTest {
|
||||
private String webGoatHomeDirectory;
|
||||
private String webwolfFileDir;
|
||||
|
||||
|
||||
@Test
|
||||
public void runTests() throws IOException {
|
||||
startLesson("XXE");
|
||||
|
||||
webGoatHomeDirectory = getWebGoatServerPath();
|
||||
webwolfFileDir = getWebWolfServerPath();
|
||||
|
||||
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/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);
|
||||
checkResults("xxe/");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This performs the steps of the exercise before the secret can be committed in the final step.
|
||||
*
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private String getSecret() throws IOException {
|
||||
|
||||
//remove any left over DTD
|
||||
Path webWolfFilePath = Paths.get(webwolfFileDir);
|
||||
if (webWolfFilePath.resolve(Paths.get(getWebgoatUser(),"blind.dtd")).toFile().exists()) {
|
||||
Files.delete(webWolfFilePath.resolve(Paths.get(getWebgoatUser(),"blind.dtd")));
|
||||
if (webWolfFilePath.resolve(Paths.get(getWebgoatUser(), "blind.dtd")).toFile().exists()) {
|
||||
Files.delete(webWolfFilePath.resolve(Paths.get(getWebgoatUser(), "blind.dtd")));
|
||||
}
|
||||
String secretFile = webGoatHomeDirectory.concat("/XXE/secret.txt");
|
||||
String dtd7String = dtd7.replace("WEBWOLFURL", webWolfUrl("/landing")).replace("SECRET", secretFile);
|
||||
@ -64,10 +55,9 @@ public class XXETest extends IntegrationTest {
|
||||
.post(webWolfUrl("/WebWolf/fileupload"))
|
||||
.then()
|
||||
.extract().response().getBody().asString();
|
||||
|
||||
//upload attack
|
||||
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
|
||||
String result = RestAssured.given()
|
||||
@ -78,8 +68,7 @@ public class XXETest extends IntegrationTest {
|
||||
.then()
|
||||
.extract().response().getBody().asString();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,48 +23,40 @@
|
||||
package org.owasp.webgoat.challenges.challenge5;
|
||||
|
||||
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 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
|
||||
@Slf4j
|
||||
public class Assignment5 extends AssignmentEndpoint {
|
||||
|
||||
//Make it more random at runtime (good luck guessing)
|
||||
private static final String USERS_TABLE_NAME = "challenge_users_" + RandomStringUtils.randomAlphabetic(16);
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
public Assignment5(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/challenge/5")
|
||||
@ResponseBody
|
||||
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)) {
|
||||
return failed().feedback("required4").build();
|
||||
}
|
||||
if (!"Larry".equals(username_login)) {
|
||||
return failed().feedback("user.not.larry").feedbackArgs(username_login).build();
|
||||
}
|
||||
|
||||
PreparedStatement statement = connection.prepareStatement("select password from " + USERS_TABLE_NAME + " where userid = '" + username_login + "' and password = '" + password_login + "'");
|
||||
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();
|
||||
|
||||
if (resultSet.next()) {
|
||||
@ -73,46 +65,6 @@ public class Assignment5 extends AssignmentEndpoint {
|
||||
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.runner.RunWith;
|
||||
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.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
|
@ -1,17 +1,9 @@
|
||||
package org.owasp.webgoat.cia;
|
||||
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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
|
||||
public class CIAQuiz extends AssignmentEndpoint {
|
||||
|
||||
|
@ -4,7 +4,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
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.web.servlet.MvcResult;
|
||||
|
@ -27,6 +27,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
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.request.MockMvcRequestBuilders;
|
||||
|
||||
@ -40,8 +42,8 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standal
|
||||
* @author nbaars
|
||||
* @since 5/2/17.
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ShopEndpointTest {
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class ShopEndpointTest extends LessonTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
|
@ -22,20 +22,15 @@
|
||||
|
||||
package org.owasp.webgoat.jwt;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.impl.TextCodec;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
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 java.sql.Connection;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.ResultSet;
|
||||
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"})
|
||||
public class JWTFinalEndpoint extends AssignmentEndpoint {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private final DataSource dataSource;
|
||||
|
||||
private JWTFinalEndpoint(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/JWT/final/follow/{user}")
|
||||
public @ResponseBody
|
||||
@ -92,8 +90,7 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
|
||||
@Override
|
||||
public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
|
||||
final String kid = (String) header.get("kid");
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
||||
try (var connection = dataSource.getConnection()) {
|
||||
ResultSet rs = connection.createStatement().executeQuery("SELECT key FROM jwt_keys WHERE id = '" + kid + "'");
|
||||
while (rs.next()) {
|
||||
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;
|
||||
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.sql.*;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Users {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private UserSessionData userSessionData;
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
UserSessionData userSessionData;
|
||||
public Users(UserSessionData userSessionData, DataSource dataSource) {
|
||||
this.userSessionData = userSessionData;
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@GetMapping(produces = {"application/json"})
|
||||
@ResponseBody
|
||||
protected HashMap<Integer, HashMap> getUsers() {
|
||||
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
String query = "SELECT * FROM user_data";
|
||||
|
||||
try {
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
HashMap<Integer,HashMap> allUsersMap = new HashMap();
|
||||
HashMap<Integer, HashMap> allUsersMap = new HashMap();
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
ResultSetMetaData resultsMetaData = results.getMetaData();
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
while (results.next()) {
|
||||
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("last", results.getString(2));
|
||||
userMap.put("cc", results.getString(3));
|
||||
userMap.put("ccType", results.getString(4));
|
||||
userMap.put("cookie", results.getString(5));
|
||||
userMap.put("loginCount",Integer.toString(results.getInt(6)));
|
||||
allUsersMap.put(id,userMap);
|
||||
userMap.put("loginCount", Integer.toString(results.getInt(6)));
|
||||
allUsersMap.put(id, userMap);
|
||||
}
|
||||
userSessionData.setValue("allUsers",allUsersMap);
|
||||
userSessionData.setValue("allUsers", allUsersMap);
|
||||
return allUsersMap;
|
||||
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
HashMap<String,String> errMap = new HashMap() {{
|
||||
put("err",sqle.getErrorCode() + "::" + sqle.getMessage());
|
||||
HashMap<String, String> errMap = new HashMap() {{
|
||||
put("err", sqle.getErrorCode() + "::" + sqle.getMessage());
|
||||
}};
|
||||
|
||||
return new HashMap<Integer,HashMap>() {{
|
||||
put(0,errMap);
|
||||
return new HashMap<Integer, HashMap>() {{
|
||||
put(0, errMap);
|
||||
}};
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HashMap<String,String> errMap = new HashMap() {{
|
||||
put("err",e.getMessage() + "::" + e.getCause());
|
||||
HashMap<String, String> errMap = new HashMap() {{
|
||||
put("err", e.getMessage() + "::" + e.getCause());
|
||||
}};
|
||||
e.printStackTrace();
|
||||
return new HashMap<Integer,HashMap>() {{
|
||||
put(0,errMap);
|
||||
return new HashMap<Integer, HashMap>() {{
|
||||
put(0, errMap);
|
||||
}};
|
||||
|
||||
|
||||
@ -108,24 +104,15 @@ public class Users {
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
HashMap<String,String> errMap = new HashMap() {{
|
||||
put("err",e.getMessage() + "::" + e.getCause());
|
||||
HashMap<String, String> errMap = new HashMap() {{
|
||||
put("err", e.getMessage() + "::" + e.getCause());
|
||||
}};
|
||||
e.printStackTrace();
|
||||
return new HashMap<Integer,HashMap>() {{
|
||||
put(0,errMap);
|
||||
return new HashMap<>() {{
|
||||
put(0, errMap);
|
||||
}};
|
||||
|
||||
}
|
||||
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();
|
||||
init(yourHashTest);
|
||||
this.mockMvc = standaloneSetup(yourHashTest).build();
|
||||
this.mockDisplayUser = new DisplayUser(new WebGoatUser("user","userPass"));
|
||||
ReflectionTestUtils.setField(yourHashTest,"userService",userService);
|
||||
when(mockDisplayUser.getUserHash()).thenReturn("2340928sadfajsdalsNfwrBla=");
|
||||
when(userService.loadUserByUsername(any())).thenReturn(new WebGoatUser("user","userPass"));
|
||||
this.mockDisplayUser = new DisplayUser(new WebGoatUser("user", "userPass"));
|
||||
ReflectionTestUtils.setField(yourHashTest, "userService", userService);
|
||||
when(userService.loadUserByUsername(any())).thenReturn(new WebGoatUser("user", "userPass"));
|
||||
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
|
||||
}
|
||||
|
||||
|
@ -23,20 +23,16 @@
|
||||
package org.owasp.webgoat.sql_injection.advanced;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
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.web.bind.annotation.PutMapping;
|
||||
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.sql.*;
|
||||
|
||||
/**
|
||||
@ -48,28 +44,23 @@ import java.sql.*;
|
||||
@Slf4j
|
||||
public class SqlInjectionChallenge extends AssignmentEndpoint {
|
||||
|
||||
private static final String PASSWORD_TOM = "thisisasecretfortomonly";
|
||||
//Make it more random at runtime (good luck guessing)
|
||||
static final String USERS_TABLE_NAME = "challenge_users_6" + RandomStringUtils.randomAlphabetic(16);
|
||||
private final DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
|
||||
public SqlInjectionChallenge() {
|
||||
log.info("Challenge 6 tablename is: {}", USERS_TABLE_NAME);
|
||||
public SqlInjectionChallenge(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@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
|
||||
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);
|
||||
|
||||
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();
|
||||
ResultSet resultSet = statement.executeQuery(checkUserQuery);
|
||||
|
||||
@ -80,14 +71,14 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
|
||||
attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build();
|
||||
}
|
||||
} 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(2, email_reg);
|
||||
preparedStatement.setString(3, password_reg);
|
||||
preparedStatement.execute();
|
||||
attackResult = success().feedback("user.created").feedbackArgs(username_reg).build();
|
||||
}
|
||||
} catch(SQLException e) {
|
||||
} catch (SQLException e) {
|
||||
attackResult = failed().output("Something went wrong").build();
|
||||
}
|
||||
}
|
||||
@ -103,46 +94,5 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
|
||||
}
|
||||
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,27 +25,30 @@ package org.owasp.webgoat.sql_injection.advanced;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
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.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;
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value ={"SqlInjectionChallengeHint1", "SqlInjectionChallengeHint2", "SqlInjectionChallengeHint3", "SqlInjectionChallengeHint4"})
|
||||
@AssignmentHints(value = {"SqlInjectionChallengeHint1", "SqlInjectionChallengeHint2", "SqlInjectionChallengeHint3", "SqlInjectionChallengeHint4"})
|
||||
public class SqlInjectionChallengeLogin extends AssignmentEndpoint {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionChallengeLogin(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjectionAdvanced/challenge_Login")
|
||||
@ResponseBody
|
||||
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
|
||||
Connection connection = DatabaseUtilities.getConnection(webSession);
|
||||
SqlInjectionChallenge.checkDatabase(connection);
|
||||
|
||||
PreparedStatement statement = connection.prepareStatement("select password from " + SqlInjectionChallenge.USERS_TABLE_NAME + " where userid = ? and password = ?");
|
||||
try (var connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement("select password from sql_challenge_users where userid = ? and password = ?");
|
||||
statement.setString(1, username_login);
|
||||
statement.setString(2, password_login);
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
@ -57,4 +60,5 @@ public class SqlInjectionChallengeLogin extends AssignmentEndpoint {
|
||||
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.AttackResult;
|
||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjectionLesson5a;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.io.IOException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
|
||||
|
||||
@RestController
|
||||
@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 {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson6a(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjectionAdvanced/attack6a")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String userid_6a) throws IOException {
|
||||
public AttackResult completed(@RequestParam String userid_6a) {
|
||||
return injectableQuery(userid_6a);
|
||||
// The answer: Smith' union select userid,user_name, password,cookie,cookie, cookie,userid from user_system_data --
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String accountName) {
|
||||
String query = "";
|
||||
try(Connection connection = DatabaseUtilities.getConnection(getWebSession())) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
boolean usedUnion = true;
|
||||
query = "SELECT * FROM user_data WHERE last_name = '" + accountName + "'";
|
||||
//Check if Union is used
|
||||
if(!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) {
|
||||
if (!accountName.matches("(?i)(^[^-/*;)]*)(\\s*)UNION(.*$)")) {
|
||||
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 results = statement.executeQuery(query);
|
||||
|
||||
@ -65,7 +73,7 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
|
||||
output.append(SqlInjectionLesson5a.writeTable(results, resultsMetaData));
|
||||
|
||||
String appendingWhenSucceded;
|
||||
if(usedUnion)
|
||||
if (usedUnion)
|
||||
appendingWhenSucceded = "Well done! Can you also figure out a solution, by appending a new Sql Statement?";
|
||||
else
|
||||
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;
|
||||
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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 javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
@ -39,10 +41,16 @@ import java.sql.Statement;
|
||||
@RestController
|
||||
public class SqlInjectionLesson6b extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson6b(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjectionAdvanced/attack6b")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String userid_6b) throws IOException {
|
||||
if (userid_6b.toString().equals(getPassword())) {
|
||||
if (userid_6b.equals(getPassword())) {
|
||||
return trackProgress(success().build());
|
||||
} else {
|
||||
return trackProgress(failed().build());
|
||||
@ -50,18 +58,15 @@ public class SqlInjectionLesson6b extends AssignmentEndpoint {
|
||||
}
|
||||
|
||||
protected String getPassword() {
|
||||
|
||||
String password = "dave";
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
String query = "SELECT password FROM user_system_data WHERE user_name = 'dave'";
|
||||
|
||||
try {
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
if (results != null && results.first()) {
|
||||
password = results.getString("password");
|
||||
}
|
||||
} catch (SQLException sqle) {
|
||||
|
@ -23,16 +23,10 @@
|
||||
package org.owasp.webgoat.sql_injection.advanced;
|
||||
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
@RestController
|
||||
@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 {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson10(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack10")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String action_string) {
|
||||
@ -45,9 +57,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
||||
StringBuffer output = new StringBuffer();
|
||||
String query = "SELECT * FROM access_log WHERE action LIKE '%" + action + "%'";
|
||||
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
try {
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
@ -59,16 +69,14 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
||||
} else {
|
||||
if (tableExists(connection)) {
|
||||
return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return trackProgress(success().feedback("sql-injection.10.success").build());
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
if (tableExists(connection)) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
@ -80,7 +88,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
|
||||
|
||||
private boolean tableExists(Connection connection) {
|
||||
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");
|
||||
int cols = results.getMetaData().getColumnCount();
|
||||
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.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.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
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint2-1", "SqlStringInjectionHint2-2", "SqlStringInjectionHint2-3", "SqlStringInjectionHint2-4"})
|
||||
public class SqlInjectionLesson2 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson2(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack2")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String query) {
|
||||
return injectableQuery(query);
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String _query) {
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = _query;
|
||||
|
||||
try {
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = statement.executeQuery(_query);
|
||||
protected AttackResult injectableQuery(String query) {
|
||||
try (var connection = dataSource.getConnection()) {
|
||||
Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, 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>");
|
||||
output.append("<span class='feedback-positive'>" + query + "</span>");
|
||||
output.append(SqlInjectionLesson8.generateTable(results));
|
||||
return trackProgress(success().feedback("sql-injection.2.success").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) {
|
||||
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,16 +26,31 @@ package org.owasp.webgoat.sql_injection.introduction;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.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
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint3-1", "SqlStringInjectionHint3-2"})
|
||||
public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson3(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack3")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String query) {
|
||||
@ -43,15 +58,10 @@ public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String _query) {
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
String query = _query;
|
||||
|
||||
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);
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
try (Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
|
||||
Statement check_statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE,
|
||||
CONCUR_READ_ONLY);
|
||||
statement.executeUpdate(_query);
|
||||
ResultSet _results = check_statement.executeQuery("SELECT * FROM employees WHERE last_name='Barnett';");
|
||||
StringBuffer output = new StringBuffer();
|
||||
@ -66,7 +76,6 @@ public class SqlInjectionLesson3 extends AssignmentEndpoint {
|
||||
}
|
||||
|
||||
} catch (SQLException sqle) {
|
||||
|
||||
return trackProgress(failed().output(sqle.getMessage()).build());
|
||||
}
|
||||
} 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.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.io.IOException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
|
||||
import static java.sql.ResultSet.*;
|
||||
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint4-1", "SqlStringInjectionHint4-2", "SqlStringInjectionHint4-3"})
|
||||
public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson4(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack4")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String query) {
|
||||
@ -45,16 +54,11 @@ public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String _query) {
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
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);
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
try (Statement statement = connection.createStatement(TYPE_SCROLL_INSENSITIVE, CONCUR_READ_ONLY)) {
|
||||
statement.executeUpdate(_query);
|
||||
ResultSet _results = check_statement.executeQuery("SELECT phone from employees;");
|
||||
ResultSetMetaData _resultMetaData = _results.getMetaData();
|
||||
connection.commit();
|
||||
ResultSet _results = statement.executeQuery("SELECT phone from employees;");
|
||||
StringBuffer output = new StringBuffer();
|
||||
// user completes lesson if column phone exists
|
||||
if (_results.first()) {
|
||||
@ -63,9 +67,7 @@ public class SqlInjectionLesson4 extends AssignmentEndpoint {
|
||||
} else {
|
||||
return trackProgress(failed().output(output.toString()).build());
|
||||
}
|
||||
|
||||
} catch (SQLException sqle) {
|
||||
|
||||
return trackProgress(failed().output(sqle.getMessage()).build());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -38,13 +38,13 @@ public class SqlInjectionLesson5 extends AssignmentEndpoint {
|
||||
|
||||
@PostMapping("/SqlInjection/attack5")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam("_query") String query) {
|
||||
public AttackResult completed(String query) {
|
||||
return injectableQuery(query);
|
||||
}
|
||||
|
||||
protected AttackResult injectableQuery(String query) {
|
||||
try {
|
||||
String regex = "(?i)^(grant alter table to [\"']?unauthorizedUser[\"']?)(?:[;]?)$";
|
||||
String regex = "(?i)^(grant alter table to [']?unauthorizedUser[']?)(?:[;]?)$";
|
||||
StringBuffer output = new StringBuffer();
|
||||
|
||||
// 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.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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.io.IOException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
|
||||
|
||||
@ -41,6 +42,11 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint {
|
||||
+ "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>, "
|
||||
+ "which will always evaluate to true, no matter what came before it.";
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson5a(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/assignment5a")
|
||||
@ResponseBody
|
||||
@ -50,12 +56,9 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint {
|
||||
|
||||
protected AttackResult injectableQuery(String accountName) {
|
||||
String query = "";
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
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_READ_ONLY)) {
|
||||
|
||||
try (Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
if ((results != null) && (results.first())) {
|
||||
@ -73,10 +76,8 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint {
|
||||
}
|
||||
} 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) {
|
||||
|
@ -26,10 +26,13 @@ package org.owasp.webgoat.sql_injection.introduction;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
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 javax.servlet.http.HttpServletRequest;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.IOException;
|
||||
import java.sql.*;
|
||||
|
||||
@ -38,6 +41,12 @@ import java.sql.*;
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint5b1", "SqlStringInjectionHint5b2", "SqlStringInjectionHint5b3", "SqlStringInjectionHint5b4"})
|
||||
public class SqlInjectionLesson5b extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson5b(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/assignment5b")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {
|
||||
@ -46,15 +55,13 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint {
|
||||
|
||||
protected AttackResult injectableQuery(String login_count, String accountName) {
|
||||
String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName;
|
||||
try {
|
||||
Connection connection = DatabaseUtilities.getConnection(getWebSession());
|
||||
PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||
|
||||
int count = 0;
|
||||
try {
|
||||
count = Integer.parseInt(login_count);
|
||||
} catch(Exception e) {
|
||||
} catch (Exception e) {
|
||||
return trackProgress(failed().output("Could not parse: " + login_count + " to a number" +
|
||||
"<br> Your query was: " + queryString.replace("?", login_count)).build());
|
||||
}
|
||||
@ -62,8 +69,6 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint {
|
||||
query.setInt(1, count);
|
||||
//String query = "SELECT * FROM user_data WHERE Login_Count = " + login_count + " and userid = " + accountName, ;
|
||||
try {
|
||||
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
|
||||
ResultSet.CONCUR_READ_ONLY);
|
||||
ResultSet results = query.executeQuery();
|
||||
|
||||
if ((results != null) && (results.first() == true)) {
|
||||
|
@ -25,20 +25,29 @@ package org.owasp.webgoat.sql_injection.introduction;
|
||||
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
import org.owasp.webgoat.session.DatabaseUtilities;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.text.SimpleDateFormat;
|
||||
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 javax.sql.DataSource;
|
||||
import java.sql.*;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
||||
import static java.sql.ResultSet.*;
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint.8.1", "SqlStringInjectionHint.8.2", "SqlStringInjectionHint.8.3", "SqlStringInjectionHint.8.4", "SqlStringInjectionHint.8.5"})
|
||||
public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson8(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack8")
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam String name, @RequestParam String auth_tan) {
|
||||
@ -49,11 +58,9 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
|
||||
StringBuffer output = new StringBuffer();
|
||||
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 {
|
||||
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);
|
||||
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 + "')";
|
||||
|
||||
try {
|
||||
Statement statement = connection.createStatement();
|
||||
Statement statement = connection.createStatement(TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE);
|
||||
statement.executeUpdate(log_query);
|
||||
} catch (SQLException e) {
|
||||
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.AssignmentHints;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
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 org.hsqldb.jdbc.JDBCResultSet.*;
|
||||
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint.9.1", "SqlStringInjectionHint.9.2", "SqlStringInjectionHint.9.3", "SqlStringInjectionHint.9.4", "SqlStringInjectionHint.9.5"})
|
||||
public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson9(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjection/attack9")
|
||||
@ResponseBody
|
||||
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) {
|
||||
StringBuffer output = new StringBuffer();
|
||||
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 {
|
||||
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);
|
||||
ResultSet results = statement.executeQuery(query);
|
||||
|
||||
var test = results.getRow() != 0;
|
||||
if (results.getStatement() != null) {
|
||||
if (results.first()) {
|
||||
output.append(SqlInjectionLesson8.generateTable(results));
|
||||
@ -66,7 +72,6 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
||||
// no results
|
||||
return trackProgress(failed().feedback("sql-injection.8.no.results").build());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
System.err.println(e.getMessage());
|
||||
@ -84,7 +89,8 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
||||
private AttackResult checkSalaryRanking(Connection connection, StringBuffer output) {
|
||||
try {
|
||||
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);
|
||||
|
||||
results.first();
|
||||
@ -95,9 +101,8 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
|
||||
} else {
|
||||
return trackProgress(failed().feedback("sql-injection.9.one").output(output.toString()).build());
|
||||
}
|
||||
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,10 @@ import com.google.common.collect.Lists;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
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.web.bind.annotation.*;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -45,6 +43,8 @@ import java.util.List;
|
||||
@RequestMapping("SqlInjectionMitigations/servers")
|
||||
public class Servers {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private class Server {
|
||||
@ -57,14 +57,15 @@ public class Servers {
|
||||
private String description;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
public Servers(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@SneakyThrows
|
||||
@ResponseBody
|
||||
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);
|
||||
ResultSet rs = preparedStatement.executeQuery();
|
||||
List<Server> servers = Lists.newArrayList();
|
||||
|
@ -22,23 +22,20 @@
|
||||
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
import org.owasp.webgoat.assignments.AssignmentPath;
|
||||
import org.owasp.webgoat.assignments.AttackResult;
|
||||
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.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-10a-1", "SqlStringInjectionHint-mitigation-10a-10a2"})
|
||||
public class SqlInjectionLesson10a extends AssignmentEndpoint {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private String[] results = {"getConnection", "PreparedStatement", "prepareStatement", "?", "?", "setString", "setString"};
|
||||
|
||||
@PostMapping("/SqlInjectionMitigations/attack10a")
|
||||
@ -47,15 +44,15 @@ public class SqlInjectionLesson10a extends AssignmentEndpoint {
|
||||
String[] userInput = {field1, field2, field3, field4, field5, field6, field7};
|
||||
int position = 0;
|
||||
boolean completed = false;
|
||||
for(String input : userInput) {
|
||||
if(input.toLowerCase().contains(this.results[position].toLowerCase())) {
|
||||
for (String input : userInput) {
|
||||
if (input.toLowerCase().contains(this.results[position].toLowerCase())) {
|
||||
completed = true;
|
||||
} else {
|
||||
return trackProgress(failed().build());
|
||||
}
|
||||
position++;
|
||||
}
|
||||
if(completed) {
|
||||
if (completed) {
|
||||
return trackProgress(success().build());
|
||||
}
|
||||
return trackProgress(failed().build());
|
||||
|
@ -27,35 +27,32 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.owasp.webgoat.assignments.AssignmentEndpoint;
|
||||
import org.owasp.webgoat.assignments.AssignmentHints;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 6/13/17.
|
||||
*/
|
||||
@RestController
|
||||
@AssignmentHints(value = {"SqlStringInjectionHint-mitigation-12a-1", "SqlStringInjectionHint-mitigation-12a-2", "SqlStringInjectionHint-mitigation-12a-3", "SqlStringInjectionHint-mitigation-12a-4"})
|
||||
@Slf4j
|
||||
public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
||||
|
||||
@Autowired
|
||||
private WebSession webSession;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SqlInjectionLesson12a(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@PostMapping("/SqlInjectionMitigations/attack12a")
|
||||
@ResponseBody
|
||||
@SneakyThrows
|
||||
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.setString(1, ip);
|
||||
preparedStatement.setString(2, "webgoat-prd");
|
||||
@ -65,4 +62,5 @@ public class SqlInjectionLesson12a extends AssignmentEndpoint {
|
||||
}
|
||||
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=""/>
|
||||
<div class="listingblock">
|
||||
<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>
|
||||
<script>
|
||||
@ -151,7 +151,7 @@
|
||||
enctype="application/json;charset=UTF-8">
|
||||
<table>
|
||||
<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">
|
||||
<option>Smith</option>
|
||||
<option>'Smith</option>
|
||||
|
@ -5,7 +5,7 @@ public static String loadAccount() {
|
||||
// Parser returns only valid string data
|
||||
String accountID = getParser().getStringParameter(ACCT_ID, "");
|
||||
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;
|
||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||
statement.setString(1, accountID);
|
||||
|
@ -7,7 +7,7 @@ public static bool isUsernameValid(string username) {
|
||||
|
||||
// SqlConnection conn is set and opened elsewhere for brevity.
|
||||
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 );
|
||||
if ( isUsernameValid( 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:
|
||||
|
||||
----
|
||||
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:
|
||||
@ -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:
|
||||
|
||||
----
|
||||
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
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* */ are inline 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
|
||||
|
||||
Example: SELECT * FROM USERS; DROP TABLE USERS;
|
||||
Example: SELECT * FROM users; DROP TABLE users;
|
||||
----
|
||||
|
||||
[source]
|
||||
@ -21,7 +21,7 @@ Example: SELECT * FROM USERS; DROP TABLE USERS;
|
||||
',+,|| allows string concatenation
|
||||
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]
|
||||
------
|
||||
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.
|
||||
@ -50,7 +50,7 @@ The Join operator is used to combine rows from two ore more tables, based on a r
|
||||
|
||||
[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
|
@ -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:
|
||||
|
||||
----
|
||||
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`
|
||||
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
|
||||
|
@ -4,16 +4,16 @@ These are the best defense against SQL injection. They either do not have data
|
||||
|
||||
=== 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
|
||||
-------------------------------------------------------
|
||||
String query = "SELECT * FROM USERS WHERE LAST_NAME = ?";
|
||||
String query = "SELECT * FROM users WHERE last_name = ?";
|
||||
PreparedStatement statement = connection.prepareStatement(query);
|
||||
statement.setString(1, accountName);
|
||||
ResultSet results = statement.executeQuery();
|
||||
|
@ -4,9 +4,9 @@
|
||||
-------------------------------------------------------
|
||||
CREATE PROCEDURE ListCustomers(@Country nvarchar(30))
|
||||
AS
|
||||
SELECT CITY, COUNT(*)
|
||||
FROM CUSTOMERS
|
||||
WHERE COUNTRY LIKE @Country GROUP BY CITY
|
||||
SELECT city, COUNT(*)
|
||||
FROM customers
|
||||
WHERE country LIKE @Country GROUP BY city
|
||||
|
||||
|
||||
EXEC ListCustomers ‘USA’
|
||||
@ -17,7 +17,7 @@ EXEC ListCustomers ‘USA’
|
||||
CREATE PROEDURE getUser(@lastName nvarchar(25))
|
||||
AS
|
||||
declare @sql nvarchar(255)
|
||||
set @sql = 'SELECT * FROM USERS WHERE
|
||||
LASTNAME = + @LastName + '
|
||||
set @sql = 'SELECT * FROM users WHERE
|
||||
lastname = + @LastName + '
|
||||
exec sp_executesql @sql
|
||||
-------------------------------------------------------
|
||||
|
@ -12,8 +12,8 @@ RecordSet rs = null;
|
||||
try {
|
||||
pUserName = request.getParameter("UserName");
|
||||
if ( isUsernameValid (pUsername) ) {
|
||||
ps = conn.prepareStatement("SELECT * FROM USER_TABLE
|
||||
WHERE USERNAME = ? ");
|
||||
ps = conn.prepareStatement("SELECT * FROM user_table
|
||||
WHERE username = ? ");
|
||||
ps.setString(1, pUsername);
|
||||
rs = ps.execute();
|
||||
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:
|
||||
|
||||
------------------------------------------------------------
|
||||
"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.
|
||||
|
@ -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:
|
||||
|
||||
--------------------------------------------------
|
||||
"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.
|
||||
|
@ -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
|
||||
* Example:
|
||||
** Retrieve data:
|
||||
** SELECT PHONE +
|
||||
FROM EMPLOYEES +
|
||||
WHERE USERID = 96134;
|
||||
** SELECT phone +
|
||||
FROM employees +
|
||||
WHERE userid = 96134;
|
||||
** This statement delivers the phone number of the employee with the userid 96134.
|
||||
|
||||
=== 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:
|
||||
|
||||
* `+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; --+` +
|
||||
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; --+` +
|
||||
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; --+` +
|
||||
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.owasp.webgoat.plugins.LessonTest;
|
||||
import org.owasp.webgoat.session.WebgoatContext;
|
||||
import org.owasp.webgoat.sql_injection.introduction.SqlInjection;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
@ -22,19 +22,13 @@
|
||||
|
||||
package org.owasp.webgoat.sql_injection.introduction;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
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.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
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.mockito.junit.MockitoJUnitRunner;
|
||||
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.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.setup.MockMvcBuilders.standaloneSetup;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
SqlInjectionLesson5 sql = new SqlInjectionLesson5();
|
||||
init(sql);
|
||||
this.mockMvc = standaloneSetup(sql).build();
|
||||
when(webSession.getCurrentLesson()).thenReturn(new SqlInjection());
|
||||
|
||||
}
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SqlInjectionLesson5Test extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void grantSolution() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||
.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\""))
|
||||
.param("query","grant alter table to unauthorizedUser"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.output", CoreMatchers.containsString("grant")))
|
||||
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
|
||||
@ -71,7 +53,7 @@ public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
||||
@Test
|
||||
public void grantSolutionWithSingleQuotes() throws Exception {
|
||||
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)));
|
||||
@ -80,7 +62,7 @@ public class SqlInjectionLesson5Test extends AssignmentEndpointTest {
|
||||
@Test
|
||||
public void grantSolutionWrong() throws Exception {
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/attack5")
|
||||
.param("_query","grant alter table to me"))
|
||||
.param("query","grant alter table to me"))
|
||||
.andExpect(status().isOk())
|
||||
.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;
|
||||
|
||||
import org.junit.Ignore;
|
||||
@ -6,27 +28,21 @@ 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 org.springframework.util.LinkedMultiValueMap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
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.status;
|
||||
|
||||
/**
|
||||
* @author nbaars
|
||||
* @since 5/21/17.
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void knownAccountShouldDisplayData() throws Exception {
|
||||
var params = Map.of("account", "Smith", "operator", "", "injection", "");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.params(new LinkedMultiValueMap(params)))
|
||||
.param("account", "Smith")
|
||||
.param("operator", "")
|
||||
.param("injection", ""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(messages.getMessage("assignment.not.solved"))))
|
||||
@ -36,10 +52,9 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||
@Ignore
|
||||
@Test
|
||||
public void unknownAccount() throws Exception {
|
||||
var params = Map.of("account", "Smith", "operator", "", "injection", "");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.params(new LinkedMultiValueMap(params)))
|
||||
|
||||
.param("account", "Smith")
|
||||
.param("operator", "").param("injection", ""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", is(SqlInjectionLesson8Test.modifySpan(messages.getMessage("NoResultsMatched")))))
|
||||
@ -48,9 +63,10 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void sqlInjection() throws Exception {
|
||||
var params = Map.of("account", "'", "operator", "OR", "injection", "'1' = '1");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.params(new LinkedMultiValueMap(params)))
|
||||
.param("account", "'")
|
||||
.param("operator", "OR")
|
||||
.param("injection", "'1' = '1"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(true)))
|
||||
.andExpect(jsonPath("$.feedback", containsString("You have succeed")))
|
||||
@ -59,9 +75,10 @@ public class SqlInjectionLesson5aTest extends SqlLessonTest {
|
||||
|
||||
@Test
|
||||
public void sqlInjectionWrongShouldDisplayError() throws Exception {
|
||||
var params = Map.of("account", "Smith'", "operator", "OR", "injection", "'1' = '1'");
|
||||
mockMvc.perform(MockMvcRequestBuilders.post("/SqlInjection/assignment5a")
|
||||
.params(new LinkedMultiValueMap(params)))
|
||||
.param("account", "Smith'")
|
||||
.param("operator", "OR")
|
||||
.param("injection", "'1' = '1'"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("lessonCompleted", is(false)))
|
||||
.andExpect(jsonPath("$.feedback", containsString(messages.getMessage("assignment.not.solved"))))
|
||||
|
@ -22,21 +22,14 @@
|
||||
|
||||
package org.owasp.webgoat.sql_injection.introduction;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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.introduction.SqlInjection;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
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.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.status;
|
||||
|
||||
|
@ -22,20 +22,14 @@
|
||||
|
||||
package org.owasp.webgoat.sql_injection.introduction;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
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.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.status;
|
||||
|
||||
|
@ -1,19 +1,12 @@
|
||||
package org.owasp.webgoat.sql_injection.mitigation;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
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.web.servlet.request.MockMvcRequestBuilders;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
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.status;
|
||||
|
||||
|
@ -9,8 +9,12 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.DependsOn;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Driver;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@ -40,14 +44,12 @@ public class HSQLDBDatabaseConfig {
|
||||
return server;
|
||||
}
|
||||
|
||||
@Primary
|
||||
@Bean
|
||||
@DependsOn("hsqlStandalone")
|
||||
public DataSource dataSource(@Value("${spring.datasource.driver-class-name}") String driverClass,
|
||||
@Value("${spring.datasource.url}") String url) {
|
||||
return DataSourceBuilder.create()
|
||||
.driverClassName(driverClass)
|
||||
.url(url)
|
||||
.build();
|
||||
@Primary
|
||||
public DataSource dataSource(@Value("${spring.datasource.url}") String url) {
|
||||
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(url);
|
||||
driverManagerDataSource.setDriverClassName("org.hsqldb.jdbc.JDBCDriver");
|
||||
return driverManagerDataSource;
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,17 @@
|
||||
package org.owasp.webwolf;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.sql.DataSource;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@ -59,4 +64,12 @@ public class MvcConfiguration implements WebMvcConfigurer {
|
||||
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) {
|
||||
|
||||
Request req = t.getRequest();
|
||||
boolean allowed = true;
|
||||
/* 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
|
||||
|
||||
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.hibernate.ddl-auto=update
|
||||
spring.messages.basename=i18n/messages
|
||||
|
Reference in New Issue
Block a user