Merge branch 'next' of https://github.com/WebGoat/WebGoat into next

Conflicts:
	.gitignore
This commit is contained in:
diver-sity 2014-09-10 21:25:45 +10:00
commit 1cfbe2b843
313 changed files with 568 additions and 223 deletions

15
.gitignore vendored
View File

@ -1,5 +1,18 @@
/nb-configuration.xml /nb-configuration.xml
/nbactions.xml /nbactions.xml
/target/
/.classpath
/.project
/.settings/.jsdtscope
/.settings/org.eclipse.jdt.core.prefs
/.settings/org.eclipse.m2e.core.prefs
/.settings/org.eclipse.wst.common.component
/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml
/.settings/org.eclipse.wst.common.project.facet.core.xml
/.settings/org.eclipse.wst.jsdt.ui.superType.container
/.settings/org.eclipse.wst.jsdt.ui.superType.name
/.settings/org.eclipse.wst.validation.prefs
/.externalToolBuilders/
.project .project
/target /target
.classpath .classpath
@ -11,5 +24,3 @@ src/main/main.iml
*.LOCAL.*.jsp *.LOCAL.*.jsp
*.REMOTE.*.jsp *.REMOTE.*.jsp

View File

@ -135,7 +135,7 @@ public class HammerHead extends HttpServlet {
return; return;
} }
if ("true".equals(request.getParameter("start"))) { if ("true".equals(request.getParameter("start")) || request.getQueryString() == null) {
logger.warn("Redirecting to start controller"); logger.warn("Redirecting to start controller");
response.sendRedirect("start.mvc"); response.sendRedirect("start.mvc");
return; return;

View File

@ -0,0 +1,49 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.owasp.webgoat.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
/**
*
* @author rlawson
*/
@Controller
public class About {
final Logger logger = LoggerFactory.getLogger(About.class);
private static final String WELCOMED = "welcomed";
@RequestMapping(value = "about.mvc", method = RequestMethod.GET)
public ModelAndView welcome(HttpServletRequest request,
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
// set the welcome attribute
// this is so the attack servlet does not also
// send them to the welcome page
HttpSession session = request.getSession();
if (session.getAttribute(WELCOMED) == null) {
session.setAttribute(WELCOMED, "true");
}
//go ahead and send them to webgoat (skip the welcome page)
ModelAndView model = new ModelAndView();
//model.setViewName("welcome");
//model.setViewName("main_new");
model.setViewName("about");
return model;
}
}

View File

@ -19,7 +19,9 @@ import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
import org.apache.ecs.html.Body; import org.apache.ecs.html.Body;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.Form; import org.apache.ecs.html.Form;
import org.apache.ecs.html.H1;
import org.apache.ecs.html.Head; import org.apache.ecs.html.Head;
import org.apache.ecs.html.Html; import org.apache.ecs.html.Html;
import org.apache.ecs.html.IMG; import org.apache.ecs.html.IMG;
@ -729,11 +731,8 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*/ */
public void handleRequest(WebSession s) { public void handleRequest(WebSession s) {
// call createContent first so messages will go somewhere // call createContent first so messages will go somewhere
Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType(""); Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
form.addElement(createContent(s)); form.addElement(createContent(s));
setContent(form); setContent(form);
} }

View File

@ -103,7 +103,7 @@ public class CrossSiteScripting extends GoatHillsFinancial
{ {
String solutionFileName = null; String solutionFileName = null;
String stage = getStage(s); String stage = getStage(s);
solutionFileName = "/lesson_solutions/Lab XSS/Lab " + stage + ".html"; solutionFileName = "/lesson_solutions_1/Lab XSS/Lab " + stage + ".html";
return solutionFileName; return solutionFileName;
} }

View File

@ -2,9 +2,11 @@ package org.owasp.webgoat.lessons;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.ecs.Element; import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer; import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement; import org.apache.ecs.StringElement;
import org.apache.ecs.html.BR;
import org.apache.ecs.html.Input; import org.apache.ecs.html.Input;
import org.owasp.webgoat.session.ECSFactory; import org.owasp.webgoat.session.ECSFactory;
import org.owasp.webgoat.session.WebSession; import org.owasp.webgoat.session.WebSession;
@ -58,6 +60,7 @@ public class HttpBasics extends LessonAdapter {
StringBuffer person = null; StringBuffer person = null;
try { try {
ec.addElement(new BR());
ec.addElement(new StringElement(WebGoatI18N.get("EnterYourName") + ": ")); ec.addElement(new StringElement(WebGoatI18N.get("EnterYourName") + ": "));
person = new StringBuffer(s.getParser().getStringParameter(PERSON, "")); person = new StringBuffer(s.getParser().getStringParameter(PERSON, ""));

View File

@ -1,7 +1,6 @@
package org.owasp.webgoat.lessons; package org.owasp.webgoat.lessons;
import java.io.PrintWriter;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -54,7 +53,8 @@ public class HttpSplitting extends SequentialLessonAdapter
private static String STAGE = "stage"; private static String STAGE = "stage";
public final static A MAC_LOGO = new A().setHref("http://www.softwaresecured.com").addElement(new IMG("images/logos/softwaresecured.gif").setAlt("Software Secured").setBorder(0).setHspace(0).setVspace(0)); public final static A MAC_LOGO = new A().setHref("http://www.softwaresecured.com").addElement(new IMG("images/logos/softwaresecured.gif").setAlt("Software Secured").setBorder(0).setHspace(0).setVspace(0));
/**
/**
* Description of the Method * Description of the Method
* *
* @param s * @param s

View File

@ -176,7 +176,7 @@ public class RoleBasedAccessControl extends GoatHillsFinancial
{ {
String solutionFileName = null; String solutionFileName = null;
String stage = getStage(s); String stage = getStage(s);
solutionFileName = "/lesson_solutions/Lab Access Control/Lab " + stage + ".html"; solutionFileName = "/lesson_solutions_1/Lab Access Control/Lab " + stage + ".html";
return solutionFileName; return solutionFileName;
} }

View File

@ -272,7 +272,7 @@ public class SQLInjection extends GoatHillsFinancial
{ {
String solutionFileName = null; String solutionFileName = null;
String stage = getStage(s); String stage = getStage(s);
solutionFileName = "/lesson_solutions/Lab SQL Injection/Lab " + stage + ".html"; solutionFileName = "/lesson_solutions_1/Lab SQL Injection/Lab " + stage + ".html";
return solutionFileName; return solutionFileName;
} }
} }

View File

@ -0,0 +1,40 @@
package org.owasp.webgoat.service;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LessonTitleService extends BaseService {
/**
* Returns the title for the current attack
*
* @param session
* @return
*/
@RequestMapping(value = "/lessontitle.mvc", produces = "application/html")
public @ResponseBody
String showPlan(HttpSession session) {
WebSession ws = getWebSession(session);
return getLessonTitle(ws);
}
private String getLessonTitle(WebSession s) {
String title = "";
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
title = lesson != null ? lesson.getTitle() : "";
}
return title;
}
}

View File

@ -0,0 +1,124 @@
<%@ page contentType="text/html; charset=ISO-8859-1" language="java"
errorPage=""%>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="plugins/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" href="css/webgoat.css" type="text/css" />
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
<h1 class="modal-title" id="myModalLabel">About WebGoat</h1>
</div>
<div class="modal-body">
<p>Thank you for using WebGoat! This program is a demonstration of common web application flaws.
The exercises are intended to provide hands on experience with
application penetration testing techniques. </p>
<p>The WebGoat project is led
by Bruce Mayhew. Please send all comments to Bruce at [TODO, session was blowing up here for some reason].</p>
<div id="team">
<table border="0" align="center" class="lessonText">
<tr>
<td width="50%">
<div align="center"><a href="http://www.owasp.org"><img
border="0" src="images/logos/owasp.jpg" alt="OWASP Foundation"
longdesc="http://www.owasp.org" /></a></div>
</td>
<td width="50%">
<div align="center"><a href="http://www.aspectsecurity.com"><img
border="0" src="images/logos/aspect.jpg" alt="Aspect Security"
longdesc="http://www.aspectsecurity.com" /></a></div>
</td>
</tr>
<tr>
<td colspan="2">
<div align="center"><span class="style1">
WebGoat Authors </span></div>
</td>
</tr>
<tr>
<td colspan="2">
<div align="center"><span class="style2">
Bruce Mayhew </span></div>
</td>
</tr>
<tr>
<td colspan="2">
<div align="center"><span class="style2">
Jeff Williams </span></div>
</td>
</tr>
<tr>
<td width="50%">
<div align="center"><span class="style1"><br />
WebGoat Design Team </span></div>
</td>
<td width="50%">
<div align="center"><span class="style1"><br />
V5.4 Lesson Contributers </span></div>
</td>
</tr>
<tr>
<td valign="top">
<div align="center" class="style2">David Anderson</div>
<div align="center" class="style2">Laurence Casey (Graphics)</div>
<div align="center" class="style2">Rogan Dawes</div>
<div align="center" class="style2">Bruce Mayhew</div>
</td>
<td valign="top">
<div align="center" class="style2">Sherif Koussa</div>
<div align="center" class="style2">Yiannis Pavlosoglou</div>
<div align="center" class="style2"></div>
</td>
</tr>
<tr>
<td height="25" valign="bottom">
<div align="center"><span class="style1">Special Thanks
for V5.4</span></div>
</td>
<td height="25" valign="bottom">
<div align="center"><span class="style1">Documentation
Contributers</span></div>
</td>
</tr>
<tr>
<td>
<div align="center" class="style2">Brian Ciomei (Multitude of bug fixes)</div>
<div align="center" class="style2">To all who have sent comments</div>
</td>
<td>
<div align="center" class="style2">
<a href="http://www.zionsecurity.com/" target="_blank">Erwin Geirnaert</a></div>
<div align="center" class="style2">
<a href="http://yehg.org/" target="_blank">Aung Khant</a></div>
<div align="center" class="style2">
<a href="http://www.softwaresecured.com" target="blank">Sherif Koussa</a>
</div>
</td>
</tr>
<tr>
<td>
<div align="center" class="style2">&nbsp;</div>
</td>
</tr>
</table>
</div>
<div align="center" class="style2">&nbsp;</div>
<div align="center" class="style2">&nbsp;</div>
<div align="center" class="style2">&nbsp;</div>
<div id="warning">WARNING<br />
While running this program, your machine is extremely vulnerable to
attack if you are not running on localhost. If you are NOT running on localhost (default configuration), You should disconnect from the network while using this program.
<br />
<br />
This program is for educational purposes only. Use of these techniques
without permission could lead to job termination, financial liability,
and/or criminal penalties.</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>

View File

@ -1,6 +1,7 @@
<%@ page contentType="text/html; charset=ISO-8859-1" language="java" <%@ page contentType="text/html; charset=ISO-8859-1" language="java"
errorPage=""%> errorPage=""%>
<%@page import="org.owasp.webgoat.session.WebSession"%> <%@page import="org.owasp.webgoat.session.WebSession"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<% <%
WebSession webSession = ((WebSession) session.getAttribute(WebSession.SESSION)); WebSession webSession = ((WebSession) session.getAttribute(WebSession.SESSION));
%> %>
@ -60,7 +61,7 @@
</head> </head>
<body class="animated fadeIn" ng-app="goatApp"> <body class="animated fadeIn" ng-app="goatApp">
<section id="container"> <section id="container" ng-controller="goatLesson">
<header id="header"> <header id="header">
<!--logo start--> <!--logo start-->
<div class="brand"> <div class="brand">
@ -72,25 +73,37 @@
<i class="fa fa-bars"></i> <i class="fa fa-bars"></i>
</button> </button>
</div><!--toggle navigation end--> </div><!--toggle navigation end-->
<div class="lessonTitle"> <div class="lessonTitle" >
<h1>Lesson Title in here</h1> <h1 id="lessonTitle">Lesson Title in here</h1>
</div><!--lesson title end--> </div><!--lesson title end-->
<div class="user-nav pull-right"> <div class="user-nav pull-right" style="margin-right: 50px;">
<button type="button" class="btn btn-default"> <div class="dropdown" style="display:inline">
<button type="button" class="btn btn-default dropdown-toggle" id="dropdownMenu1" data-toggle="dropdown">
<i class="fa fa-user"></i> <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-menu-left" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">User: TODO</a></li>
<li role="presentation" class="disabled"><a role="menuitem" tabindex="-1" href="#">Role: TODO</a></li>
<li role="presentation" class="divider"></li>
<li role="presentation"><a role="menuitem" tabindex="-1" href="<c:url value="j_spring_security_logout" />">Logout</a></li>
</ul>
</div>
<button type="button" class="btn btn-default right_nav_button" ng-click="showAbout()" data-toggle="tooltip" title="About WebGoat">
<i class="fa fa-info"></i> <i class="fa fa-info"></i>
</button> </button>
<button type="button" class="btn btn-default"> <a href="mailto:someone@example.com?Subject=Hello%20again" target="_top">
<i class="fa fa-envelope"></i> <button type="button" class="btn btn-default right_nav_button"data-toggle="tooltip" title="Contact Us">
</button> <i class="fa fa-envelope"></i>
<button type="button" class="btn btn-default"> </button>
<i class="fa fa-user"></i> </a>
</button>
</div> </div>
</header> </header>
<!--sidebar left start--> <!--sidebar left start-->
<aside class="sidebar"> <aside class="sidebar">
<div id="leftside-navigation" class="nano" ng-controller="goatLessonMenu"> <div id="leftside-navigation" class="nano">
<ul class="nano-content"> <ul class="nano-content">
<li class="sub-menu" ng-repeat="item in menuTopics"> <li class="sub-menu" ng-repeat="item in menuTopics">
<a ng-click="expanded = !expanded" href=""><i class="fa {{item.class}}"></i><span>{{item.name}}</span></a> <a ng-click="expanded = !expanded" href=""><i class="fa {{item.class}}"></i><span>{{item.name}}</span></a>
@ -112,42 +125,21 @@
<!--main content start--> <!--main content start-->
<section class="main-content-wrapper"> <section class="main-content-wrapper">
<section id="main-content" ng-controller="lessonHelpController"> <section id="main-content" > <!-- ng-controller="lessonController" -->
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<div class="col-md-12" align="left"> <div class="col-md-12" align="left">
<div class="panel"> <div class="panel">
<div class="panel-body"> <div class="panel-body">
<button type="button" id="showSourceBtn" class="btn btn-primary">Java [Source]</button> <button type="button" id="showSourceBtn" class="btn btn-primary btn-xs" ng-click="showLessonSource()">Java [Source]</button>
<button type="button" id="showSolutionBtn" class="btn btn-primary">Solution</button> <button type="button" id="showSolutionBtn" class="btn btn-primary btn-xs" ng-click="showLessonSolution()">Solution</button>
<button type="button" id="showPlanBtn" class="btn btn-primary btn-xs" ng-click="showLessonPlan()">Lesson Plan</button>
<button type="button" id="showHintsBtn" class="btn btn-primary btn-xs" ng-click="viewHints()">Hints</button>
</div> </div>
</div> </div>
</div>
<div class="col-md-12">
<div class="panel" id="buttonPanel">
<button type="button" id="showParamsCookiesBtn" class="btn btn-primary btn-xs" ng-click="viewCookiesAndParams()">Params/Cookies</button>
<button type="button" id="showHintsBtn" class="btn btn-primary btn-xs lessonHelpBtn">Hints</button>
<button type="button" id="showPlanBtn" class="btn btn-primary btn-xs lessonHelpBtn">Lesson Plan</button>
<button type="button" id="showSourceBtn" class="btn btn-primary btn-xs lessonHelpBtn">Java [Source]</button> <!-- ng-click="showSource('lg') -->
<button type="button" id="showSolutionBtn" class="btn btn-primary btn-xs lessonHelpBtn">Solution</button> <!-- ng-click="showSolution('lg') -->
</div>
<div class="panel" id="cookiesAndParams"> </div>
<div class="cookiesView"> <div class="col-md-12">
cookies:
<ul ng-repeat="cookie in cookies">
<li ng-repeat="(key, value) in cookie">{{key}} :: {{ value}} </td>
</ul>
</div>
<div> <!--class="paramsView"-->
params:<br/>
<ul>
<li ng-repeat="param in params">
{{param.name}} = {{param.value}}
</li>
</ul>
</div>
</div>
<div class="panel" > <div class="panel" >
<div class="panel-body" id="lesson_content"> <div class="panel-body" id="lesson_content">
<b>This should default to the "How to Work with Webgoat" lesson</b> <b>This should default to the "How to Work with Webgoat" lesson</b>
@ -161,19 +153,61 @@
<div class="panel"> <div class="panel">
<div class="panel-body"> <div class="panel-body">
<div align="left"> <div align="left">
<button id="showParamsCookiesBtn" type="button" class="btn btn-default">Params / Cookies</button> <h3>Cookies / Parameters</h3>
<button id="showHintsBtn" type="button" class="btn btn-default">Hints</button>
<button id="showPlanBtn" type="button" class="btn btn-default">Lesson Plan</button>
</div> </div>
<hr /> <hr />
<h3>Hints</h3> <div id="cookiesAndParamsView">
<p>Nam placerat magna in massa euismod fringilla. Pellentesque in cursus risus, eu hendrerit ligula. Quisque ultrices eget tortor ut eleifend. Praesent auctor libero nec quam fringilla faucibus. Curabitur cursus risus eu faucibus rutrum. Morbi dapibus nulla risus, et euismod eros posuere volutpat. Quisque ut diam diam. Quisque sed enim tortor. Suspendisse commodo magna nec felis ultricies laoreet. Donec sit amet vehicula eros. Phasellus at dapibus enim. Sed massa quam, aliquet eu mattis at, porttitor a nisi.</p> <div class="cookiesView">
<h4>Cookies</h4>
<table class="cookieTable table-striped table-nonfluid" ng-repeat="cookie in cookies">
<thead>
<tr><th>Field</th><th>Value</th></tr>
</thead>
<tbody>
<tr ng-repeat="(key, value) in cookie">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</tbody>
<!--<li ng-repeat="(key, value) in cookie">{{key}} :: {{ value}} </td>-->
<!--</ul>-->
</table>
</div>
<div id="paramsView"> <!--class="paramsView"-->
<h4>Params</h4>
<table class="paramsTable table-striped table-nonfluid" id="paramsTable">
<thead>
<tr><th>Param</th><th>Value</th></tr>
</thead>
<tbody>
<tr ng-repeat="param in parameters">
<td>{{param.name}}</td>
<td>{{param.value}}</td>
</tr>
</tbody>
</table>
</ul>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div><!--col-md-4 end--> </div><!--col-md-4 end-->
</div> </div>
<div id="lessonHelpsWrapper"> <div id="lessonHelpsWrapper">
<div class="row lessonHelp" id="lesson_hint_row">
<div class="col-md-12">
<h4>Hints</h4>
<div class="panel" >
<div class="panel-body" id="lesson_hint">
<span class="glyphicon-class glyphicon glyphicon-circle-arrow-left" id="showPrevHintBtn" ng-click="viewPrevHint()"></span>
<span class="glyphicon-class glyphicon glyphicon-circle-arrow-right" id="showNextHintBtn" ng-click="viewNextHint()"></span>
<br/>
{{curHint}}
</div>
</div>
</div>
</div>
<div class="row lessonHelp" id="lesson_cookies_row"> <div class="row lessonHelp" id="lesson_cookies_row">
<div class="col-md-12"> <div class="col-md-12">
<h4>Lesson Parameters and Cookies</h4> <h4>Lesson Parameters and Cookies</h4>
@ -199,7 +233,7 @@
<h4>Lesson Plan</h4> <h4>Lesson Plan</h4>
<div class="panel" > <div class="panel" >
<div class="panel-body" id="lesson_plan"> <div class="panel-body" id="lesson_plan">
<!-- allowing jQuery to handle this one -->
</div> </div>
</div> </div>
</div> </div>
@ -207,7 +241,7 @@
<div class="row lessonHelp" id="lesson_solution_row"> <div class="row lessonHelp" id="lesson_solution_row">
<div class="col-md-12"> <div class="col-md-12">
<h4>Lesson Solution</h4> <h4>Lesson Solution</h4>
<div class="panel" > <div class="panel">
<div class="panel-body" id="lesson_solution"> <div class="panel-body" id="lesson_solution">
</div> </div>
</div> </div>
@ -216,8 +250,9 @@
<div class="row lessonHelp" id="lesson_source_row"> <div class="row lessonHelp" id="lesson_source_row">
<div class="col-md-12"> <div class="col-md-12">
<h4>Lesson Source Code</h4> <h4>Lesson Source Code</h4>
<div class="panel" > <div class="panel">
<div class="panel-body" id="lesson_source"> <div class="panel-body" id="lesson_source">
<pre>{{source}}</pre>
</div> </div>
</div> </div>
</div> </div>
@ -237,83 +272,83 @@
<!-- TODO pull source into project instead of loading from external --> <!-- TODO pull source into project instead of loading from external -->
<script src="http://malsup.github.com/jquery.form.js"></script> <script src="http://malsup.github.com/jquery.form.js"></script>
<script> <script>
//Load global functions //Load global functions
// set this to true if you want to see form submissions // set this to true if you want to see form submissions
// set to false once we get all the kinks worked out // set to false once we get all the kinks worked out
var DEBUG_FORM_SUBMISSION = false; var DEBUG_FORM_SUBMISSION = false;
$(document).ready(function() { $(document).ready(function() {
// bind to click events on menu links app.init();
/*$('.menu-link').bind('click', function(event) { //can be augmented later to 'resume' for a given user ... currently kluged to start at fixed lesson
event.preventDefault(); var url = 'attack?Screen=32&menu=5';
$.get(this.href, {}, function(reply) { angular.element($('#leftside-navigation')).scope().renderLesson(url);
$("#lesson_content").html(reply); });
goat.utils.showLessonSource(); // make all forms ajax forms
}, "html"); var options = {
});*/ target: '#lesson_content', // target element(s) to be updated with server response
beforeSubmit: showRequest, // pre-submit callback, comment out after debugging
success: showResponse // post-submit callback, comment out after debugging
app.init(); // other available options:
//url: url // override for form's 'action' attribute
//type: type // 'get' or 'post', override for form's 'method' attribute
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
//clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
}); // $.ajax options can be used here too, for example:
// make all forms ajax forms //timeout: 3000
var options = { };
target: '#lesson_content', // target element(s) to be updated with server response // pre-submit callback
beforeSubmit: showRequest, // pre-submit callback, comment out after debugging function showRequest(formData, jqForm, options) {
success: showResponse // post-submit callback, comment out after debugging if (DEBUG_FORM_SUBMISSION) {
// formData is an array; here we use $.param to convert it to a string to display it
// but the form plugin does this for you automatically when it submits the data
var queryString = $.param(formData);
// other available options: // jqForm is a jQuery object encapsulating the form element. To access the
//url: url // override for form's 'action' attribute // DOM element for the form do this:
//type: type // 'get' or 'post', override for form's 'method' attribute // var formElement = jqForm[0];
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
//clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
// $.ajax options can be used here too, for example: alert('About to submit: \n\n' + queryString);
//timeout: 3000 }
};
// pre-submit callback
function showRequest(formData, jqForm, options) {
if (DEBUG_FORM_SUBMISSION) {
// formData is an array; here we use $.param to convert it to a string to display it
// but the form plugin does this for you automatically when it submits the data
var queryString = $.param(formData);
// jqForm is a jQuery object encapsulating the form element. To access the // here we could return false to prevent the form from being submitted;
// DOM element for the form do this: // returning anything other than false will allow the form submit to continue
// var formElement = jqForm[0]; return true;
}
alert('About to submit: \n\n' + queryString); // post-submit callback
} function showResponse(responseText, statusText, xhr, $form) {
// for normal html responses, the first argument to the success callback
// is the XMLHttpRequest object's responseText property
// here we could return false to prevent the form from being submitted; // if the ajaxForm method was passed an Options Object with the dataType
// returning anything other than false will allow the form submit to continue // property set to 'xml' then the first argument to the success callback
return true; // is the XMLHttpRequest object's responseXML property
}
// post-submit callback // if the ajaxForm method was passed an Options Object with the dataType
function showResponse(responseText, statusText, xhr, $form) { // property set to 'json' then the first argument to the success callback
// for normal html responses, the first argument to the success callback // is the json data object returned by the server
// is the XMLHttpRequest object's responseText property if (DEBUG_FORM_SUBMISSION) {
alert('status: ' + statusText + '\n\nresponseText: \n' + responseText +
// if the ajaxForm method was passed an Options Object with the dataType '\n\nThe output div should have already been updated with the responseText.');
// property set to 'xml' then the first argument to the success callback }
// is the XMLHttpRequest object's responseXML property // JASON - SEE THIS HOOK
// update lesson cookies and params
// if the ajaxForm method was passed an Options Object with the dataType // make any embedded forms ajaxy
// property set to 'json' then the first argument to the success callback goat.utils.showLessonCookiesAndParams();
// is the json data object returned by the server goat.utils.makeFormsAjax();
if (DEBUG_FORM_SUBMISSION) { }
alert('status: ' + statusText + '\n\nresponseText: \n' + responseText +
'\n\nThe output div should have already been updated with the responseText.');
}
// JASON - SEE THIS HOOK
// update lesson cookies and params
// make any embedded forms ajaxy
goat.utils.showLessonCookiesAndParams();
goat.utils.makeFormsAjax();
}
</script> </script>
<!-- Modal -->
<div class="modal fade" id="aboutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
</div>
</div>
</div>
</body> </body>
</html> </html>

View File

@ -250,7 +250,7 @@ img {
} }
.main-content-wrapper #main-content { .main-content-wrapper #main-content {
background: url('img/webBg.png') no-repeat top left; /*background: url('img/webBg.png') no-repeat top left;*/
border-top: solid thin #e7e8ec; border-top: solid thin #e7e8ec;
display: inline-block; display: inline-block;
padding: 15px 15px 0 15px; padding: 15px 15px 0 15px;
@ -781,11 +781,23 @@ fieldset[disabled] .btn-warning.active {
.lessonHelp, .lessonHelpBtn { .lessonHelp, .lessonHelpBtn {
display: none; display: none;
} }
/*
.paramsView { .table-nonfluid {
float:right; width:auto;
width 50%; }
margin-right:10px;
border-left:2px solid #333; .cookieTable tr td, .paramsTable tr td {
padding: 3px;
max-width: 200px;
font-size: x-small;
}
/* HINTS */
#hintsViewTop{
display: none;
background-color: #eee;
}
.info {
color:#e84c3d;
font-weight: bold;
} }
*/

View File

@ -19,8 +19,11 @@ var goatConstants = {
solutionService:'service/solution.mvc', solutionService:'service/solution.mvc',
lessonPlanService:'service/lessonplan.mvc', lessonPlanService:'service/lessonplan.mvc',
menuService: 'service/lessonmenu.mvc', menuService: 'service/lessonmenu.mvc',
lessonTitleService: 'service/lessontitle.mvc',
// literals // literals
notFound: 'Could not find' notFound: 'Could not find',
noHints: 'There are no hints defined.'
}; };

View File

@ -3,10 +3,12 @@
/* ### GOAT CONTROLLERS ### */ /* ### GOAT CONTROLLERS ### */
/** Menu Controller /** Lesson Controller (includes menu stuff)
* prepares and updates menu topic items for the view * prepares and updates menu topic items for the view
*/ */
goat.controller('goatLessonMenu', function($scope, $http, $modal, $log, $templateCache) { goat.controller('goatLesson', function($scope, $http, $modal, $log, $templateCache) {
$scope.cookies = [];
$scope.params = [];
//TODO: implement via separate promise and use config for menu (goat.data.loadMenuData()) //TODO: implement via separate promise and use config for menu (goat.data.loadMenuData())
$http({method: 'GET', url: goatConstants.lessonService}).then( $http({method: 'GET', url: goatConstants.lessonService}).then(
function(menuData) { function(menuData) {
@ -18,85 +20,156 @@ goat.controller('goatLessonMenu', function($scope, $http, $modal, $log, $templat
console.error("Error rendering menu: " + error); console.error("Error rendering menu: " + error);
} }
); );
$scope.renderLesson = function(url) { $scope.renderLesson = function(url) {
//console.log(url + ' was passed in'); //console.log(url + ' was passed in');
// use jquery to render lesson content to div // use jquery to render lesson content to div
$scope.hintIndex = 0;
var curScope = $scope;
curScope.parameters = goat.utils.scrapeParams(url);
goat.data.loadLessonContent(url).then( goat.data.loadLessonContent(url).then(
function(reply) { function(reply) {
$("#lesson_content").html(reply); $("#lesson_content").html(reply);
// hook forms goat.data.loadLessonTitle().then(
function(reply) {
$("#lessonTitle").text(reply);
}
);
//hook forms
goat.utils.makeFormsAjax(); goat.utils.makeFormsAjax();
//render lesson title $('#hintsView').hide();
$('#lessonTitle').text(goat.utils.extractLessonTitle($(reply)));
// adjust menu to lessonContent size if necssary // adjust menu to lessonContent size if necssary
//@TODO: this is still clunky ... needs some TLC //@TODO: this is still clunky ... needs some TLC
if ($('div.panel-body').height() > 400) { if ($('div.panel-body').height() > 400) {
$('#leftside-navigation').height($(window).height()); $('#leftside-navigation').height($(window).height());
} }
goat.lesson.lessonInfo = new goat.lesson.CurLesson(url); //cookies
goat.lesson.lessonInfo.loadInfo(); //uses pseudo and actual service calls goat.data.loadCookies().then(
// @TODO: convert to real services (and more angularjs, likely ... in phase 2) function(resp) {
curScope.cookies = resp;
}
);
//hints
curScope.hintIndex = 0;
goat.data.loadHints().then(
function(resp) {
curScope.hints = resp;
if (curScope.hints.length > 0 && curScope.hints[0].hint.indexOf(goatConstants.noHints) === -1) {
goat.utils.displayButton('showHintsBtn', true);
} else {
goat.utils.displayButton('showHintsBtn', false);
}
}
);
//source
goat.data.loadSource().then(
function(resp) {
curScope.source = resp;
}
);
//plan
goat.data.loadPlan().then(
function(resp) {
curScope.plan = resp;
}
);
//solution
goat.data.loadSolution().then(
function(resp) {
curScope.solution = resp;
}
);
goat.utils.scrollToTop();
} }
); );
};
}).animation('.slideDown', function() {
var NgHideClassName = 'ng-hide';
return {
beforeAddClass: function(element, className, done) {
if (className === NgHideClassName) {
$(element).slideUp(done);
}
},
removeClass: function(element, className, done) {
if (className === NgHideClassName) {
$(element).hide().slideDown(done);
}
}
};
});
goat.controller('lessonHelpController', function($scope) {
$scope.cookies=[];
$scope.params=[];
$scope.viewCookiesAndParams = function() {
$scope.cookies=goat.lesson.lessonInfo.cookies;
console.log($scope.cookies);
$scope.params=goat.lesson.lessonInfo.params;
//@TODO: issue callback to track view
}; };
//$scope.watch()
$scope.showLessonSource = function() {
$('.lessonHelp').hide();
$('#lesson_source_row').show();
goat.utils.scrollToHelp();
}
$scope.showLessonPlan = function() {
$('.lessonHelp').hide();
$("#lesson_plan").html($scope.plan);
$('#lesson_plan_row').show();
goat.utils.scrollToHelp();
}
$scope.showLessonSolution = function() {
$('.lessonHelp').hide();
$("#lesson_solution").html($scope.solution);
$('#lesson_solution_row').show();
goat.utils.scrollToHelp();
}
$scope.manageHintButtons = function() {
if ($scope.hintIndex === $scope.hints.length - 1) {
$('#showNextHintBtn').css('visibility', 'hidden');
} else if ($scope.hintIndex < $scope.hints.length - 1) {
$('#showNextHintBtn').css('visibility', 'visible');
}
//
if ($scope.hintIndex === 0) {
$('#showPrevHintBtn').css('visibility', 'hidden');
} else if ($scope.hintIndex > 0) {
$('#showPrevHintBtn').css('visibility', 'visible');
}
};
$scope.viewHints = function() {
if (!$scope.hints) {
return;
}
$('.lessonHelp').hide();
$('#lesson_hint_row').show();
goat.utils.scrollToHelp();
$scope.curHint = $scope.hints[$scope.hintIndex].hint;
$scope.manageHintButtons();
};
$scope.viewNextHint = function() {
$scope.hintIndex++;
$scope.curHint = $scope.hints[$scope.hintIndex].hint;
$scope.manageHintButtons();
};
$scope.viewPrevHint = function() {
$scope.hintIndex--;
$scope.curHint = $scope.hints[$scope.hintIndex].hint;
$scope.manageHintButtons();
};
$scope.hideHints = function() {
};
$scope.showAbout = function() {
$('#aboutModal').modal({
remote: 'about.mvc'
});
};
}).animation('.slideDown', function() {
var NgHideClassName = 'ng-hide';
return {
beforeAddClass: function(element, className, done) {
if (className === NgHideClassName) {
$(element).slideUp(done);
}
},
removeClass: function(element, className, done) {
if (className === NgHideClassName) {
$(element).hide().slideDown(done);
}
}
};
}); });
/*
*DEPRECATED
//Controllers for modal instances
var showSourceController = function($scope, $modalInstance, lessonSource) {
$scope.lessonSource = lessonSource;
$scope.ok = function() {
$modalInstance.close();
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};
var showSolutionController = function($scope, $modalInstance, lessonSolutionUrl) {
$scope.lessonSolutionUrl = lessonSolutionUrl;
$scope.ok = function() {
$modalInstance.close();
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
};
*/

