Allow WebGoat to create per-user databases
This creates the infrastructure to allow WebGoat to create per-user databases, so that any modifications made by one user do not affect other users. Some lessons may have made provision for this internally (e.g. CrossSiteScripting lesson), but this simplifies things generally. This also switches the default database from Access on windows, and Enhydra on Unix/other platforms to using HSQLDB, in an "in-memory" configuration. We may get performance problems from having too many instances of the database in memory at once at sites that have 10's of users banging on a central WebGoat. Only time will tell. git-svn-id: http://webgoat.googlecode.com/svn/trunk@190 4033779f-a91e-0410-96ef-6bf7bf53c507
This commit is contained in:
parent
9d19fa2433
commit
d04371884b
@ -2,7 +2,6 @@ package org.owasp.webgoat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.SQLException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
@ -212,12 +211,7 @@ public class HammerHead extends HttpServlet
|
||||
log(request, "Could not write error screen: "
|
||||
+ thr.getMessage());
|
||||
}
|
||||
try
|
||||
{
|
||||
WebSession.closeConnection();
|
||||
} catch (SQLException sqle) {
|
||||
sqle.printStackTrace();
|
||||
}
|
||||
WebSession.returnConnection(mySession);
|
||||
// System.out.println( "HH Leaving doPost: " );
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ public class BackDoors extends SequentialLessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
return connection;
|
||||
|
@ -72,7 +72,7 @@ public class BlindSqlInjection extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
ec.addElement(new P().addElement("Enter your Account Number: "));
|
||||
@ -335,7 +335,7 @@ public class BlindSqlInjection extends LessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -85,7 +85,7 @@ public class CSRF extends LessonAdapter {
|
||||
|
||||
if ( connection == null )
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection( s );
|
||||
connection = DatabaseUtilities.getConnection( s );
|
||||
}
|
||||
|
||||
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
|
||||
@ -173,7 +173,7 @@ public class CSRF extends LessonAdapter {
|
||||
{
|
||||
if ( connection == null )
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection( s );
|
||||
connection = DatabaseUtilities.getConnection( s );
|
||||
}
|
||||
|
||||
Statement statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY );
|
||||
@ -228,7 +228,7 @@ public class CSRF extends LessonAdapter {
|
||||
|
||||
if ( connection == null )
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection( s );
|
||||
connection = DatabaseUtilities.getConnection( s );
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,7 +208,7 @@ public class Challenge2Screen extends SequentialLessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Statement statement3 = connection.createStatement(
|
||||
|
@ -99,7 +99,7 @@ public class DOS_Login extends LessonAdapter
|
||||
// Check if the login is valid
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
String query = "SELECT * FROM user_system_data WHERE user_name = '"
|
||||
|
@ -428,7 +428,7 @@ public class SoapRequest extends SequentialLessonAdapter
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.makeConnection(getWebgoatContext());
|
||||
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
|
||||
if (connection == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -122,7 +122,7 @@ public class SqlNumericInjection extends SequentialLessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
try
|
||||
@ -188,7 +188,7 @@ public class SqlNumericInjection extends SequentialLessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
ec.addElement(makeStationList(s));
|
||||
@ -288,7 +288,7 @@ public class SqlNumericInjection extends SequentialLessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Map<String, String> stations = new TreeMap<String, String>();
|
||||
@ -395,7 +395,7 @@ public class SqlNumericInjection extends SequentialLessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -98,7 +98,7 @@ public class SqlStringInjection extends SequentialLessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
ec.addElement(makeAccountLine(s));
|
||||
@ -180,7 +180,7 @@ public class SqlStringInjection extends SequentialLessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
ec.addElement(makeAccountLine(s));
|
||||
@ -311,7 +311,7 @@ public class SqlStringInjection extends SequentialLessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -95,7 +95,7 @@ public class StoredXss extends LessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
String query = "INSERT INTO messages VALUES (?, ?, ?, ? )";
|
||||
@ -209,7 +209,7 @@ public class StoredXss extends LessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
// edit by Chuck Willis - Added logic to associate similar usernames
|
||||
@ -331,7 +331,7 @@ public class StoredXss extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Statement statement = connection.createStatement(
|
||||
|
@ -75,7 +75,7 @@ public class ThreadSafetyProblem extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
ec.addElement(new StringElement("Enter user name: "));
|
||||
@ -208,7 +208,7 @@ public class ThreadSafetyProblem extends LessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -221,7 +221,7 @@ public class WSDLScanning extends LessonAdapter
|
||||
int id = s.getParser().getIntParameter("id");
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Table t = new Table().setCellSpacing(0).setCellPadding(2)
|
||||
@ -290,7 +290,7 @@ public class WSDLScanning extends LessonAdapter
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.makeConnection(getWebgoatContext());
|
||||
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
|
||||
if (connection == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -186,7 +186,7 @@ public class WsSqlInjection extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
ec.addElement(makeAccountLine(s));
|
||||
|
||||
@ -246,7 +246,7 @@ public class WsSqlInjection extends LessonAdapter
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection connection = DatabaseUtilities.makeConnection(getWebgoatContext());
|
||||
Connection connection = DatabaseUtilities.getConnection("guest", getWebgoatContext());
|
||||
if (connection == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -66,7 +66,7 @@ public class ProductsAdminScreen extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Statement statement = connection.createStatement(
|
||||
|
@ -155,7 +155,7 @@ public class RefreshDBScreen extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
CreateDB db = new CreateDB();
|
||||
|
@ -66,7 +66,7 @@ public class UserAdminScreen extends LessonAdapter
|
||||
{
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
Statement statement = connection.createStatement(
|
||||
|
@ -77,7 +77,7 @@ public class ViewDatabase extends LessonAdapter
|
||||
|
||||
if (connection == null)
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection(s);
|
||||
connection = DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
if (sqlStatement.length() > 0)
|
||||
|
@ -6,6 +6,9 @@ import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.ecs.MultiPartElement;
|
||||
import org.apache.ecs.html.B;
|
||||
import org.apache.ecs.html.TD;
|
||||
@ -46,23 +49,50 @@ import org.apache.ecs.html.Table;
|
||||
public class DatabaseUtilities
|
||||
{
|
||||
|
||||
/**
|
||||
* Description of the Method
|
||||
*
|
||||
* @param s Description of the Parameter
|
||||
*
|
||||
* @return Description of the Return Value
|
||||
*
|
||||
* @exception ClassNotFoundException Description of the Exception
|
||||
* @exception SQLException Description of the Exception
|
||||
*/
|
||||
public static Connection makeConnection(WebSession s)
|
||||
throws ClassNotFoundException, SQLException
|
||||
{
|
||||
return makeConnection(s.getWebgoatContext());
|
||||
}
|
||||
private static Map<String, Connection> connections = new HashMap<String, Connection>();
|
||||
private static Map<String, Boolean> dbBuilt = new HashMap<String, Boolean>();
|
||||
|
||||
public static Connection makeConnection(WebgoatContext context)
|
||||
public static Connection getConnection(WebSession s)
|
||||
throws ClassNotFoundException, SQLException
|
||||
{
|
||||
return getConnection(s.getUserName(), s.getWebgoatContext());
|
||||
}
|
||||
|
||||
public static Connection getConnection(String user, WebgoatContext context)
|
||||
throws ClassNotFoundException, 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;
|
||||
}
|
||||
|
||||
public static 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();
|
||||
}
|
||||
}
|
||||
|
||||
public static Connection makeConnection(String user, WebgoatContext context)
|
||||
throws ClassNotFoundException, SQLException
|
||||
{
|
||||
Class.forName(context.getDatabaseDriver());
|
||||
@ -72,8 +102,8 @@ public class DatabaseUtilities
|
||||
if (password == null || password.equals("")) {
|
||||
return (DriverManager.getConnection(conn));
|
||||
} else {
|
||||
String user = context.getDatabaseUser();
|
||||
return DriverManager.getConnection(conn, user, password);
|
||||
String userPrefix = context.getDatabaseUser();
|
||||
return DriverManager.getConnection(conn, userPrefix + "_" + user, password);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,8 +156,6 @@ public class WebSession
|
||||
|
||||
private int previousScreen = ERROR;
|
||||
|
||||
private static Connection connection = null;
|
||||
|
||||
private int hintNum = -1;
|
||||
|
||||
private boolean isAdmin = false;
|
||||
@ -217,20 +215,11 @@ public class WebSession
|
||||
public static synchronized Connection getConnection(WebSession s)
|
||||
throws SQLException, ClassNotFoundException
|
||||
{
|
||||
if ( connection == null || connection.isClosed() )
|
||||
{
|
||||
connection = DatabaseUtilities.makeConnection( s );
|
||||
}
|
||||
|
||||
return connection;
|
||||
return DatabaseUtilities.getConnection(s);
|
||||
}
|
||||
|
||||
public static synchronized void closeConnection() throws SQLException
|
||||
{
|
||||
if (connection != null && !connection.isClosed()) {
|
||||
connection.close();
|
||||
connection = null;
|
||||
}
|
||||
public static void returnConnection(WebSession s) {
|
||||
DatabaseUtilities.returnConnection(s.getUserName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.owasp.webgoat.session;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
public class WebgoatContext {
|
||||
@ -32,8 +30,6 @@ public class WebgoatContext {
|
||||
|
||||
public final static String DEBUG = "debug";
|
||||
|
||||
private static boolean databaseBuilt = false;
|
||||
|
||||
private String databaseConnectionString;
|
||||
|
||||
private String realConnectionString = null;
|
||||
@ -84,18 +80,6 @@ public class WebgoatContext {
|
||||
isDebug = "true".equals( servlet.getInitParameter( DEBUG ) );
|
||||
servletName = servlet.getServletName();
|
||||
|
||||
// FIXME: need to solve concurrency problem here -- make tables for this user
|
||||
if ( !databaseBuilt ) {
|
||||
try {
|
||||
Connection conn = DatabaseUtilities.makeConnection(this);
|
||||
new CreateDB().makeDB(conn);
|
||||
conn.close();
|
||||
databaseBuilt = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
BIN
webgoat/main/project/WebContent/WEB-INF/lib/hsqldb.jar
Normal file
BIN
webgoat/main/project/WebContent/WEB-INF/lib/hsqldb.jar
Normal file
Binary file not shown.
Binary file not shown.
@ -145,17 +145,14 @@
|
||||
<init-param>
|
||||
<param-name>DatabaseDriver</param-name>
|
||||
<param-value>
|
||||
sun.jdbc.odbc.JdbcOdbcDriver
|
||||
<!--org.enhydra.instantdb.jdbc.idbDriver-->
|
||||
org.hsqldb.jdbcDriver
|
||||
</param-value>
|
||||
</init-param>
|
||||
|
||||
<init-param>
|
||||
<param-name>DatabaseConnectionString</param-name>
|
||||
<param-value>
|
||||
<!-- insert the word PATH where you want to insert the realpath to the base of the web context-->
|
||||
<!--jdbc:idb:PATH/database.prp-->
|
||||
jdbc:odbc:;DRIVER=Microsoft Access Driver (*.mdb);DBQ=PATH/webgoat.mdb;PWD=webgoat"
|
||||
jdbc:hsqldb:.
|
||||
</param-value>
|
||||
</init-param>
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
DROP USER webgoat CASCADE;
|
||||
CREATE USER webgoat IDENTIFIED BY webgoat DEFAULT TABLESPACE users;
|
||||
GRANT CONNECT, RESOURCE TO webgoat;
|
||||
GRANT CREATE PROCEDURE TO webgoat;
|
||||
DROP USER webgoat_guest CASCADE;
|
||||
CREATE USER webgoat_guest IDENTIFIED BY webgoat DEFAULT TABLESPACE users;
|
||||
GRANT CONNECT, RESOURCE TO webgoat_guest;
|
||||
GRANT CREATE PROCEDURE TO webgoat_guest;
|
||||
|
||||
CREATE TABLE WEBGOAT.EMPLOYEE (
|
||||
CREATE TABLE WEBGOAT_guest.EMPLOYEE (
|
||||
userid INT NOT NULL PRIMARY KEY,
|
||||
first_name VARCHAR(20),
|
||||
last_name VARCHAR(20),
|
||||
@ -24,7 +24,7 @@ CREATE TABLE WEBGOAT.EMPLOYEE (
|
||||
);
|
||||
|
||||
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) AS
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT_guest.EMPLOYEE_LOGIN(v_id NUMBER, v_password VARCHAR) AS
|
||||
stmt VARCHAR(32767);v_userid NUMBER;
|
||||
BEGIN
|
||||
stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || '''';
|
||||
@ -32,7 +32,7 @@ BEGIN
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT.EMPLOYEE_LOGIN_BACKUP(v_id NUMBER, v_password VARCHAR) AS
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT_guest.EMPLOYEE_LOGIN_BACKUP(v_id NUMBER, v_password VARCHAR) AS
|
||||
stmt VARCHAR(32767);v_userid NUMBER;
|
||||
BEGIN
|
||||
stmt := 'SELECT USERID FROM EMPLOYEE WHERE USERID = ' || v_id || ' AND PASSWORD = ''' || v_password || '''';
|
||||
@ -40,7 +40,7 @@ BEGIN
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT.UPDATE_EMPLOYEE(
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT_guest.UPDATE_EMPLOYEE(
|
||||
v_userid IN employee.userid%type,
|
||||
v_first_name IN employee.first_name%type,
|
||||
v_last_name IN employee.last_name%type,
|
||||
@ -82,7 +82,7 @@ BEGIN
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT.UPDATE_EMPLOYEE_BACKUP(
|
||||
CREATE OR REPLACE PROCEDURE WEBGOAT_guest.UPDATE_EMPLOYEE_BACKUP(
|
||||
v_userid IN employee.userid%type,
|
||||
v_first_name IN employee.first_name%type,
|
||||
v_last_name IN employee.last_name%type,
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user