logging, formatting

This commit is contained in:
lawson89 2014-06-03 15:41:50 -04:00
parent 10be6757af
commit a0d4a02f0a
6 changed files with 1800 additions and 2015 deletions

View File

@ -64,7 +64,6 @@ public class HammerHead extends HttpServlet {
final Logger logger = LoggerFactory.getLogger(HammerHead.class);
private static final String WELCOMED = "welcomed";
/**
@ -82,7 +81,7 @@ public class HammerHead extends HttpServlet {
*/
private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2;
// private final static int sessionTimeoutSeconds = 1;
// private final static int sessionTimeoutSeconds = 1;
/**
* Properties file path
*/
@ -121,10 +120,9 @@ public class HammerHead extends HttpServlet {
WebSession mySession = null;
try {
// System.out.println( "HH Entering doPost: " );
// System.out.println( " - HH request " + request);
// System.out.println( " - HH principle: " +
// request.getUserPrincipal() );
logger.debug("Entering doPost");
logger.debug("request: " + request);
logger.debug("principle: " + request.getUserPrincipal());
// setCacheHeaders(response, 0);
ServletContext context = getServletContext();
@ -132,6 +130,7 @@ public class HammerHead extends HttpServlet {
// call makeScreen() and writeScreen()
mySession = updateSession(request, response, context);
if (response.isCommitted()) {
logger.debug("Response already committed, exiting");
return;
}
@ -142,7 +141,8 @@ public class HammerHead extends HttpServlet {
// where the lesson "knows" what has happened. To track it at a
// latter point would
// require the lesson to have memory.
screen = makeScreen(mySession); // This calls the lesson's
screen = makeScreen(mySession);
// This calls the lesson's
// handleRequest()
if (response.isCommitted()) {
return;
@ -178,21 +178,20 @@ public class HammerHead extends HttpServlet {
request.setAttribute("client.browser", clientBrowser);
request.getSession().setAttribute("websession", mySession);
request.getSession().setAttribute("course", mySession.getCourse());
request.getRequestDispatcher(getViewPage(mySession)).forward(request, response);
String viewPage = getViewPage(mySession);
logger.debug("Forwarding to view: " + viewPage);
request.getRequestDispatcher(viewPage).forward(request, response);
} catch (Throwable t) {
t.printStackTrace();
log("ERROR: " + t);
logger.error("Error handling request", t);
screen = new ErrorScreen(mySession, t);
} finally {
try {
this.writeScreen(mySession, screen, response);
} catch (Throwable thr) {
thr.printStackTrace();
log(request, "Could not write error screen: " + thr.getMessage());
logger.error("Could not write error screen", thr);
}
WebSession.returnConnection(mySession);
// System.out.println( "HH Leaving doPost: " );
logger.debug("Leaving doPost: ");
}
}
@ -240,6 +239,7 @@ public class HammerHead extends HttpServlet {
*/
@Override
public void init() throws ServletException {
logger.info("Initializing main webgoat servlet");
httpDateFormat = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
httpDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
propertiesPath = getServletContext().getRealPath("./WEB-INF/webgoat.properties");
@ -280,7 +280,7 @@ public class HammerHead extends HttpServlet {
} else {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson == null && s.isHackedAdmin()) {
// If admin was hacked, let the user see some of the
// If admin was hacked, let the user see some of the
// admin screens
lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE);
}
@ -288,7 +288,7 @@ public class HammerHead extends HttpServlet {
if (lesson != null) {
screen = lesson;
// We need to do some bookkeeping for the hackable admin
// We need to do some bookkeeping for the hackable admin
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
@ -307,7 +307,7 @@ public class HammerHead extends HttpServlet {
if (scr == WebSession.WELCOME) {
screen = new WelcomeAdminScreen(s);
} else {
// Admin can see all roles.
// Admin can see all roles.
// FIXME: should be able to pass a list of roles.
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.ADMIN_ROLE);
if (lesson == null) {
@ -320,7 +320,7 @@ public class HammerHead extends HttpServlet {
if (lesson != null) {
screen = lesson;
// We need to do some bookkeeping for the hackable admin
// We need to do some bookkeeping for the hackable admin
// interface.
// This is the only place we can tell if the user
// successfully hacked the hackable
@ -374,7 +374,7 @@ public class HammerHead extends HttpServlet {
HttpSession hs;
hs = request.getSession(true);
// System.out.println( "HH Entering Session_id: " + hs.getId() );
// System.out.println( "HH Entering Session_id: " + hs.getId() );
// dumpSession( hs );
// Get our session object out of the HTTP session
WebSession session = null;
@ -383,7 +383,7 @@ public class HammerHead extends HttpServlet {
if ((o != null) && o instanceof WebSession) {
session = (WebSession) o;
} else {
// Create new custom session and save it in the HTTP session
// Create new custom session and save it in the HTTP session
// System.out.println( "HH Creating new WebSession: " );
session = new WebSession(webgoatContext, context);
// Ensure splash screen shows on any restart
@ -396,7 +396,7 @@ public class HammerHead extends HttpServlet {
session.update(request, response, this.getServletName());
// to authenticate
// to authenticate
// System.out.println( "HH Leaving Session_id: " + hs.getId() );
// dumpSession( hs );
return (session);
@ -419,7 +419,7 @@ public class HammerHead extends HttpServlet {
screen = new ErrorScreen(s, "Page to display was null");
}
// set the content-length of the response.
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength(screen.getContentLength());
response.setHeader("Content-Length", screen.getContentLength() + "");

View File

@ -1,173 +1,166 @@
package org.owasp.webgoat.lessons;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 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 code.google.com, a repository for free software
* projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class Category implements Comparable
{
public final static Category INTRODUCTION = new Category("Introduction", new Integer(5));
public final static Category GENERAL = new Category("General", new Integer(100));
public final static Category ACCESS_CONTROL = new Category("Access Control Flaws", new Integer(200));
public final static Category AJAX_SECURITY = new Category("AJAX Security", new Integer(400));
public final static Category AUTHENTICATION = new Category("Authentication Flaws", new Integer(500));
public final static Category BUFFER_OVERFLOW = new Category("Buffer Overflows", new Integer(600));
public final static Category CODE_QUALITY = new Category("Code Quality", new Integer(700));
public final static Category CONCURRENCY = new Category("Concurrency", new Integer(800));
public final static Category XSS = new Category("Cross-Site Scripting (XSS)", new Integer(900));
public final static Category ERROR_HANDLING = new Category("Improper Error Handling", new Integer(1000));
public final static Category INJECTION = new Category("Injection Flaws", new Integer(1100));
public final static Category DOS = new Category("Denial of Service", new Integer(1200));
public final static Category INSECURE_COMMUNICATION = new Category("Insecure Communication", new Integer(1300));
public final static Category INSECURE_CONFIGURATION = new Category("Insecure Configuration", new Integer(1400));
public final static Category INSECURE_STORAGE = new Category("Insecure Storage", new Integer(1500));
public final static Category MALICIOUS_EXECUTION = new Category("Malicious Execution", new Integer(1600));
public final static Category PARAMETER_TAMPERING = new Category("Parameter Tampering", new Integer(1700));
public final static Category SESSION_MANAGEMENT = new Category("Session Management Flaws", new Integer(1800));
public final static Category WEB_SERVICES = new Category("Web Services", new Integer(1900));
public final static Category ADMIN_FUNCTIONS = new Category("Admin Functions", new Integer(2000));
public final static Category CHALLENGE = new Category("Challenge", new Integer(3000));
private static final List<Category> categories = new ArrayList<Category>();
private String category;
private Integer ranking;
static
{
categories.add(INTRODUCTION);
categories.add(PARAMETER_TAMPERING);
categories.add(ACCESS_CONTROL);
categories.add(AUTHENTICATION);
categories.add(SESSION_MANAGEMENT);
categories.add(XSS);
categories.add(BUFFER_OVERFLOW);
categories.add(INJECTION);
categories.add(MALICIOUS_EXECUTION);
categories.add(ERROR_HANDLING);
categories.add(INSECURE_STORAGE);
categories.add(DOS);
categories.add(INSECURE_CONFIGURATION);
categories.add(WEB_SERVICES);
categories.add(AJAX_SECURITY);
categories.add(ADMIN_FUNCTIONS);
categories.add(GENERAL);
categories.add(CODE_QUALITY);
categories.add(CONCURRENCY);
categories.add(INSECURE_COMMUNICATION);
categories.add(CHALLENGE);
}
public static synchronized void addCategory(Category c)
{
categories.add(c);
}
public static synchronized Category getCategory(String name)
{
Iterator<Category> it = categories.iterator();
while (it.hasNext())
{
Category c = it.next();
if (c.getName().equals(name)) return c;
}
return null;
}
public Category(String category, Integer ranking)
{
this.category = category;
this.ranking = ranking;
}
public int compareTo(Object obj)
{
int value = 1;
if (obj instanceof Category)
{
value = this.getRanking().compareTo(((Category) obj).getRanking());
}
return value;
}
public Integer getRanking()
{
return ranking;
}
public Integer setRanking(Integer ranking)
{
return this.ranking = ranking;
}
public String getName()
{
return category;
}
public boolean equals(Object obj)
{
return (obj instanceof Category) && getName().equals(((Category) obj).getName());
}
public String toString()
{
return getName();
}
}
package org.owasp.webgoat.lessons;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 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 code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class Category implements Comparable {
public final static Category INTRODUCTION = new Category("Introduction", new Integer(5));
public final static Category GENERAL = new Category("General", new Integer(100));
public final static Category ACCESS_CONTROL = new Category("Access Control Flaws", new Integer(200));
public final static Category AJAX_SECURITY = new Category("AJAX Security", new Integer(400));
public final static Category AUTHENTICATION = new Category("Authentication Flaws", new Integer(500));
public final static Category BUFFER_OVERFLOW = new Category("Buffer Overflows", new Integer(600));
public final static Category CODE_QUALITY = new Category("Code Quality", new Integer(700));
public final static Category CONCURRENCY = new Category("Concurrency", new Integer(800));
public final static Category XSS = new Category("Cross-Site Scripting (XSS)", new Integer(900));
public final static Category ERROR_HANDLING = new Category("Improper Error Handling", new Integer(1000));
public final static Category INJECTION = new Category("Injection Flaws", new Integer(1100));
public final static Category DOS = new Category("Denial of Service", new Integer(1200));
public final static Category INSECURE_COMMUNICATION = new Category("Insecure Communication", new Integer(1300));
public final static Category INSECURE_CONFIGURATION = new Category("Insecure Configuration", new Integer(1400));
public final static Category INSECURE_STORAGE = new Category("Insecure Storage", new Integer(1500));
public final static Category MALICIOUS_EXECUTION = new Category("Malicious Execution", new Integer(1600));
public final static Category PARAMETER_TAMPERING = new Category("Parameter Tampering", new Integer(1700));
public final static Category SESSION_MANAGEMENT = new Category("Session Management Flaws", new Integer(1800));
public final static Category WEB_SERVICES = new Category("Web Services", new Integer(1900));
public final static Category ADMIN_FUNCTIONS = new Category("Admin Functions", new Integer(2000));
public final static Category CHALLENGE = new Category("Challenge", new Integer(3000));
private static final List<Category> categories = new ArrayList<Category>();
private String category;
private Integer ranking;
static {
categories.add(INTRODUCTION);
categories.add(PARAMETER_TAMPERING);
categories.add(ACCESS_CONTROL);
categories.add(AUTHENTICATION);
categories.add(SESSION_MANAGEMENT);
categories.add(XSS);
categories.add(BUFFER_OVERFLOW);
categories.add(INJECTION);
categories.add(MALICIOUS_EXECUTION);
categories.add(ERROR_HANDLING);
categories.add(INSECURE_STORAGE);
categories.add(DOS);
categories.add(INSECURE_CONFIGURATION);
categories.add(WEB_SERVICES);
categories.add(AJAX_SECURITY);
categories.add(ADMIN_FUNCTIONS);
categories.add(GENERAL);
categories.add(CODE_QUALITY);
categories.add(CONCURRENCY);
categories.add(INSECURE_COMMUNICATION);
categories.add(CHALLENGE);
}
public static synchronized void addCategory(Category c) {
categories.add(c);
}
public static synchronized Category getCategory(String name) {
Iterator<Category> it = categories.iterator();
while (it.hasNext()) {
Category c = it.next();
if (c.getName().equals(name)) {
return c;
}
}
return null;
}
public Category(String category, Integer ranking) {
this.category = category;
this.ranking = ranking;
}
@Override
public int compareTo(Object obj) {
int value = 1;
if (obj instanceof Category) {
value = this.getRanking().compareTo(((Category) obj).getRanking());
}
return value;
}
public Integer getRanking() {
return ranking;
}
public Integer setRanking(Integer ranking) {
return this.ranking = ranking;
}
public String getName() {
return category;
}
@Override
public boolean equals(Object obj) {
return (obj instanceof Category) && getName().equals(((Category) obj).getName());
}
@Override
public String toString() {
return getName();
}
}

View File

@ -1,452 +1,392 @@
package org.owasp.webgoat.session;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.LinkedList;
import javax.servlet.ServletContext;
import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 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 code.google.com, a repository for free software
* projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class Course
{
private List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
private WebgoatProperties properties = null;
private List<String> files = new LinkedList<String>();
private WebgoatContext webgoatContext;
public Course()
{
try
{
properties = new WebgoatProperties(PROPERTIES_FILENAME);
} catch (IOException e)
{
System.out.println("Error loading WebGoat properties");
e.printStackTrace();
}
}
/**
* Take an absolute file and return the filename.
*
* Ex. /etc/password becomes password
*
* @param s
* @return the file name
*/
private static String getFileName(String s)
{
String fileName = new File(s).getName();
if (fileName.indexOf("/") != -1)
{
fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
}
if (fileName.indexOf(".") != -1)
{
fileName = fileName.substring(0, fileName.indexOf("."));
}
return fileName;
}
/**
* Take a class name and return the equivalent file name
*
* Ex. org.owasp.webgoat becomes org/owasp/webgoat.java
*
* @param className
* @return
*/
private static String getSourceFile(String className)
{
StringBuffer sb = new StringBuffer();
sb.append(className.replace(".", "/"));
sb.append(".java");
return sb.toString();
}
/**
* Takes a file name and builds the class file name
*
* @param fileName
* Description of the Parameter
* @param path
* Description of the Parameter
* @return Description of the Return Value
*/
private static String getClassFile(String fileName, String path)
{
String ext = ".class";
fileName = fileName.trim();
/**
* We do not handle directories.
* We do not handle files with different extensions
*/
if (fileName.endsWith("/") || !fileName.endsWith(ext)) { return null; }
// if the file is in /WEB-INF/classes strip the dir info off
int index = fileName.indexOf("/WEB-INF/classes/");
if (index != -1)
{
fileName = fileName.substring(index + "/WEB-INF/classes/".length(), fileName.length() - ext.length());
fileName = fileName.replace('/', '.');
fileName = fileName.replace('\\', '.');
}
else
{
// Strip off the leading path info
fileName = fileName.substring(path.length(), fileName.length() - ext.length());
}
return fileName;
}
/**
* Gets the categories attribute of the Course object
*
* @return The categories value
*/
public List getCategories()
{
List<Category> categories = new ArrayList<Category>();
Iterator iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = (AbstractLesson) iter.next();
if (!categories.contains(lesson.getCategory()))
{
categories.add(lesson.getCategory());
}
}
Collections.sort(categories);
return categories;
}
/**
* Gets the firstLesson attribute of the Course object
*
* @return The firstLesson value
*/
public AbstractLesson getFirstLesson()
{
List<String> roles = new ArrayList<String>();
roles.add(AbstractLesson.USER_ROLE);
// Category 0 is the admin function. We want the first real category
// to be returned. This is noramally the General category and the Http Basics lesson
return ((AbstractLesson) getLessons((Category) getCategories().get(0), roles).get(0));
}
/**
* Gets the lesson attribute of the Course object
*
* @param lessonId
* Description of the Parameter
* @param role
* Description of the Parameter
* @return The lesson value
*/
public AbstractLesson getLesson(WebSession s, int lessonId, List<String> roles)
{
if (s.isHackedAdmin())
{
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
// System.out.println("getLesson() with roles: " + roles);
Iterator<AbstractLesson> iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = iter.next();
// System.out.println("getLesson() at role: " + lesson.getRole());
if (lesson.getScreenId() == lessonId && roles.contains(lesson.getRole())) { return lesson; }
}
return null;
}
public AbstractLesson getLesson(WebSession s, int lessonId, String role)
{
List<String> roles = new Vector<String>();
roles.add(role);
return getLesson(s, lessonId, roles);
}
public List getLessons(WebSession s, String role)
{
List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, roles);
}
/**
* Gets the lessons attribute of the Course object
*
* @param role
* Description of the Parameter
* @return The lessons value
*/
public List<AbstractLesson> getLessons(WebSession s, List<String> roles)
{
if (s.isHackedAdmin())
{
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator categoryIter = getCategories().iterator();
while (categoryIter.hasNext())
{
lessonList.addAll(getLessons(s, (Category) categoryIter.next(), roles));
}
return lessonList;
}
/**
* Gets the lessons attribute of the Course object
*
* @param category
* Description of the Parameter
* @param role
* Description of the Parameter
* @return The lessons value
*/
private List<AbstractLesson> getLessons(Category category, List roles)
{
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator iter = lessons.iterator();
while (iter.hasNext())
{
AbstractLesson lesson = (AbstractLesson) iter.next();
if (lesson.getCategory().equals(category) && roles.contains(lesson.getRole()))
{
lessonList.add(lesson);
}
}
Collections.sort(lessonList);
// System.out.println(java.util.Arrays.asList(lessonList));
return lessonList;
}
public List getLessons(WebSession s, Category category, String role)
{
List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, category, roles);
}
public List<AbstractLesson> getLessons(WebSession s, Category category, List<String> roles)
{
if (s.isHackedAdmin())
{
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
return getLessons(category, roles);
}
/**
* Load all of the filenames into a temporary cache
*
* @param context
* @param path
*/
private void loadFiles(ServletContext context, String path)
{
Set resourcePaths = context.getResourcePaths(path);
Iterator itr = resourcePaths.iterator();
while (itr.hasNext())
{
String file = (String) itr.next();
if (file.length() != 1 && file.endsWith("/"))
{
loadFiles(context, file);
}
else
{
files.add(file);
}
}
}
/**
* Instantiate all the lesson objects into a cache
*
* @param path
*/
private void loadLessons(String path)
{
Iterator itr = files.iterator();
while (itr.hasNext())
{
String file = (String) itr.next();
String className = getClassFile(file, path);
if (className != null && !className.endsWith("_i"))
{
try
{
Class c = Class.forName(className);
Object o = c.newInstance();
if (o instanceof AbstractLesson)
{
AbstractLesson lesson = (AbstractLesson) o;
lesson.setWebgoatContext(webgoatContext);
lesson.update(properties);
if (lesson.getHidden() == false)
{
lessons.add(lesson);
}
}
} catch (Exception e)
{
// System.out.println("Warning: " + e.getMessage());
}
}
}
}
private String getLanguageFromFileName(String first, String absoluteFile){
int p1 = absoluteFile.indexOf("/",absoluteFile.indexOf(first)+1);
int p2 = absoluteFile.indexOf("/",p1+1);
String langStr=absoluteFile.substring(p1+1,p2);
return new String(langStr);
}
/**
* For each lesson, set the source file and lesson file
*/
private void loadResources()
{
Iterator lessonItr = lessons.iterator();
while (lessonItr.hasNext())
{
AbstractLesson lesson = (AbstractLesson) lessonItr.next();
String className = lesson.getClass().getName();
String classFile = getSourceFile(className);
Iterator fileItr = files.iterator();
while (fileItr.hasNext())
{
String absoluteFile = (String) fileItr.next();
String fileName = getFileName(absoluteFile);
// System.out.println("Course: looking at file: " + absoluteFile);
if (absoluteFile.endsWith(classFile))
{
// System.out.println("Set source file for " + classFile);
lesson.setSourceFileName(absoluteFile);
}
if (absoluteFile.startsWith("/lesson_plans") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName))
{
// System.out.println("DEBUG: setting lesson plan file " + absoluteFile + " for
// lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
String language = getLanguageFromFileName("/lesson_plans",absoluteFile);
lesson.setLessonPlanFileName(language, absoluteFile);
this.webgoatContext.getWebgoatI18N().loadLanguage(language);
}
if (absoluteFile.startsWith("/lesson_solutions") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName))
{
// System.out.println("DEBUG: setting lesson solution file " + absoluteFile + "
// for lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
lesson.setLessonSolutionFileName(absoluteFile);
}
}
}
}
/**
* Description of the Method
*
* @param path
* Description of the Parameter
* @param context
* Description of the Parameter
*/
public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path)
{
this.webgoatContext = webgoatContext;
loadFiles(context, path);
loadLessons(path);
loadResources();
}
}
package org.owasp.webgoat.session;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import java.util.LinkedList;
import javax.servlet.ServletContext;
import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 2007 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 code.google.com, a repository
* for free software projects.
*
* For details, please see http://code.google.com/p/webgoat/
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @created October 28, 2003
*/
public class Course {
private List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
private WebgoatProperties properties = null;
private List<String> files = new LinkedList<String>();
private WebgoatContext webgoatContext;
public Course() {
try {
properties = new WebgoatProperties(PROPERTIES_FILENAME);
} catch (IOException e) {
System.out.println("Error loading WebGoat properties");
e.printStackTrace();
}
}
/**
* Take an absolute file and return the filename.
*
* Ex. /etc/password becomes password
*
* @param s
* @return the file name
*/
private static String getFileName(String s) {
String fileName = new File(s).getName();
if (fileName.indexOf("/") != -1) {
fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
}
if (fileName.indexOf(".") != -1) {
fileName = fileName.substring(0, fileName.indexOf("."));
}
return fileName;
}
/**
* Take a class name and return the equivalent file name
*
* Ex. org.owasp.webgoat becomes org/owasp/webgoat.java
*
* @param className
* @return
*/
private static String getSourceFile(String className) {
StringBuffer sb = new StringBuffer();
sb.append(className.replace(".", "/"));
sb.append(".java");
return sb.toString();
}
/**
* Takes a file name and builds the class file name
*
* @param fileName Description of the Parameter
* @param path Description of the Parameter
* @return Description of the Return Value
*/
private static String getClassFile(String fileName, String path) {
String ext = ".class";
fileName = fileName.trim();
/**
* We do not handle directories. We do not handle files with different
* extensions
*/
if (fileName.endsWith("/") || !fileName.endsWith(ext)) {
return null;
}
// if the file is in /WEB-INF/classes strip the dir info off
int index = fileName.indexOf("/WEB-INF/classes/");
if (index != -1) {
fileName = fileName.substring(index + "/WEB-INF/classes/".length(), fileName.length() - ext.length());
fileName = fileName.replace('/', '.');
fileName = fileName.replace('\\', '.');
} else {
// Strip off the leading path info
fileName = fileName.substring(path.length(), fileName.length() - ext.length());
}
return fileName;
}
/**
* Gets the categories attribute of the Course object
*
* @return The categories value
*/
public List getCategories() {
List<Category> categories = new ArrayList<Category>();
Iterator iter = lessons.iterator();
while (iter.hasNext()) {
AbstractLesson lesson = (AbstractLesson) iter.next();
if (!categories.contains(lesson.getCategory())) {
categories.add(lesson.getCategory());
}
}
Collections.sort(categories);
return categories;
}
/**
* Gets the firstLesson attribute of the Course object
*
* @return The firstLesson value
*/
public AbstractLesson getFirstLesson() {
List<String> roles = new ArrayList<String>();
roles.add(AbstractLesson.USER_ROLE);
// Category 0 is the admin function. We want the first real category
// to be returned. This is noramally the General category and the Http Basics lesson
return ((AbstractLesson) getLessons((Category) getCategories().get(0), roles).get(0));
}
/**
* Gets the lesson attribute of the Course object
*
* @param lessonId Description of the Parameter
* @param role Description of the Parameter
* @return The lesson value
*/
public AbstractLesson getLesson(WebSession s, int lessonId, List<String> roles) {
if (s.isHackedAdmin()) {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
// System.out.println("getLesson() with roles: " + roles);
Iterator<AbstractLesson> iter = lessons.iterator();
while (iter.hasNext()) {
AbstractLesson lesson = iter.next();
// System.out.println("getLesson() at role: " + lesson.getRole());
if (lesson.getScreenId() == lessonId && roles.contains(lesson.getRole())) {
return lesson;
}
}
return null;
}
public AbstractLesson getLesson(WebSession s, int lessonId, String role) {
List<String> roles = new Vector<String>();
roles.add(role);
return getLesson(s, lessonId, roles);
}
public List getLessons(WebSession s, String role) {
List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, roles);
}
/**
* Gets the lessons attribute of the Course object
*
* @param role Description of the Parameter
* @return The lessons value
*/
public List<AbstractLesson> getLessons(WebSession s, List<String> roles) {
if (s.isHackedAdmin()) {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator categoryIter = getCategories().iterator();
while (categoryIter.hasNext()) {
lessonList.addAll(getLessons(s, (Category) categoryIter.next(), roles));
}
return lessonList;
}
/**
* Gets the lessons attribute of the Course object
*
* @param category Description of the Parameter
* @param role Description of the Parameter
* @return The lessons value
*/
private List<AbstractLesson> getLessons(Category category, List roles) {
List<AbstractLesson> lessonList = new ArrayList<AbstractLesson>();
Iterator iter = lessons.iterator();
while (iter.hasNext()) {
AbstractLesson lesson = (AbstractLesson) iter.next();
if (lesson.getCategory().equals(category) && roles.contains(lesson.getRole())) {
lessonList.add(lesson);
}
}
Collections.sort(lessonList);
// System.out.println(java.util.Arrays.asList(lessonList));
return lessonList;
}
public List getLessons(WebSession s, Category category, String role) {
List<String> roles = new Vector<String>();
roles.add(role);
return getLessons(s, category, roles);
}
public List<AbstractLesson> getLessons(WebSession s, Category category, List<String> roles) {
if (s.isHackedAdmin()) {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
return getLessons(category, roles);
}
/**
* Load all of the filenames into a temporary cache
*
* @param context
* @param path
*/
private void loadFiles(ServletContext context, String path) {
Set resourcePaths = context.getResourcePaths(path);
Iterator itr = resourcePaths.iterator();
while (itr.hasNext()) {
String file = (String) itr.next();
if (file.length() != 1 && file.endsWith("/")) {
loadFiles(context, file);
} else {
files.add(file);
}
}
}
/**
* Instantiate all the lesson objects into a cache
*
* @param path
*/
private void loadLessons(String path) {
Iterator itr = files.iterator();
while (itr.hasNext()) {
String file = (String) itr.next();
String className = getClassFile(file, path);
if (className != null && !className.endsWith("_i")) {
try {
Class c = Class.forName(className);
Object o = c.newInstance();
if (o instanceof AbstractLesson) {
AbstractLesson lesson = (AbstractLesson) o;
lesson.setWebgoatContext(webgoatContext);
lesson.update(properties);
if (lesson.getHidden() == false) {
lessons.add(lesson);
}
}
} catch (Exception e) {
// System.out.println("Warning: " + e.getMessage());
}
}
}
}
private String getLanguageFromFileName(String first, String absoluteFile) {
int p1 = absoluteFile.indexOf("/", absoluteFile.indexOf(first) + 1);
int p2 = absoluteFile.indexOf("/", p1 + 1);
String langStr = absoluteFile.substring(p1 + 1, p2);
return new String(langStr);
}
/**
* For each lesson, set the source file and lesson file
*/
private void loadResources() {
Iterator lessonItr = lessons.iterator();
while (lessonItr.hasNext()) {
AbstractLesson lesson = (AbstractLesson) lessonItr.next();
String className = lesson.getClass().getName();
String classFile = getSourceFile(className);
Iterator fileItr = files.iterator();
while (fileItr.hasNext()) {
String absoluteFile = (String) fileItr.next();
String fileName = getFileName(absoluteFile);
// System.out.println("Course: looking at file: " + absoluteFile);
if (absoluteFile.endsWith(classFile)) {
// System.out.println("Set source file for " + classFile);
lesson.setSourceFileName(absoluteFile);
}
if (absoluteFile.startsWith("/lesson_plans") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName)) {
// System.out.println("DEBUG: setting lesson plan file " + absoluteFile + " for
// lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
String language = getLanguageFromFileName("/lesson_plans", absoluteFile);
lesson.setLessonPlanFileName(language, absoluteFile);
this.webgoatContext.getWebgoatI18N().loadLanguage(language);
}
if (absoluteFile.startsWith("/lesson_solutions") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName)) {
// System.out.println("DEBUG: setting lesson solution file " + absoluteFile + "
// for lesson " +
// lesson.getClass().getName());
// System.out.println("fileName: " + fileName + " == className: " + className );
lesson.setLessonSolutionFileName(absoluteFile);
}
}
}
}
/**
* Description of the Method
*
* @param path Description of the Parameter
* @param context Description of the Parameter
*/
public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path) {
this.webgoatContext = webgoatContext;
loadFiles(context, path);
loadLessons(path);
loadResources();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,248 +1,231 @@
package org.owasp.webgoat.session;
import java.util.Iterator;
import javax.servlet.http.HttpServlet;
import org.owasp.webgoat.util.WebGoatI18N;
public class WebgoatContext
{
public final static String DATABASE_CONNECTION_STRING = "DatabaseConnectionString";
public final static String DATABASE_DRIVER = "DatabaseDriver";
public final static String DATABASE_USER = "DatabaseUser";
public final static String DATABASE_PASSWORD = "DatabasePassword";
public final static String ENTERPRISE = "Enterprise";
public final static String CODING_EXERCISES = "CodingExercises";
public final static String SHOWCOOKIES = "ShowCookies";
public final static String SHOWPARAMS = "ShowParams";
public final static String SHOWREQUEST = "ShowRequest";
public final static String SHOWSOURCE = "ShowSource";
public final static String SHOWSOLUTION = "ShowSolution";
public final static String SHOWHINTS = "ShowHints";
public final static String DEFUSEOSCOMMANDS = "DefuseOSCommands";
public final static String FEEDBACK_ADDRESS_HTML = "FeedbackAddressHTML";
public final static String FEEDBACK_ADDRESS = "email";
public final static String DEBUG = "debug";
public final static String DEFAULTLANGUAGE = "DefaultLanguage";
private String databaseConnectionString;
private String realConnectionString = null;
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 defuseOSCommands = false;
private boolean enterprise = false;
private boolean codingExercises = false;
private String feedbackAddress = "webgoat@owasp.org";
private String feedbackAddressHTML = "<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>";
private boolean isDebug = false;
private String servletName;
private HttpServlet servlet;
private String defaultLanguage;
private WebGoatI18N webgoati18n = null;
public WebgoatContext(HttpServlet servlet)
{
this.servlet = servlet;
databaseConnectionString = getParameter(servlet, DATABASE_CONNECTION_STRING);
databaseDriver = getParameter(servlet, DATABASE_DRIVER);
databaseUser = getParameter(servlet, DATABASE_USER);
databasePassword = getParameter(servlet, DATABASE_PASSWORD);
// initialize from web.xml
showParams = "true".equals(getParameter(servlet, SHOWPARAMS));
showCookies = "true".equals(getParameter(servlet, SHOWCOOKIES));
showSource = "true".equals(getParameter(servlet, SHOWSOURCE));
showSolution = "true".equals(getParameter(servlet, SHOWSOLUTION));
defuseOSCommands = "true".equals(getParameter(servlet, DEFUSEOSCOMMANDS));
enterprise = "true".equals(getParameter(servlet, ENTERPRISE));
codingExercises = "true".equals(getParameter(servlet, CODING_EXERCISES));
feedbackAddressHTML = getParameter(servlet, FEEDBACK_ADDRESS_HTML) != null ? getParameter(servlet,
FEEDBACK_ADDRESS_HTML)
: feedbackAddressHTML;
feedbackAddress = getParameter(servlet, FEEDBACK_ADDRESS) != null ? getParameter(servlet, FEEDBACK_ADDRESS)
: feedbackAddress;
showRequest = "true".equals(getParameter(servlet, SHOWREQUEST));
isDebug = "true".equals(getParameter(servlet, DEBUG));
servletName = servlet.getServletName();
defaultLanguage = getParameter(servlet,DEFAULTLANGUAGE)!=null ? new String(getParameter(servlet, DEFAULTLANGUAGE)): new String("English");
webgoati18n = new WebGoatI18N(this);
}
private String getParameter(HttpServlet servlet, String key)
{
String value = System.getenv().get(key);
if (value == null) value = servlet.getInitParameter(key);
return value;
}
/**
* returns the connection string with the real path to the database directory inserted at the
* word PATH
*
* @return The databaseConnectionString value
*/
public String getDatabaseConnectionString()
{
if (realConnectionString == null) try
{
String path = servlet.getServletContext().getRealPath("/database").replace('\\', '/');
System.out.println("PATH: " + path);
realConnectionString = databaseConnectionString.replaceAll("PATH", path);
System.out.println("Database Connection String: " + realConnectionString);
} catch (Exception e)
{
System.out.println("Couldn't open database: check web.xml database parameters");
e.printStackTrace();
}
return realConnectionString;
}
/**
* 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);
}
public boolean isDefuseOSCommands()
{
return defuseOSCommands;
}
public boolean isEnterprise()
{
return enterprise;
}
public boolean isCodingExercises()
{
return codingExercises;
}
public String getFeedbackAddress()
{
return feedbackAddress;
}
public String getFeedbackAddressHTML()
{
return feedbackAddressHTML;
}
public boolean isDebug()
{
return isDebug;
}
public String getServletName()
{
return servletName;
}
public boolean isShowCookies()
{
return showCookies;
}
public boolean isShowParams()
{
return showParams;
}
public boolean isShowRequest()
{
return showRequest;
}
public boolean isShowSource()
{
return showSource;
}
public boolean isShowSolution()
{
return showSolution;
}
public String getDefaultLanguage() {
return defaultLanguage;
}
public void setWebgoatiI18N(WebGoatI18N webgoati18n) {
this.webgoati18n = webgoati18n;
}
public WebGoatI18N getWebgoatI18N() {
return webgoati18n;
}
}
package org.owasp.webgoat.session;
import javax.servlet.http.HttpServlet;
import org.owasp.webgoat.util.WebGoatI18N;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class WebgoatContext {
final Logger logger = LoggerFactory.getLogger(WebgoatContext.class);
public final static String DATABASE_CONNECTION_STRING = "DatabaseConnectionString";
public final static String DATABASE_DRIVER = "DatabaseDriver";
public final static String DATABASE_USER = "DatabaseUser";
public final static String DATABASE_PASSWORD = "DatabasePassword";
public final static String ENTERPRISE = "Enterprise";
public final static String CODING_EXERCISES = "CodingExercises";
public final static String SHOWCOOKIES = "ShowCookies";
public final static String SHOWPARAMS = "ShowParams";
public final static String SHOWREQUEST = "ShowRequest";
public final static String SHOWSOURCE = "ShowSource";
public final static String SHOWSOLUTION = "ShowSolution";
public final static String SHOWHINTS = "ShowHints";
public final static String DEFUSEOSCOMMANDS = "DefuseOSCommands";
public final static String FEEDBACK_ADDRESS_HTML = "FeedbackAddressHTML";
public final static String FEEDBACK_ADDRESS = "email";
public final static String DEBUG = "debug";
public final static String DEFAULTLANGUAGE = "DefaultLanguage";
private String databaseConnectionString;
private String realConnectionString = null;
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 defuseOSCommands = false;
private boolean enterprise = false;
private boolean codingExercises = false;
private String feedbackAddress = "webgoat@owasp.org";
private String feedbackAddressHTML = "<A HREF=mailto:webgoat@owasp.org>webgoat@owasp.org</A>";
private boolean isDebug = false;
private String servletName;
private HttpServlet servlet;
private String defaultLanguage;
private WebGoatI18N webgoati18n = null;
public WebgoatContext(HttpServlet servlet) {
this.servlet = servlet;
databaseConnectionString = getParameter(servlet, DATABASE_CONNECTION_STRING);
databaseDriver = getParameter(servlet, DATABASE_DRIVER);
databaseUser = getParameter(servlet, DATABASE_USER);
databasePassword = getParameter(servlet, DATABASE_PASSWORD);
// initialize from web.xml
showParams = "true".equals(getParameter(servlet, SHOWPARAMS));
showCookies = "true".equals(getParameter(servlet, SHOWCOOKIES));
showSource = "true".equals(getParameter(servlet, SHOWSOURCE));
showSolution = "true".equals(getParameter(servlet, SHOWSOLUTION));
defuseOSCommands = "true".equals(getParameter(servlet, DEFUSEOSCOMMANDS));
enterprise = "true".equals(getParameter(servlet, ENTERPRISE));
codingExercises = "true".equals(getParameter(servlet, CODING_EXERCISES));
feedbackAddressHTML = getParameter(servlet, FEEDBACK_ADDRESS_HTML) != null ? getParameter(servlet,
FEEDBACK_ADDRESS_HTML)
: feedbackAddressHTML;
feedbackAddress = getParameter(servlet, FEEDBACK_ADDRESS) != null ? getParameter(servlet, FEEDBACK_ADDRESS)
: feedbackAddress;
showRequest = "true".equals(getParameter(servlet, SHOWREQUEST));
isDebug = "true".equals(getParameter(servlet, DEBUG));
servletName = servlet.getServletName();
defaultLanguage = getParameter(servlet, DEFAULTLANGUAGE) != null ? new String(getParameter(servlet, DEFAULTLANGUAGE)) : new String("English");
webgoati18n = new WebGoatI18N(this);
}
private String getParameter(HttpServlet servlet, String key) {
String value = System.getenv().get(key);
if (value == null) {
value = servlet.getInitParameter(key);
}
return value;
}
/**
* returns the connection string with the real path to the database
* directory inserted at the word PATH
*
* @return The databaseConnectionString value
*/
public String getDatabaseConnectionString() {
if (realConnectionString == null) {
try {
String path = servlet.getServletContext().getRealPath("/database").replace('\\', '/');
System.out.println("PATH: " + path);
realConnectionString = databaseConnectionString.replaceAll("PATH", path);
System.out.println("Database Connection String: " + realConnectionString);
} catch (Exception e) {
logger.error("Couldn't open database: check web.xml database parameters", e);
}
}
return realConnectionString;
}
/**
* 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);
}
public boolean isDefuseOSCommands() {
return defuseOSCommands;
}
public boolean isEnterprise() {
return enterprise;
}
public boolean isCodingExercises() {
return codingExercises;
}
public String getFeedbackAddress() {
return feedbackAddress;
}
public String getFeedbackAddressHTML() {
return feedbackAddressHTML;
}
public boolean isDebug() {
return isDebug;
}
public String getServletName() {
return servletName;
}
public boolean isShowCookies() {
return showCookies;
}
public boolean isShowParams() {
return showParams;
}
public boolean isShowRequest() {
return showRequest;
}
public boolean isShowSource() {
return showSource;
}
public boolean isShowSolution() {
return showSolution;
}
public String getDefaultLanguage() {
return defaultLanguage;
}
public void setWebgoatiI18N(WebGoatI18N webgoati18n) {
this.webgoati18n = webgoati18n;
}
public WebGoatI18N getWebgoatI18N() {
return webgoati18n;
}
}

View File

@ -1,4 +1,4 @@
log4j.rootLogger=INFO, MAIN_LOG, ERROR_LOG
log4j.rootLogger=DEBUG, MAIN_LOG, ERROR_LOG
# MAIN - everything gets logged here
log4j.appender.MAIN_LOG=org.apache.log4j.RollingFileAppender
@ -9,6 +9,9 @@ log4j.appender.MAIN_LOG.MaxFileSize=10MB
log4j.appender.MAIN_LOG.MaxBackupIndex=5
log4j.appender.MAIN_LOG.append=true
# a little less spring output
log4j.category.org.springframework = INFO
# ERROR
log4j.appender.ERROR_LOG=org.apache.log4j.RollingFileAppender
log4j.appender.ERROR_LOG.File=${catalina.home}/logs/webgoat_error.log