View File

@ -18,7 +18,7 @@ goat.data = {
return $.get(goatConstants.sourceService, {}); return $.get(goatConstants.sourceService, {});
}, },
loadSolution: function () { loadSolution: function () {
return $.get(goatConstants.solutionService, {}) return $.get(goatConstants.solutionService, {});
}, },
loadPlan: function () { loadPlan: function () {
return $.get(goatConstants.lessonPlanService, {}); return $.get(goatConstants.lessonPlanService, {});
@ -30,5 +30,8 @@ goat.data = {
loadMenuData: function() { loadMenuData: function() {
//TODO use goatConstants var for url //TODO use goatConstants var for url
return $http({method: 'GET', url: goatConstants.menuService}); return $http({method: 'GET', url: goatConstants.menuService});
},
loadLessonTitle: function () {
return $.get(goatConstants.lessonTitleService, {});
} }
}; };

View File

@ -31,7 +31,7 @@ goat.lesson = {
goat.data.loadHints().then( goat.data.loadHints().then(
function(resp) { function(resp) {
scope.hints = resp; scope.hints = resp;
if (scope.hints.length > 0) { if (scope.hints.length > 0 && scope.hints[0].hint.indexOf(goatConstants.noHints) === -1) {
goat.utils.displayButton('showHintsBtn',true); goat.utils.displayButton('showHintsBtn',true);
} else { } else {
goat.utils.displayButton('showHintsBtn',false); goat.utils.displayButton('showHintsBtn',false);
@ -103,7 +103,7 @@ goat.lesson = {
); );
}, },
getParams: function() { getParams: function() {
this.params = goat.utils.scrapeParams(this.lessonUrl) this.params = goat.utils.scrapeParams(this.lessonUrl);
} }
} }
} }

View File

@ -15,14 +15,6 @@ goat.utils = {
//console.log("Hooking any lesson forms to make them ajax"); //console.log("Hooking any lesson forms to make them ajax");
$("form").ajaxForm(options); $("form").ajaxForm(options);
}, },
/**goatApp.extractLessonTitle
*pulls lesson title from html fragment returned (looks for it in h1 element)
*@param - html rendered to object passed in
*/
extractLessonTitle: function(el) {
var title = $('h1', el).text();
return title;
},
displayButton: function(id,show) { displayButton: function(id,show) {
if ($('#'+id)) { if ($('#'+id)) {
if (show) { if (show) {
@ -44,7 +36,7 @@ goat.utils = {
}, },
showLessonSource: function(source) { showLessonSource: function(source) {
$('.lessonHelp').hide(); $('.lessonHelp').hide();
$('#lesson_source').html("<pre>"+goat.lesson.lessonInfo.source+"</pre>"); //$('#lesson_source').html("<pre>"+goat.lesson.lessonInfo.source+"</pre>");
$('#lesson_source_row').show(); $('#lesson_source_row').show();
goat.utils.scrollToHelp(); goat.utils.scrollToHelp();
}, },
@ -65,6 +57,7 @@ goat.utils = {
goat.utils.scrollEasy(target); goat.utils.scrollEasy(target);
}, },
scrollToTop: function() { scrollToTop: function() {
$('.lessonHelp').hide();
var target= $('#container'); var target= $('#container');
goat.utils.scrollEasy(target); goat.utils.scrollEasy(target);
}, },

View File

@ -8,7 +8,7 @@
<p> <p>
<b>How HTTP works:</b> <b>How HTTP works:</b>
</p> </p>
All HTTP transactions follow the same general format. Each client request and server response has three parts: the request or response line, a header section, and the entity body. The client initiates a transaction as follows: <br> All HTTP transactions follow the same general format. Each client request and server response has three parts: the request or response line, a header section and the entity body. The client initiates a transaction as follows: <br>
<br> <br>
The client contacts the server and sends a document request <br> The client contacts the server and sends a document request <br>
</div> </div>
@ -20,8 +20,8 @@ All HTTP transactions follow the same general format. Each client request and se
After sending the request and headers, the client may send additional data. This data is mostly used by CGI programs using the POST method.<br> After sending the request and headers, the client may send additional data. This data is mostly used by CGI programs using the POST method.<br>
<p><b>General Goal(s):</b> </p> <p><b>General Goal(s):</b> </p>
<!-- Start Instructions --> <!-- Start Instructions -->
Enter your name in the input field below and press "go" to submit. The server will accept the request, reverse the input, and display it back to the user, illustrating the basics of handling an HTTP request. Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input and display it back to the user, illustrating the basics of handling an HTTP request.
<br/><br/> <br/><br/>
The user should become familiar with the features of WebGoat by manipulating the above The user should become familiar with the features of WebGoat by manipulating the above
buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using WebScarab for the first time. buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using OWASP Zed Attack Proxy for the first time.
<!-- Stop Instructions --> <!-- Stop Instructions -->

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 186 KiB

View File

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 189 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

View File

Before

Width:  |  Height:  |  Size: 136 KiB

After

Width:  |  Height:  |  Size: 136 KiB

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 172 KiB

View File

Before

Width:  |  Height:  |  Size: 174 KiB

After

Width:  |  Height:  |  Size: 174 KiB

View File

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Some files were not shown because too many files have changed in this diff Show More