Merge branch 'release/8.0.0'

This commit is contained in:
nbaars 2017-12-30 16:50:39 +01:00
commit 114fbc5760
952 changed files with 57090 additions and 32287 deletions

9
.gitignore vendored
View File

@ -14,7 +14,8 @@
/.settings/org.eclipse.wst.validation.prefs
/.externalToolBuilders/
.project
/target
*/target/*
mongo-data/*
.classpath
.idea/
.settings/
@ -29,9 +30,15 @@ src/main/webapp/plugin_lessons/*.jar
src/main/webapp/users/*.props
classes/*
*.iml
pom.xml.versionsBackup
/*.iml
.extract/*
UserDatabase.mv.db
webgoat-container/src/main/webapp/users/guest.org.owasp.webgoat.plugin.*.props
webgoat-container/src/main/webapp/plugin_lessons/dist-*.pom
webgoat-lessons/**/target
**/*.jar
**/.DS_Store
webgoat-server/mongo-data/*
webgoat-lessons/vulnerable-components/dependency-reduced-pom.xml

View File

@ -1,59 +1,53 @@
services:
- docker
language: java
jdk:
- oraclejdk7
- oraclejdk8
install: "/bin/true"
script:
- export BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
- echo "TRAVIS_BRANCH=$TRAVIS_BRANCH, PR=$PR, BRANCH=$BRANCH"
- if [ ! -z "${TRAVIS_TAG}" ]; then mvn versions:set -DnewVersion=${TRAVIS_TAG:1}; fi
- mvn clean install -q
- git clone -b develop https://github.com/WebGoat/WebGoat-Lessons.git
- mvn -file ./WebGoat-Lessons/pom.xml clean package -q
- cp -fa ./WebGoat-Lessons/target/plugins/*.jar ./webgoat-container/src/main/webapp/plugin_lessons/
# Start the container this will make sure we do not see the debug logging of the Tomcat 7 Maven plugin
# which seems to always be set to DEBUG this will fail the build because we generate too much logging
- nohup bash -c "java -jar ./webgoat-standalone/target/webgoat-standalone-7.1-SNAPSHOT-exec.jar --port 8888 2>&1 &"
- if [[ $TRAVIS_PULL_REQUEST == "false" ]]; then mvn "-Dbuild.number=$TRAVIS_BUILD_NUMBER" -q clean install failsafe:integration-test; else mvn -q failsafe:integration-test; fi
cache:
directories:
- $HOME/.m2
- "$HOME/.m2"
before_deploy:
- export WEBGOAT_CONTAINTER_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webgoat-container/target
- export WEBGOAT_STANDALONE_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webgoat-standalone/target
- export WEBGOAT_SERVER_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webgoat-server/target
- export WEBWOLF_TARGET_DIR=$HOME/build/$TRAVIS_REPO_SLUG/webwolf/target
- export WEBGOAT_ARTIFACTS_FOLDER=$HOME/build/$TRAVIS_REPO_SLUG/Deployable_Artifacts/
- mkdir $WEBGOAT_ARTIFACTS_FOLDER
- cp -fa $WEBGOAT_CONTAINTER_TARGET_DIR/* $WEBGOAT_ARTIFACTS_FOLDER/
- cp -fa $WEBGOAT_STANDALONE_TARGET_DIR/* $WEBGOAT_ARTIFACTS_FOLDER/
- echo "Contents of artifcts folder:"
- mkdir -p $WEBGOAT_ARTIFACTS_FOLDER
- cp -fa $WEBGOAT_SERVER_TARGET_DIR/*.jar $WEBGOAT_ARTIFACTS_FOLDER/
- cp -fa $WEBWOLF_TARGET_DIR/*.jar $WEBGOAT_ARTIFACTS_FOLDER/
- echo "Contents of artifacts folder:"
- ls $WEBGOAT_ARTIFACTS_FOLDER
deploy:
provider: s3
access_key_id: AKIAJQLKPGHXRH2AH5QA
secret_access_key:
secure: 45+SwWlPFujD9FOOFLA9Lz0CaePVrn/SEsAhAn0Ve9sYpI0VsijZNymh6D29t93jBXgZoGhu/v0QJkcAA/71fQM+nGMBJjB5wmVFJ1c2A4k7tfWCVbBRI0aHGpJu12j+7BLuSfPCmCAFQGoVo7dWzfqeODe5j9Qpe9fsiQVnrKI=
bucket: webgoat-war
- provider: script
skip_cleanup: true
acl: public_read
local_dir: "$WEBGOAT_ARTIFACTS_FOLDER"
script: bash scripts/deploy-webgoat.sh
on:
repo: WebGoat/WebGoat
tags: true
- provider: script
skip_cleanup: true
script: bash scripts/deploy-webgoat.sh
on:
repo: WebGoat/WebGoat
branch: develop
jdk: oraclejdk8
after_success:
- mvn versioneye:update -q
- mvn cobertura:cobertura coveralls:report -q
notifications:
slack:
secure: S9VFew5NSE8WDzYD1VDBUULKKT0fzgblQACznwQ85699b2yeX9TX58N3RZvRS1JVagVP1wu2xOrwN2g+AWx4Ro3UBZD5XG86uTJWpCLD4cRWHBoGMH2TfvI7/IzsWmgxH4MBxFRvZr/eEhlVAux+N9H4EoEdS4CKsJXEqV37PlA=
- provider: releases
skip_cleanup: true
overwrite: true
api_key:
#api-key from webgoat-github user
secure: pJOLBnl6427PcVg/tVy/qB18JC7b8cKpffau+IP0pjdSt7KUfBdBY3QuJ7mrM65zRoVILzggLckaew2PlRmYQRdumyWlyRn44XiJ9KO4n6Bsufbz+ictB4ggtozpp9+I9IIUh1TmqypL9lhkX2ONM9dSHmyblYpAAgMuYSK8FYc=
file_glob: true
file: $WEBGOAT_ARTIFACTS_FOLDER/*
on:
repo: WebGoat/WebGoat
tags: true
env:
global:
- secure: "ZLZKz6lGt8YZ+NhkZPBAlI235+lEmu37Tcf+yTwh5yXuHAlnvvF6hPui7rANA/stbYGOIqIdhGOXbdrwyTU4Pvg78VwJOwsa9RtHJfou3pg4Ud9i0/dEeVl8aakmg2HDaWYGcFox8X1ViVc5UWjuBLztfJKQUEx0buJoWdMSf2E="
addons:
sauce_connect: true
coverity_scan:
project:
name: "WebGoat/WebGoat"
description: "Coverity Scan from Travis CI Build Automation"
notification_email: doug.morato@owasp.org
build_command_prepend: "mvn clean"
build_command: "mvn -DskipTests=true install"
branch_pattern: coverity_scan
#Docker login
- secure: XgPc0UKRTUI70I4YWNQpThPPWeQIxkmzh1GNoR/SSDC2GPIBq3EfkkbSQewqil8stTy+S1/xSzc0JXG8NTn7UOxHVHA/2nhI6jX9E+DKtXQ89YwmaDNQjkbMjziAtDCIex+5TRykxNfkxj6VPYbDssrzI7iJXOIZVj/HoyO3O5E=
#Docker password
- secure: aly5TKBUK9sIiqtMbytNNPZHQhC0a7Yond5tEtuJ8fO+j/KZB4Uro3I6BhzYjGWFb5Kndd0j2TXHPFvtOl402J1CmFsY3v0BhilQd0g6zOssp5T0A73m8Jgq4ItV8wQJJy2bQsXqL1B+uFYieYPiMchj7JxWW0vBn7TV5b68l6U=

29
CREATE_RELEASE.MD Normal file
View File

@ -0,0 +1,29 @@
## Release WebGoat
### Version numbers
For WebGoat we use milestone releases first before we release the official version, we use `v8.0.0.M3` while tagging
and 8.0.0.M3 in the `pom.xml`. When we create the final release we remove the milestone release and use
`v8.0.0` and 8.0.0 in the `pom.xml`
At the moment we use Gitflow, for a release you create a new release branch and take the following steps:
```
git checkout develop
git flow release start <version>
mvn versions:set <<version>
git commit -am "New release, updaing pom.xml"
git flow release publish
```
Now we can make a new release, be sure you committed all your changes.
```
git tag v8.0.0.M3
git push origin v8.0.0.M3
```
Now Travis takes over and will create the release in Github and on Docker Hub.

271
README.MD
View File

@ -1,17 +1,13 @@
# WebGoat: A deliberately insecure Web Application
# WebGoat 8: A deliberately insecure Web Application
[![Build Status](https://travis-ci.org/WebGoat/WebGoat.svg?branch=develop)](https://travis-ci.org/WebGoat/WebGoat)
[![Coverage Status](https://coveralls.io/repos/WebGoat/WebGoat/badge.svg?branch=master&service=github)](https://coveralls.io/github/WebGoat/WebGoat?branch=master)
[![Coverage Status](https://coveralls.io/repos/WebGoat/WebGoat/badge.svg?branch=develop&service=github)](https://coveralls.io/github/WebGoat/WebGoat?branch=master)
[![Codacy Badge](https://api.codacy.com/project/badge/b69ee3a86e3b4afcaf993f210fccfb1d)](https://www.codacy.com/app/dm/WebGoat)
[![Dependency Status](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa/badge.svg?style=flat)](https://www.versioneye.com/user/projects/562da95ae346d7000e0369aa)
[![OWASP Labs](https://img.shields.io/badge/owasp-labs-orange.svg)](https://www.owasp.org/index.php/OWASP_Project_Inventory#tab=Labs_Projects)
# Important Information
### The WebGoat Lesson Server, is currently **UNDER MAJOR DEVELOMENT**.
As of November 18th 2016, the version "7.1" is considered the first **STABLE** version of a major architecture and UI changes.
#### Older/Legacy version of WebGoat an be found at: [WebGoat-Legacy](https://github.com/WebGoat/WebGoat-Legacy)
# Introduction
WebGoat is a deliberately insecure web application maintained by [OWASP](http://www.owasp.org/) designed to teach web
application security lessons.
@ -20,19 +16,8 @@ This program is a demonstration of common server-side application flaws. The
exercises are intended to be used by people to learn about application security and
penetration testing techniques.
* [Home Page](http://webgoat.github.io)
* [OWASP Project Home Page](http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project)
* [Source Code](https://github.com/WebGoat/WebGoat)
* [Easy-Run Download](https://s3.amazonaws.com/webgoat-war/webgoat-container-7.0.1-war-exec.jar)
* [Wiki](https://github.com/WebGoat/WebGoat/wiki)
* [FAQ (old info):](http://code.google.com/p/webgoat/wiki/FAQ)
* [Project Leader - Direct to Bruce Mayhew](mailto:webgoat@owasp.org)
* [Mailing List - WebGoat Community - For most questions](mailto:owasp-webgoat@lists.owasp.org)
* [Artifacts generated from Continuous Integration](http://webgoat-war.s3-website-us-east-1.amazonaws.com/)
* [Output from our Travis.CI Build server](https://travis-ci.org/WebGoat/WebGoat)
**WARNING 1:** *While running this program your machine will be extremely
vulnerable to attack. You should to disconnect from the Internet while using
vulnerable to attack. You should disconnect from the Internet while using
this program.* WebGoat's default configuration binds to localhost to minimize
the exposure.
@ -42,171 +27,147 @@ you are caught engaging in unauthorized hacking, most companies will fire you.
Claiming that you were doing security research will not work as that is the
first thing that all hackers claim.*
# Easy Run ( For non-developers )
# Run Instructions:
Every successful build of the WebGoat Lessons Container and the WebGoat Lessons in our Continuous Integration Server
creates an "Easy Run" Executable JAR file, which contains the WebGoat Lessons Server, the lessons and a embedded Tomcat server.
## 1. Run using Docker
You can check for the "Last Modified" date of our "Easy Run" jar file [HERE](http://webgoat-war.s3-website-us-east-1.amazonaws.com/)
The "Easy Run" JAR file offers a no hassle approach to testing and running WebGoat. Follow these instructions if you
wish to simply try/test/run the current development version of WebGoat
### Prerequisites:
* Java VM 1.8
## Standalone
#### 1. Download the easy run executable jar file which contains all the lessons and a embedded Tomcat server:
https://s3.amazonaws.com/webgoat-war/webgoat-standalone-7.1-SNAPSHOT-exec.jar
#### 2. Run it using java:
Open a command shell/window, browse to where you downloaded the easy run jar and type:
From time to time we publish a new development preview of WebGoat 8 on Docker HUB, you can download this version
[https://hub.docker.com/r/webgoat/webgoat-8.0/](https://hub.docker.com/r/webgoat/webgoat-8.0/).
First install Docker, then open a command shell/window and type:
```Shell
java -jar webgoat-standalone-7.0.1-exec.jar [-p | --p <port>] [-a | --address <address>]
docker pull webgoat/webgoat-8.0
docker run -p 8080:8080 -it webgoat/webgoat-8.0 /home/webgoat/start.sh
```
Using the `--help` option will show the allowed command line arguments.
Wait for the Docker container to start, and run `docker ps` to verify it's running.
#### 3. Browse to the url shown in the console and happy hacking !
- If you are using `docker-machine`, verify the machine IP using `docker-machine env`
- If you are using `boot2docker` on OSX, verify the IP by running `docker network inspect bridge`
- Otherwise, the host will be bound to localhost
## Vagrant
Once you have the IP and port, you'll want to navigate to the `/WebGoat` path in the URL. For example:
To run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
```
http://192.168.99.100:8080/WebGoat
```
Here you'll be able to register a new user and get started.
_Please note: this version may not be completely in sync with the develop branch._
## 2. Standalone
Download the latest WebWolf release from [https://github.com/WebGoat/WebGoat/releases](https://github.com/WebGoat/WebGoat/releases)
```Shell
java -jar webgoat-server-<<version>>.jar
```
By default WebGoat starts at port 8080 in order to change this use the following property:
```Shell
java -jar webgoat-server-<<version>>.jar --server.port=9090
```
You can specify one of the following arguments when starting WebGoat:
```Shell
java -jar webgoat-server-<<version>>.jar --server.port=9090 --server.address=x.x.x.x
```
This will start WebGoat on a different port and/or different address.
## 3. Run from the sources
### Prerequisites:
* Java 8
* Maven > 3.2.1
* Your favorite IDE
* Git, or Git support in your IDE
Open a command shell/window:
```Shell
git clone git@github.com:WebGoat/WebGoat.git
```
Now let's start by compiling the project.
```Shell
cd WebGoat
git checkout <<branch_name>>
mvn clean install
```
Now we are ready to run the project. WebGoat 8.x is using Spring-Boot.
```Shell
mvn -pl webgoat-server spring-boot:run
```
... you should be running webgoat on localhost:8080/WebGoat momentarily
To change IP address add the following variable to WebGoat/webgoat-container/src/main/resources/application.properties file
```
server.address=x.x.x.x
```
# Vagrant
We supply a complete development environment using Vagrant, to run WebGoat with Vagrant you must first have Vagrant and Virtualbox installed.
```shell
$ cd WebGoat/webgoat-images/vagrant-users
$ vagrant up
```
Once you see the message 'Browse to http://localhost:9999/WebGoat and happy hacking! you can open a
browser.
# For Developers
## Vagrant
For an easy development experience you can use Vagrant. Note you should have Vagrant and Virtualbox installed on your system.
```shell
$ cd WebGoat/webgoat-images/vagrant-developers
$ vagrant up
```
Once the provisioning is complete login to the Virtualbox with username vagrant and password vagrant.
The source code will be available in the home directory.
## Set up manual
Follow these instructions if you wish to run Webgoat and modify the source code as well.
# Building a new Docker image
### Prerequisites:
NOTE: Travis will create a new Docker image automatically when making a new release.
* Java 1.8
* Maven > 2.0.9
* Your favorite IDE, with Maven awareness: Netbeans/IntelliJ/Eclipse with m2e installed.
* Git, or Git support in your IDE
## The Easy Way: Developer Edition run using Linux or Mac
The __webgoat_developer_bootstrap.sh__ script will clone the necessary repositories, call the maven goals in order
launch Tomcat listening on localhost:8080
WebGoat now has Docker support for x86 and ARM (raspberry pi).
### Docker on x86
On x86 you can build a container with the following commands:
```Shell
mkdir WebGoat-Workspace
cd WebGoat-Workspace
curl -o webgoat_developer_bootstrap.sh https://raw.githubusercontent.com/WebGoat/WebGoat/master/webgoat_developer_bootstrap.sh
./webgoat_developer_bootstrap.sh
cd WebGoat/
mvn install
cd webgoat-server
docker build -t webgoat/webgoat-8.0 .
docker tag webgoat/webgoat-8.0 webgoat/webgoat-8.0:8.0
docker login
docker push webgoat/webgoat-8.0
```
## The Manual Way: Developer Edition!
#### Cloning the Lesson Server and the Lessons project:
Open a command shell/window, navigate to where you wish to download the source and type:
### Docker on ARM (Raspberry Pi)
On a Raspberry Pi (it has yet been tested with a Raspberry Pi 3 and the hypriot Docker image) you need to build JFFI for
ARM first. This is needed by the docker-maven-plugin ([see here](https://github.com/spotify/docker-maven-plugin/issues/233)):
```Shell
git clone https://github.com/WebGoat/WebGoat.git
git clone https://github.com/WebGoat/WebGoat-Lessons.git
sudo apt-get install build-essential
git clone https://github.com/jnr/jffi.git
cd jffi
ant jar
cd build/jni
sudo cp libjffi-1.2.so /usr/lib
```
#### Now let's start by compiling the WebGoat Lessons server.
When you have done this you can build the Docker container using the following commands:
```Shell
cd WebGoat
git checkout develop
mvn clean compile install
cd ..
cd WebGoat/
mvn install
cd webgoat-server
mvn docker:build -Drpi=true
docker tag webgoat/webgoat-8.0 webgoat/webgoat-8.0:8.0
docker login
docker push webgoat/webgoat-8.0
```
#### Before you can run the project, we need to compile the lessons and copy them over:
**If you don't run this step, you will not have any Lessons to work with!**
```Shell
cd WebGoat-Lessons
git checkout develop
mvn package
(linux) cp target/plugins/*.jar ../WebGoat/webgoat-container/src/main/webapp/plugin_lessons/
(windows) xcopy "target\plugins\*.jar" "..\WebGoat\webgoat-container\src\main\webapp\plugin_lessons\"
cd ..
```
#### Now we are ready to run the project. There are 3 options you can choose from to run the project:
Then you can run the project with one of the steps below (From the WebGoat folder not WebGoat-Lessons):
#### Option #1: Using the Maven-Tomcat Plugin
The __maven tomcat7:run-war__ goal runs the project in an embedded tomcat:
```Shell
cd WebGoat
mvn -pl webgoat-container tomcat7:run-war
```
Browse to [http://localhost:8080/WebGoat](http://localhost:8080/WebGoat) and happy hacking !
#### Option #2: Java executable JAR
The __maven package__ goal generates an executable .jar file:
```Shell
cd WebGoat
mvn package
cd webgoat-standalone/target
java -jar webgoat-standalone-7.1-SNAPSHOT-exec.jar [-p | --p <port>] [-a | --address <address>]
```
Browse to url shown in the console and happy hacking !
#### Option #3: Deploy the WebGoat WAR file in your local Tomcat or other Application Server:
The __maven package__ goal generates a .war file that can deployed into an Application Server, such as Tomcat
```Shell
cd WebGoat
mvn package
cp webgoat-container/target/webgoat-container-7.1-SNAPSHOT.war <your_tomcat_directory>/webapps/
```
Browse to [http://localhost:8080/WebGoat](http://localhost:8080/WebGoat) and happy hacking !
# Debugging and Troubleshooting
## Reloading plugins and lessons
If you want to __reload all the plugin and lessons__, open a new browser tab and visit the following url:
[http://localhost:8080/WebGoat/service/reloadplugins.mvc](http://localhost:8080/WebGoat/service/reloadplugins.mvc)
After the plugin reload is complete, _reloading a message_ will appear and you can refresh the __main WebGoat browser tab__.
## Debugging label properties
To be able to see which labels are loaded through a property file, open a new browser tab and visit the following url:
[http://localhost:8080/WebGoat/service/debug/labels.mvc](http://localhost:8080/WebGoat/service/debug/labels.mvc)
Switch back to the main WebGoat broswer tab and __reload the main WebGoat browser tab__.
After the reload is complete, all labels which where loaded from a property file will be __marked green__.

12
buildspec.yml Normal file
View File

@ -0,0 +1,12 @@
version: 0.1
phases:
build:
commands:
- mvn package
artifacts:
files:
- webgoat-server/target/webgoat-server-8.0-SNAPSHOT.jar
discard-paths: yes

View File

@ -1,3 +0,0 @@
grant {
permission java.security.AllPermission;
};

15
docker-compose.yml Normal file
View File

@ -0,0 +1,15 @@
version: '2.0'
services:
webgoat:
build: webgoat-server/
command: "sh /home/webgoat/start.sh"
ports:
- "8080:8080"
webwolf:
build: webwolf/
command: "sh /home/webwolf/start.sh"
depends_on:
- webgoat
ports:
- "8081:8081"

View File

@ -0,0 +1,31 @@
# AWS
- This contains the various platform Quick Starts for Getting WebGoat Deployed into AWS.
- This IaaS quickstart uses AWS CloudFormation to perform most of the provisioning
- This IaaS quickstart is composed of three independent bundles
- Code pipeline and Build
- Deploying to EC2
- Deploying to ECS
It is Assumed:
- You have an AWS Account
- You know what an S3 bucket is
- You have seen the IAM console and have permissions to create IAM Roles
## Code Pipeline and Build
This Quickstart is for those that just want to perform builds with AWS. It Triggers off of Github to perform builds of `webgoat-server`
## EC2
(WIP) This uses AWS CodePipeline, CodeBuild, and CodeDeploy to land WebGoat to Running EC2 instances
## ECS
(WIP) This uses AWS CodePipeline, CodeBuild, ECR, to land a container onto an ECS cluster

View File

@ -0,0 +1,101 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "IAM Roles for Code Build WebGoat IaaS Quickstart",
"Parameters": {
"qsS3BucketName": {
"Description": "Name of the S3 Bucket for artifacts",
"Type": "String",
"MinLength": "1"
},
"qsRoleName": {
"Description": "Name of the IAM role that CodeBuild Will Use",
"Type": "String",
"Default": "SimpleCodeBuildRole",
"MinLength": "1"
}
},
"Resources": {
"qsCodeBuildRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"codebuild.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/webgoat/",
"RoleName": {
"Ref": "qsRoleName"
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/AWSCodeCommitFullAccess",
"arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess",
"arn:aws:iam::aws:policy/AWSCodeDeployDeployerAccess"
],
"Policies": [
{
"PolicyName": "CloudWatchLogs",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
{"Fn::Join": [ "",["arn:aws:logs:*:", { "Ref": "AWS::AccountId" }, ":log-group:/aws/codebuild*" ] ]}
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}
]
}
},
{
"PolicyName": "S3buckets",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "qsS3BucketName"
},
"*"
]
]
},
"arn:aws:s3:::codepipeline-*"
],
"Action": [
"s3:Put*",
"s3:Get*",
"s3:List*"
]
}
]
}
}
]
}
}
}
}

View File

@ -0,0 +1,127 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "IAM Role for Code Pipeline WebGoat IaaS Quickstart",
"Parameters": {
"qsS3BucketName": {
"Description": "Name of the S3 Bucket for artifacts",
"Type": "String",
"MinLength": "1"
},
"qsRoleName": {
"Description": "Name of the IAM role that CodePipeline Will Use",
"Type": "String",
"Default": "SimpleCodePipelineRole",
"MinLength": "1"
}
},
"Resources": {
"qsCodePipelineRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "codepipeline.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Path": "/webgoat/",
"RoleName": {
"Ref": "qsRoleName"
},
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/AWSCodeCommitFullAccess",
"arn:aws:iam::aws:policy/AWSCodeBuildDeveloperAccess",
"arn:aws:iam::aws:policy/AWSCodeDeployDeployerAccess"
],
"Policies": [
{
"PolicyName": "CloudWatchLogsPipeline",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
{"Fn::Join": [ "",["arn:aws:logs:*:", { "Ref": "AWS::AccountId" }, ":log-group:/aws/*" ] ]}
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
}
]
}
},
{
"PolicyName": "MiscComputeOpen",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": "*",
"Action": [
"lambda:InvokeFunction",
"lambda:ListFunctions",
"elasticbeanstalk:*",
"ec2:*",
"elasticloadbalancing:*",
"autoscaling:*",
"cloudwatch:*",
"s3:*",
"sns:*",
"cloudformation:*",
"rds:*",
"sqs:*",
"ecs:*",
"iam:PassRole"
]
}
]
}
},
{
"PolicyName": "S3buckets",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "qsS3BucketName"
},
"*"
]
]
},
"arn:aws:s3:::codepipeline-*",
"arn:aws:s3:::elasticbeanstalk*"
],
"Action": [
"s3:Put*",
"s3:Get*",
"s3:List*"
]
}
]
}
}
]
}
}
}
}

View File

@ -0,0 +1,123 @@
AWSTemplateFormatVersion: "2010-09-09"
Description: >
AWS Cloud Formation for creating an AWS CodePipeline that checks a git repo for changes and then performs a build using code build
Parameters:
qsPipelineName:
Description: The name of the AWS Code Pipeline
Type: String
Default: WG-pipeline
MinLength: 1
qsPipelineRoleARN:
Description: The complete ARN to the IAM role that code pipeline should use
Type: String
MinLength: 1
qsCodeRepo:
Description: The Repository
Type: String
MinLength: 1
qsRepoBranch:
Description: The Branch in the Repository
Type: String
MinLength: 1
qsGitHubUser:
Description: The GitHub User Id
Type: String
MinLength: 1
qsGitHubAPIToken:
Description: The GitHub Personal Access token do not use password
NoEcho: true
Type: String
MinLength: 1
qsS3PipelineArtifacts:
Description: Where Code Pipeline will state artifacts in S3
Type: String
MinLength: 1
qsS3CodeBuildArtifacts:
Description: Where Code Build will upload Artifacts can be same as codepipeline
Type: String
MinLength: 1
qsCodeBuildName:
Description: Name of the AWS Code Build
Type: String
Default: WG-mvnBuilder
MinLength: 1
qsKMSKeyARN:
Description: The KMS ARN that the IAM Role is allowed to use
Type: String
MinLength: 1
qsCodeRoleArn:
Description: The IAM Role ARN for CodePipeline and CodeDeploy
Type: String
MinLength: 1
Resources:
stkcbrCodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Description: Builds WebGoat Jar using build file in repo
EncryptionKey: !Ref 'qsKMSKeyARN'
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/java:openjdk-8
Type: LINUX_CONTAINER
Name: !Ref 'qsCodeBuildName'
ServiceRole: !Ref 'qsCodeRoleArn'
TimeoutInMinutes: 10
Source:
Type: CODEPIPELINE
stkcplPipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: !Ref 'qsPipelineName'
RoleArn: !Ref 'qsPipelineRoleARN'
ArtifactStore:
Location: !Ref 'qsS3PipelineArtifacts'
Type: S3
Stages:
- Name: CodeRepo
Actions:
- Name: CodeSource
ActionTypeId:
Category: Source
Owner: ThirdParty
Provider: GitHub
Version: 1
Configuration:
Branch: !Ref 'qsRepoBranch'
Repo: !Ref 'qsCodeRepo'
Owner: !Ref 'qsGitHubUser'
OAuthToken: !Ref 'qsGitHubAPIToken'
OutputArtifacts:
- Name: MySource
RunOrder: '1'
- Name: Build
Actions:
- Name: CodeBuild
ActionTypeId:
Category: Build
Owner: AWS
Provider: CodeBuild
Version: 1
InputArtifacts:
- Name: MySource
Configuration:
ProjectName: !Ref stkcbrCodeBuild
OutputArtifacts:
- Name: MyBuild
RunOrder: '2'

View File

@ -0,0 +1,64 @@
# Serverless MVN builds Featuring AWS
This Quick Start forms the basis for the other AWS quickstarts. This only BUILDS the `webgoat-server` spring boot jar. If you want to also run it on AWS skip to the other AWS quickstarts
Before you Begin
1. Do you have an AWS Account?
2. Can you create an S3 Bucket?
3. Can you create a KMS Key?
4. Do you know what Cloud Formation is?
5. Do you have enough permissions to do any real work in said AWS Account?
If you said no to any of those...hop over to [docs](https://aws.amazon.com/documentation/) and learn (but don't do) how to create those.
You will also need:
1. A GitHub Account
2. Fork of WebGoat
3. Personal access Token with `Admin:repo_hook` and `repo`
## Create Pre-requisites
First pick an AWS region and stick with it for ALL the quickstarts. This one was mostly executed on US-east-1/2 but any region with KMS, CodePipeline, and CodeBuild will work. eu-Central-1, ap-southeast-1 and sa-east-1 have reported success also.
1. Create an S3 bucket and call it something meaningfull like `webgoat-stash-username` or something or use an existing bucket you have access to.
2. Create a KMS Key. Make sure you are a key administrator so you can add key users later.
## Deploy IAM role Cloud Formation Stacks
In this folder there are two json cloudformation templates:
-`01_IAM_codebuild.json`
-`01_IAM_codepipeline.json`
You will use the CloudFormation templates to create two roles. One for CodePipeline and the Other for CodeBuild. You will use the name of the bucket you just created as a parameter.
## Update KMS Key
Access the KMS key you created earlier...add the two IAM roles you just created and Key Users
## Finally the Pipeline
You will use the yaml cloudformation template `01_codepiplinebuild.yml` to create the code building pipeline.
Some of the parameters you will need to pass:
1. The S3 bucket (twice)
2. The Github Branch name (master? develop? yourbranchname?)
3. The Github user (if you forked it would be your username)
4. You personal access token for GitHub
5. The name or the repo (WebGoat! ...unless you renamed and did a whole bunch of fancy git magic)
6. The ARN of the KMS key
7. The ARN of the role for the codebuild for parameter qsCodeRoleArn
8. The ARN for codepipeline
If this Stack successfully deploys a build will begin based on the latest commit automatically. You will have a funky named zip file (without the .zip ending) in a folder in the S3 bucket in a few minutes.
Congratulations. You just Deployed a two step AWS Codepipeline that looks for codechanges and then performs a build.
... ON to the next AWS Quickstart

View File

@ -0,0 +1,80 @@
# GKE - DockerHub
This Quickstart shows how to create a Kubernettes Cluster using Google Cloud Platform's [GKE](https://cloud.google.com/container-engine/) and WebGoat's Docker [Image](https://hub.docker.com/r/webgoat/webgoat-8.0/).
To be Successfull with this Quickstart
1. You have a Google Cloud Platform account and have enough access rights to create Compute Engine and Container Engine Resources
2. You know how to `git clone`
3. You have the gcloud SDK install and initialized somewhere ( do not use the google cloud shell)
Remeber to perform a 'gcloud auth login' before using the gcloud commands below.
## Create Kubernettes Cluster
You can create a cluster using the Google Cloud Console. The Default settings will suffice. For this QuickStart the cluster name used is `owaspbasiccluster`. The `PROJECTNAME` is whatever your project is. The `REGION` is a region/zone near you.
If you want to use the gcloud sdk from a properly initialized gcloud commandline environment use the following command
```
gcloud container --project "PROJECTNAME" clusters create "owaspbasiccluster" --zone "REGION" --machine-type "n1-standard-1" --image-type "COS" --disk-size "100" --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/cloud-platform","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append","https://www.googleapis.com/auth/source.read_only" --num-nodes "3" --network "default" --enable-cloud-logging --no-enable-cloud-monitoring
```
The command creates a similar cluster with more of the options set explicitly.
## Set up Kubectl
Using the commandline gcloud SDK environment you need to set-up 'kubectl'
If you have not already installed 'Kubectl' you can do so with the following command using `gcloud`
- `gcloud components install kubectl`
Then you just run:
- `gcloud container clusters get-credentials owaspbasiccluster --zone REGION --project PROJECTNAME`
## Deploy WebGoat Deployment
Time to deploy the latest DockerImage for WebGoat!
Let's First Make a namespace for this:
- `kubectl create namespace webgoat`
Now it is time to make the magic happen!
- `kubectl create -f /where_you_git_cloned_webgoat/platformQuickStart/GCP/GKE-Docker/webgoat_noDNSnoTLS.yml`
This should complete with no errors.
Use the following command to see information/status about the deployment
- `kubectl describe deployment webgoat-dpl --namespace=webgoat`
After a few minutes the service endpoint should be ready. You can check the status with
- `kubectl describe service webgoatsvc --namespace=webgoat`
In the output you should see a message like "Created load..." after a "Creating load..." which means that the public facing loadbalancer (even thou there is just one container running!) is ready.
If you want to see the Kubernetes dashboard you can run `kubectl proxy` (in a new terminal window) and then navigate to http://localhost:8001/ui .
## Test Deployment
From the previous `describe service` command the `LoadBalancer Ingress:` line should have the external IP. The line below should give the port.
So.....
[IP]:[PORT]/WebGoat in your browser!
DONE

View File

@ -0,0 +1,39 @@
---
apiVersion: v1
kind: Service
metadata:
labels:
app: webgoatapp
name: webgoatsvc
namespace: webgoat
spec:
ports:
-
port: 8080
protocol: TCP
selector:
app: webgoatapp
type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: webgoat-dpl
namespace: webgoat
spec:
replicas: 1
template:
metadata:
name: webgoatapp
labels:
app: webgoatapp
spec:
containers:
-
image: webgoat/webgoat-8.0
name: webgoat
ports:
-
containerPort: 8080

View File

@ -0,0 +1,17 @@
# WebGoat on GCP!
This folder contains sub folders for the various ways you could deploy WebGoat on Google Cloud Platform
It is assumed:
1. You have a Google Cloud Platform Account
2. You can use Git
3. You can use a Linux/Mac/Google Cloud Shell
## GKE Docker
Uses GKE to run the latest DockerHub version of WebGoat8
## AppEngine
WIP

View File

@ -0,0 +1,22 @@
# OWASP WebGoat Platform Quick Starts
Want to Run WebGoat? Want to run WebGoat in the Cloud? Don't want to be cloud Expert?
Do we have a solution for you!
Additionally, Each IaaS/PaaS will have their deployment steps broken down giving the *app-guy-new-to-cloud* an opportunity to learn how said platform works.
## AWS
Multi-Part Quickstart. Starts with simple pipeline that just builds code to a deploying onto EC2 instances and then containers using ECS/ECR
## GCP
Get WebGoat Running on GKE and AppEngine

52
pom.xml
View File

@ -5,7 +5,7 @@
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-parent</artifactId>
<packaging>pom</packaging>
<version>7.1</version>
<version>8.0.0.M3</version>
<name>WebGoat Parent Pom</name>
<description>Parent Pom for the WebGoat Project. A deliberately insecure Web Application</description>
@ -17,6 +17,12 @@
<url>https://webgoat.github.io/</url>
</organization>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.5.RELEASE</version>
</parent>
<licenses>
<license>
<name>GNU General Public License, version 2</name>
@ -35,14 +41,14 @@
<developer>
<id>nbaars</id>
<name>Nanne Baars</name>
<email>nbaars@xebia.com</email>
<email>nanne.baars@owasp.org</email>
<organizationUrl>https://github.com/nbaars</organizationUrl>
<timezone>Europe/Amsterdam</timezone>
</developer>
<developer>
<id>misfir3</id>
<name />
<email />
<name>Jason White</name>
<email>jason.white@owasp.org</email>
</developer>
<developer>
<id>jwayman</id>
@ -86,7 +92,7 @@
<url>https://github.com/WebGoat/WebGoat</url>
<connection>scm:git:git@github.com:WebGoat/WebGoat.git</connection>
<developerConnection>scm:git:git@github.com:WebGoat/WebGoat.git</developerConnection>
<tag>7.1</tag>
<tag>HEAD</tag>
</scm>
<issueManagement>
@ -100,6 +106,9 @@
</ciManagement>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Use UTF-8 Encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@ -121,22 +130,20 @@
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<commons-io.version>2.4</commons-io.version>
<commons-lang3.version>3.4</commons-lang3.version>
<commons-logging.version>1.2</commons-logging.version>
<coveralls-maven-plugin.version>4.0.0</coveralls-maven-plugin.version>
<ecs.version>1.4.2</ecs.version>
<gatling.version>2.2.5</gatling.version>
<gatling-plugin.version>2.2.4</gatling-plugin.version>
<guava.version>18.0</guava.version>
<h2.version>1.4.190</h2.version>
<hsqldb.version>1.8.0.10</hsqldb.version>
<hsqldb.version>2.3.2</hsqldb.version>
<j2h.version>1.3.1</j2h.version>
<jackson-core.version>2.6.3</jackson-core.version>
<jackson-databind.version>2.6.3</jackson-databind.version>
<javaee-api.version>6.0</javaee-api.version>
<javax.transaction-api.version>1.2</javax.transaction-api.version>
<jcl-over-slf4j.version>1.7.12</jcl-over-slf4j.version>
<jstl.version>1.2</jstl.version>
<jtds.version>1.3.1</jtds.version>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<mail-api.version>1.5.4</mail-api.version>
<maven-compiler-plugin.version>3.3</maven-compiler-plugin.version>
<maven-failsafe-plugin.version>2.19</maven-failsafe-plugin.version>
@ -146,13 +153,10 @@
<maven-release-plugin.version>2.5.2</maven-release-plugin.version>
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
<maven-surefire-plugin.version>2.19</maven-surefire-plugin.version>
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<nexus-staging-maven-plugin.version>1.6.7</nexus-staging-maven-plugin.version>
<org.springframework.version>3.2.4.RELEASE</org.springframework.version>
<nexus-staging-maven-plugin.version>1.6.6</nexus-staging-maven-plugin.version>
<scala.version>2.11.7</scala.version>
<sauce_junit.version>2.1.20</sauce_junit.version>
<selenium-java.version>2.48.2</selenium-java.version>
<slf4j-api.version>1.7.12</slf4j-api.version>
<slf4j-log4j12.version>1.7.12</slf4j-log4j12.version>
<spring.security.version>3.2.4.RELEASE</spring.security.version>
<standard.version>1.1.2</standard.version>
<tiles.version>3.0.5</tiles.version>
@ -164,7 +168,9 @@
<modules>
<module>webgoat-container</module>
<module>webgoat-standalone</module>
<module>webgoat-lessons</module>
<module>webgoat-server</module>
<module>webwolf</module>
</modules>
<distributionManagement>
@ -285,6 +291,20 @@
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>

22
scripts/deploy-webgoat.sh Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
docker login -u $DOCKER_USER -p $DOCKER_PASS
export REPO=webgoat/webgoat-8.0
cd webgoat-server
ls target/
if [ "${BRANCH}" == "master" ] && [ ! -z "${TRAVIS_TAG}" ]; then
# If we push a tag to master this will update the LATEST Docker image and tag with the version number
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:latest -t $REPO:${TRAVIS_TAG} .
docker push $REPO
elif [ ! -z "${TRAVIS_TAG}" ]; then
# Creating a tag build we push it to Docker with that tag
docker build --build-arg webgoat_version=${TRAVIS_TAG:1} -f Dockerfile -t $REPO:${TRAVIS_TAG} -t $REPO:latest .
docker push $REPO
elif [ "${BRANCH}" == "develop" ]; then
docker build -f Dockerfile -t $REPO:snapshot .
docker push $REPO
else
echo "Skipping releasing to DockerHub because it is a build of branch ${BRANCH}"
fi

View File

@ -1,92 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<groupId>org.owasp.webgoat</groupId>
<name>webgoat-container</name>
<modelVersion>4.0.0</modelVersion>
<artifactId>webgoat-container</artifactId>
<packaging>war</packaging>
<packaging>jar</packaging>
<parent>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-parent</artifactId>
<version>7.1</version>
<version>8.0.0.M3</version>
</parent>
<profiles>
<profile>
<id>run-integration-tests</id>
<activation>
<activeByDefault>false</activeByDefault>
<property>
<name>run-integration</name>
<value>true</value>
</property>
</activation>
<id>performance</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.3-SNAPSHOT</version>
<configuration>
<server>local_tomcat</server>
<url>http://localhost:8080/manager</url>
<path>/WebGoat</path>
<attachArtifactClassifier>exec</attachArtifactClassifier>
<contextReloadable>true</contextReloadable>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
<contextFile>${project.basedir}/src/main/webapp/WEB-INF/context.xml</contextFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-container</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
</execution>
<execution>
<id>tomcat-startup</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run-war-only</goal>
</goals>
<configuration>
<port>8888</port>
<fork>true</fork>
</configuration>
</execution>
<!-- At post-integration-test phase, stop the embedded Tomcat server. -->
<execution>
<id>tomcat-shutdown</id>
<phase>post-integration-test</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<log4j.configuration>file:${project.basedir}/src/test/resources/log4j-silent.properties</log4j.configuration>
</systemPropertyVariables>
</configuration>
<groupId>io.gatling</groupId>
<artifactId>gatling-maven-plugin</artifactId>
<version>${gatling-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
<goal>execute</goal>
</goals>
</execution>
</executions>
@ -94,178 +33,91 @@
</plugins>
</build>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<directory>src/main/java</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<delimiters>
<delimiter>@</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>1.8</source>
<target>1.8</target>
<encoding>ISO-8859-1</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<executions>
<execution>
<id>create-jar</id>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<!-- archiving the classes breaks the admin screen loads in course.java
the legacy lesson loader does not look in jar files for lessons -->
<archiveClasses>false</archiveClasses>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Specification-Title>${project.name}</Specification-Title>
<Specification-Version>${project.version}</Specification-Version>
<Implementation-Version>${build.number}</Implementation-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/webgoat-container-${project.version}.jar</file>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.3-SNAPSHOT</version>
<configuration>
<server>local_tomcat</server>
<url>http://localhost:8080/manager/text</url>
<path>/WebGoat</path>
<attachArtifactClassifier>exec</attachArtifactClassifier>
<contextReloadable>true</contextReloadable>
<useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader>
<contextFile>${project.basedir}/src/main/webapp/WEB-INF/context.xml</contextFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.owasp.webgoat</groupId>
<artifactId>webgoat-container</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<excludes>
<exclude>**/*IT.java</exclude>
</excludes>
<forkMode>never</forkMode>
</configuration>
</plugin>
<!--<plugin>-->
<!--<groupId>com.github.webdriverextensions</groupId>-->
<!--<artifactId>webdriverextensions-maven-plugin</artifactId>-->
<!--<version>3.0.2</version>-->
<!--<executions>-->
<!--<execution>-->
<!--<goals>-->
<!--<goal>install-drivers</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<!--<configuration>-->
<!--<drivers>-->
<!--<driver>-->
<!--<name>chromedriver</name>-->
<!--<platform>windows</platform>-->
<!--<bit>64</bit>-->
<!--</driver>-->
<!--</drivers>-->
<!--<keepDownloadedWebdrivers>true</keepDownloadedWebdrivers>-->
<!--</configuration>-->
<!--</plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>${activation.version}</version>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis</artifactId>
<version>${axis.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-saaj</artifactId>
<version>${axis-saaj.version}</version>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>${axis-jaxrpc.version}</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-ant</artifactId>
<version>${axis-ant.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
@ -273,232 +125,76 @@
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>io.gatling.highcharts</groupId>
<artifactId>gatling-charts-highcharts</artifactId>
<version>${gatling.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>commons-digester</groupId>
<artifactId>commons-digester</artifactId>
<version>${commons-digester.version}</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${jcl-over-slf4j.version}</version>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>${activation.version}</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>${commons-discovery.version}</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>${mail-api.version}</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>${hsqldb.version}</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>${wsdl4j.version}</version>
</dependency>
<dependency>
<groupId>java2html</groupId>
<artifactId>j2h</artifactId>
<version>${j2h.version}</version>
</dependency>
<dependency>
<groupId>ecs</groupId>
<artifactId>ecs</artifactId>
<version>${ecs.version}</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>${javax.transaction-api.version}</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>${jtds.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat-catalina.version}</version>
<scope>provided</scope>
<groupId>org.scala-lang</groupId>
<artifactId>scala-compiler</artifactId>
<version>${scala.version}</version>
<scope>test</scope>
</dependency>
<!-- ************* spring MVC and related dependencies ************** -->
<!-- servlet API -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-core.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
<!-- Spring MVC framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<!-- Apache Commons Upload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<!-- JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>${standard.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
<exclusions>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>${tiles.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
<type>jar</type>
</dependency>
<!-- ************* END spring MVC and related dependencies ************** -->
<!-- ************* START: Dependencies for Unit and Integration Testing ************** -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
<dependency>
<groupId>com.saucelabs</groupId>
<artifactId>sauce_junit</artifactId>
<version>${sauce_junit.version}</version>
<scope>test</scope>
</dependency>
<!--<dependency>-->
<!--<groupId>com.github.webdriverextensions</groupId>-->
<!--<artifactId>webdriverextensions</artifactId>-->
<!--<version>2.8.0</version>-->
<!--</dependency>-->
<!-- ************* END: Dependencies for Unit and Integration Testing ************** -->
<!-- ************* END: <dependencies> ************** -->
</dependencies>
</project>

View File

@ -1,71 +1,58 @@
package org.owasp.webgoat.servlets;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* *************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
* @version $Id: $Id
* @author dm
*/
public class Controller extends HttpServlet {
private static final long serialVersionUID = 1L;
package org.owasp.webgoat;
/** {@inheritDoc} */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
doPost(request, response);
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* <p>AjaxAuthenticationEntryPoint class.</p>
*
* @author zupzup
*/
public class AjaxAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
public AjaxAuthenticationEntryPoint(String loginFormUrl) {
super(loginFormUrl);
}
/** {@inheritDoc} */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
String userAgent = request.getHeader("user-agent");
String clientBrowser = "Not known!";
if (userAgent != null) {
clientBrowser = userAgent;
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
if(request.getHeader("x-requested-with") != null) {
response.sendError(401, authException.getMessage());
} else {
super.commence(request, response, authException);
}
request.setAttribute("client.browser", clientBrowser);
request.getRequestDispatcher("/view.jsp").forward(request, response);
}
}

View File

@ -0,0 +1,127 @@
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author WebGoat
* @version $Id: $Id
* @since December 12, 2015
*/
package org.owasp.webgoat;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.asciidoctor.Asciidoctor;
import org.owasp.webgoat.i18n.Language;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import java.io.*;
import java.util.Map;
import static org.apache.commons.lang3.CharEncoding.UTF_8;
import static org.asciidoctor.Asciidoctor.Factory.create;
/**
* Thymeleaf resolver for AsciiDoc used in the lesson, can be used as follows inside a lesson file:
* <p>
* <code>
* <div th:replace="doc:AccessControlMatrix_plan.adoc"></div>
* </code>
*/
@Slf4j
public class AsciiDoctorTemplateResolver extends TemplateResolver {
private static final Asciidoctor asciidoctor = create();
private static final String PREFIX = "doc:";
private final Language language;
public AsciiDoctorTemplateResolver(Language language) {
this.language = language;
setResourceResolver(new AdocResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
}
@Override
protected String computeResourceName(TemplateProcessingParameters params) {
String templateName = params.getTemplateName();
return templateName.substring(PREFIX.length());
}
private class AdocResourceResolver implements IResourceResolver {
@Override
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
try (InputStream is = readInputStreamOrFallbackToEnglish(resourceName, language)) {
if (is == null) {
log.warn("Resource name: {} not found, did you add the adoc file?", resourceName);
return new ByteArrayInputStream(new byte[0]);
} else {
StringWriter writer = new StringWriter();
asciidoctor.convert(new InputStreamReader(is), writer, createAttributes());
return new ByteArrayInputStream(writer.getBuffer().toString().getBytes(UTF_8));
}
} catch (IOException e) {
//no html yet
return new ByteArrayInputStream(new byte[0]);
}
}
/**
* The resource name is for example HttpBasics_content1.adoc. This is always located in the following directory:
* <code>plugin/HttpBasics/lessonPlans/en/HttpBasics_content1.adoc</code>
*/
private String computeResourceName(String resourceName, String language) {
return String.format("lessonPlans/%s/%s", language, resourceName);
}
private InputStream readInputStreamOrFallbackToEnglish(String resourceName, Language language) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, language.getLocale().getLanguage()));
if (is == null) {
is = Thread.currentThread().getContextClassLoader().getResourceAsStream(computeResourceName(resourceName, "en"));
}
return is;
}
private Map<String, Object> createAttributes() {
Map<String, Object> attributes = Maps.newHashMap();
attributes.put("source-highlighter", "coderay");
attributes.put("backend", "xhtml");
Map<String, Object> options = Maps.newHashMap();
options.put("attributes", attributes);
return options;
}
@Override
public String getName() {
return "adocResourceResolver";
}
}
}

View File

@ -1,120 +0,0 @@
package org.owasp.webgoat;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since March 13, 2007
* @version $Id: $Id
*/
public class Catcher extends HammerHead
{
/**
*
*/
private static final long serialVersionUID = 7441856110845727651L;
/**
* Description of the Field
*/
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
/** Constant <code>END_SOURCE_SKIP="END_OMIT_SOURCE"</code> */
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
/** Constant <code>PROPERTY="PROPERTY"</code> */
public static final String PROPERTY = "PROPERTY";
/** Constant <code>EMPTY_STRING=""</code> */
public static final String EMPTY_STRING = "";
/**
* {@inheritDoc}
*
* Description of the Method
* @exception IOException
* Description of the Exception
* @exception ServletException
* Description of the Exception
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
try
{
// System.out.println( "Entering doPost: " );
// System.out.println( " - request " + request);
// System.out.println( " - principle: " + request.getUserPrincipal() );
// setCacheHeaders(response, 0);
WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION);
session.update(request, response, this.getServletName()); // FIXME: Too much in this
// call.
int scr = session.getCurrentScreen();
Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
log(request, lesson.getClass().getName() + " | " + session.getParser().toString());
String property = new String(session.getParser().getStringParameter(PROPERTY, EMPTY_STRING));
// if the PROPERTY parameter is available - write all the parameters to the
// property file. No other control parameters are supported at this time.
if (!property.equals(EMPTY_STRING))
{
Enumeration<String> e = session.getParser().getParameterNames();
while (e.hasMoreElements())
{
String name = (String) e.nextElement();
String value = session.getParser().getParameterValues(name)[0];
lesson.getLessonTracker(session).getLessonProperties().setProperty(name, value);
}
}
lesson.getLessonTracker(session).store(session, lesson);
// BDM MC
// WEB-173 - removed for testing, as plugin architecture would not allow this
// if ( request.getParameter("Deleter") != null ){org.owasp.webgoat.lessons.BlindScript.StaticDeleter();}
} catch (Throwable t)
{
t.printStackTrace();
log("ERROR: " + t);
}
}
}

View File

@ -0,0 +1,27 @@
package org.owasp.webgoat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.FileSystemUtils;
import javax.annotation.PostConstruct;
import java.io.File;
/**
* @author nbaars
* @since 4/15/17.
*/
@Slf4j
@Configuration
@ConditionalOnExpression("'${webgoat.clean}' == 'true'")
public class CleanupLocalProgressFiles {
@Value("${webgoat.server.directory}")
private String webgoatHome;
@PostConstruct
public void clean() {
}
}

View File

@ -1,442 +1,61 @@
package org.owasp.webgoat;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.WelcomeScreen;
import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.ErrorScreen;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* *************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect
* Security</a>
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @author Jeff Williams
* @author Bruce Mayhew
* @author Nanne Baars
* @version $Id: $Id
* @since October 28, 2003
*/
public class HammerHead extends HttpServlet {
final Logger logger = LoggerFactory.getLogger(HammerHead.class);
@Controller
@AllArgsConstructor
public class HammerHead {
private final Course course;
/**
*
* Entry point for WebGoat, redirects to the first lesson found within the course.
*/
private static final long serialVersionUID = 645640331343188020L;
/**
* Description of the Field
*/
protected static SimpleDateFormat httpDateFormat;
/**
* Set the session timeout to be 2 days
*/
private final static int sessionTimeoutSeconds = 60 * 60 * 24 * 2;
// private final static int sessionTimeoutSeconds = 1;
/**
* Properties file path
*/
public static String propertiesPath = null;
/**
* provides convenience methods for getting setup information from the
* ServletContext
*/
private WebgoatContext webgoatContext = null;
/**
* {@inheritDoc}
*
* Description of the Method
* @exception IOException Description of the Exception
* @exception ServletException Description of the Exception
*/
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doPost(request, response);
}
/**
* {@inheritDoc}
*
* Description of the Method
* @exception IOException Description of the Exception
* @exception ServletException Description of the Exception
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Screen screen = null;
WebSession mySession = null;
try {
logger.debug("Entering doPost");
logger.debug("request: " + request);
logger.debug("principle: " + request.getUserPrincipal());
// setCacheHeaders(response, 0);
ServletContext context = getServletContext();
// FIXME: If a response is written by updateSession(), do not
// call makeScreen() and writeScreen()
mySession = updateSession(request, response, context);
if (response.isCommitted()) {
logger.debug("Response already committed, exiting");
return;
}
if ("true".equals(request.getParameter("start")) || request.getQueryString() == null) {
logger.warn("Redirecting to first lesson");
response.sendRedirect("start.mvc" + mySession.getCourse().getFirstLesson().getLink());
return;
}
// Note: For the lesson to track the status, we need to update
// the lesson tracker object
// from the screen.createContent() method. The create content is
// the only point
// 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
// handleRequest()
if (response.isCommitted()) {
return;
}
// perform lesson-specific tracking activities
if (screen instanceof AbstractLesson) {
AbstractLesson lesson = (AbstractLesson) screen;
// we do not count the initial display of the lesson screen as a visit
if ("GET".equals(request.getMethod())) {
String uri = request.getRequestURI() + "?" + request.getQueryString();
if (!uri.endsWith(lesson.getLink())) {
screen.getLessonTracker(mySession).incrementNumVisits();
}
} else if ("POST".equals(request.getMethod())
&& mySession.getPreviousScreen() == mySession.getCurrentScreen()) {
screen.getLessonTracker(mySession).incrementNumVisits();
}
}
// log the access to this screen for this user
UserTracker userTracker = UserTracker.instance();
userTracker.update(mySession, screen);
log(request, screen.getClass().getName() + " | " + mySession.getParser().toString());
// Redirect the request to our View servlet
String userAgent = request.getHeader("user-agent");
String clientBrowser = "Not known!";
if (userAgent != null) {
clientBrowser = userAgent;
}
request.setAttribute("client.browser", clientBrowser);
// removed - this is being done in updateSession call
//request.getSession().setAttribute(WebSession.SESSION, mySession);
// not sure why this is being set in the session?
//request.getSession().setAttribute(WebSession.COURSE, mySession.getCourse());
String viewPage = getViewPage(mySession);
logger.debug("Forwarding to view: " + viewPage);
logger.debug("Screen: " + screen);
request.getRequestDispatcher(viewPage).forward(request, response);
} catch (Throwable t) {
logger.error("Error handling request", t); screen = new ErrorScreen(mySession, t);
} finally {
try {
if (screen instanceof ErrorScreen) {
this.writeScreen(mySession, screen, response);
}
} catch (Throwable thr) {
logger.error("Could not write error screen", thr);
}
WebSession.returnConnection(mySession);
logger.debug("Leaving doPost: ");
}
}
private String getViewPage(WebSession webSession) {
// now always display the lesson content
String page = "/lesson_content.jsp";
//page = "/main.jsp";
return page;
}
/**
* Description of the Method
*
* @param date Description of the Parameter
* @return RFC 1123 http date format
*/
protected static String formatHttpDate(Date date) {
synchronized (httpDateFormat) {
return httpDateFormat.format(date);
}
}
/**
* {@inheritDoc}
*
* Return information about this servlet
*/
@Override
public String getServletInfo() {
return "WebGoat is sponsored by Aspect Security.";
}
/**
* {@inheritDoc}
*
* Return properties path
*/
@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");
webgoatContext = new WebgoatContext(this);
URL runningStandalone = Thread.currentThread().getContextClassLoader().getResource("standalone.properties");
if (runningStandalone == null) {
logger.info("Browse to http://localhost:8080/WebGoat and happy hacking!");
}
}
/**
* Description of the Method
*
* @param request Description of the Parameter
* @param message Description of the Parameter
*/
public void log(HttpServletRequest request, String message) {
String output = new Date() + " | " + request.getRemoteHost() + ":" + request.getRemoteAddr() + " | " + message;
log(output);
logger.debug(output);
}
/*
* public List getLessons(Category category, String role) { Course course =
* mySession.getCourse(); // May need to clone the List before returning it. //return new
* ArrayList(course.getLessons(category, role)); return course.getLessons(category, role); }
*/
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Screen makeScreen(WebSession s) {
Screen screen = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
if (scr == WebSession.WELCOME) {
screen = new WelcomeScreen(s);
} 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
// admin screens
lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE);
}
if (lesson != null) {
screen = lesson;
// 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
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
} else {
screen = new ErrorScreen(s, "Invalid screen requested. Try: http://localhost/WebGoat/attack");
}
}
} else if (s.isAdmin()) {
if (scr == WebSession.WELCOME) {
screen = new WelcomeAdminScreen(s);
} else {
// 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) {
lesson = course.getLesson(s, scr, AbstractLesson.HACKED_ADMIN_ROLE);
}
if (lesson == null) {
lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
}
if (lesson != null) {
screen = lesson;
// 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
// admin and has actually accessed an admin screen. You
// need BOTH pieces of information
// in order to satisfy the remote admin lesson.
s.setHasHackableAdmin(screen.getRole());
lesson.handleRequest(s);
s.setCurrentMenu(lesson.getCategory().getRanking());
} else {
screen = new ErrorScreen(s,
"Invalid screen requested. Try Setting Admin to false or Try: http://localhost/WebGoat/attack");
}
}
}
return (screen);
}
/**
* This method sets the required expiration headers in the response for a
* given RunData object. This method attempts to set all relevant headers,
* both for HTTP 1.0 and HTTP 1.1.
*
* @param response The new cacheHeaders value
* @param expiry The new cacheHeaders value
*/
protected static void setCacheHeaders(HttpServletResponse response, int expiry) {
if (expiry == 0) {
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Expires", formatHttpDate(new Date()));
} else {
Date expiryDate = new Date(System.currentTimeMillis() + expiry);
response.setHeader("Expires", formatHttpDate(expiryDate));
}
}
/**
* Description of the Method
*
* @param request Description of the Parameter
* @param response Description of the Parameter
* @param context Description of the Parameter
* @return Description of the Return Value
* @throws java.io.IOException if any.
*/
protected WebSession updateSession(HttpServletRequest request, HttpServletResponse response, ServletContext context)
throws IOException {
HttpSession hs;
// session should already be created by spring security
hs = request.getSession(false);
logger.debug("HH Entering Session_id: " + hs.getId());
// dumpSession( hs );
// Get our session object out of the HTTP session
WebSession session = null;
Object o = hs.getAttribute(WebSession.SESSION);
if ((o != null) && o instanceof WebSession) {
session = (WebSession) o;
hs.setAttribute(WebSession.COURSE, session.getCourse());
} else {
// Create new custom session and save it in the HTTP session
logger.warn("HH Creating new WebSession");
session = new WebSession(webgoatContext, context);
// Ensure splash screen shows on any restart
// rlawson - removed this since we show splash screen at login now
//hs.removeAttribute(WELCOMED);
hs.setAttribute(WebSession.SESSION, session);
// reset timeout
hs.setMaxInactiveInterval(sessionTimeoutSeconds);
}
session.update(request, response, this.getServletName());
// update last attack request info (cookies, parms)
// this is so the REST services can have access to them via the session
session.updateLastAttackRequestInfo(request);
// to authenticate
logger.debug("HH Leaving Session_id: " + hs.getId());
//dumpSession( hs );
return (session);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
* @param screen a {@link org.owasp.webgoat.session.Screen} object.
* @param response Description of the Parameter
* @exception IOException Description of the Exception
* @throws java.io.IOException if any.
*/
protected void writeScreen(WebSession s, Screen screen, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (s == null) {
screen = new ErrorScreen(s, "Page to display was null");
}
// set the content-length of the response.
// Trying to avoid chunked-encoding. (Aspect required)
response.setContentLength(screen.getContentLength());
response.setHeader("Content-Length", screen.getContentLength() + "");
screen.output(out);
out.flush();
out.close();
@RequestMapping(path = "/attack", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView attack(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView("redirect:" + "start.mvc" + course.getFirstLesson().getLink());
}
}

View File

@ -1,191 +0,0 @@
package org.owasp.webgoat;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class LessonSource extends HammerHead {
/**
*
*/
private static final long serialVersionUID = 2588430536196446145L;
/**
* Description of the Field
*/
public final static String START_SOURCE_SKIP = "START_OMIT_SOURCE";
/** Constant <code>END_SOURCE_SKIP="END_OMIT_SOURCE"</code> */
public final static String END_SOURCE_SKIP = "END_OMIT_SOURCE";
/**
* {@inheritDoc}
*
* Description of the Method
* @exception IOException Description of the Exception
* @exception ServletException Description of the Exception
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String source = null;
try {
// System.out.println( "Entering doPost: " );
// System.out.println( " - request " + request);
// System.out.println( " - principle: " + request.getUserPrincipal()
// );
// setCacheHeaders(response, 0);
WebSession session = (WebSession) request.getSession(true).getAttribute(WebSession.SESSION);
// FIXME: Too much in this call.
session.update(request, response, this.getServletName());
boolean showSolution = session.getParser().getBooleanParameter("solution", false);
boolean showSource = session.getParser().getBooleanParameter("source", false);
if (showSolution) {
// Get the Java solution of the lesson.
source = getSolution(session);
int scr = session.getCurrentScreen();
Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSolution(true);
} else if (showSource) {
// Get the Java source of the lesson. FIXME: Not needed
source = getSource(session);
int scr = session.getCurrentScreen();
Course course = session.getCourse();
AbstractLesson lesson = course.getLesson(session, scr, AbstractLesson.USER_ROLE);
lesson.getLessonTracker(session).setViewedSource(true);
}
} catch (Throwable t) {
t.printStackTrace();
log("ERROR: " + t);
} finally {
try {
this.writeSource(source, response);
} catch (Throwable thr) {
thr.printStackTrace();
log(request, "Could not write error screen: " + thr.getMessage());
}
// System.out.println( "Leaving doPost: " );
}
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected String getSource(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getSource(s);
}
}
if (source == null) {
return "Source code is not available. Contact "
+ s.getWebgoatContext().getFeedbackAddressHTML();
}
return (source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP,
"Code Section Deliberately Omitted"));
}
/**
* <p>getSolution.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
protected String getSolution(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isChallenge()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getSolution(s);
}
}
if (source == null) {
return "Solution is not available. Contact "
+ s.getWebgoatContext().getFeedbackAddressHTML();
}
return (source);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @param response Description of the Parameter
* @exception IOException Description of the Exception
* @throws java.io.IOException if any.
*/
protected void writeSource(String s, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
if (s == null) {
s = new String();
}
out.print(s);
out.close();
}
}

View File

@ -0,0 +1,94 @@
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @since October 28, 2003
* @version $Id: $Id
*/
package org.owasp.webgoat;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.ByteStreams;
import lombok.SneakyThrows;
import org.springframework.core.io.ResourceLoader;
import org.thymeleaf.TemplateProcessingParameters;
import org.thymeleaf.resourceresolver.IResourceResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.util.Map;
/**
* Dynamically resolve a lesson. In the html file this can be invoked as:
*
* <code>
* <div th:case="true" th:replace="lesson:__${lesson.class.simpleName}__"></div>
* </code>
*
* Thymeleaf will invoke this resolver based on the prefix and this implementation will resolve the html in the plugins directory
*/
public class LessonTemplateResolver extends TemplateResolver {
private final static String PREFIX = "lesson:";
private final File pluginTargetDirectory;
private ResourceLoader resourceLoader;
private Map<String, byte[]> resources = Maps.newHashMap();
public LessonTemplateResolver(File pluginTargetDirectory, ResourceLoader resourceLoader) {
this.pluginTargetDirectory = pluginTargetDirectory;
this.resourceLoader = resourceLoader;
setResourceResolver(new LessonResourceResolver());
setResolvablePatterns(Sets.newHashSet(PREFIX + "*"));
}
@Override
protected String computeResourceName(TemplateProcessingParameters params) {
String templateName = params.getTemplateName();
return templateName.substring(PREFIX.length());
}
private class LessonResourceResolver implements IResourceResolver {
@Override
@SneakyThrows
public InputStream getResourceAsStream(TemplateProcessingParameters params, String resourceName) {
byte[] resource = resources.get(resourceName);
if (resource == null) {
resource = ByteStreams.toByteArray(resourceLoader.getResource("classpath:/html/" + resourceName + ".html").getInputStream());
resources.put(resourceName, resource);
}
return new ByteArrayInputStream(resource);
}
@Override
public String getName() {
return "lessonResourceResolver";
}
}
}

View File

@ -0,0 +1,160 @@
/**
* ************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @version $Id: $Id
* @since October 28, 2003
*/
package org.owasp.webgoat;
import com.google.common.collect.Sets;
import org.owasp.webgoat.i18n.Language;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.LabelDebugger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.templateresolver.TemplateResolver;
import java.io.File;
/**
* Configuration for Spring MVC
*/
@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {
@Autowired
@Qualifier("pluginTargetDirectory")
private File pluginTargetDirectory;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.addViewController("/lesson_content").setViewName("lesson_content");
registry.addViewController("/start.mvc").setViewName("main_new");
registry.addViewController("/scoreboard").setViewName("scoreboard");
//registry.addViewController("/list_users").setViewName("list_users");
}
@Bean
public TemplateResolver springThymeleafTemplateResolver(ApplicationContext applicationContext) {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("classpath:/templates/");
resolver.setSuffix(".html");
resolver.setOrder(1);
resolver.setCacheable(false);
resolver.setApplicationContext(applicationContext);
return resolver;
}
@Bean
public LessonTemplateResolver lessonTemplateResolver(ResourceLoader resourceLoader) {
LessonTemplateResolver resolver = new LessonTemplateResolver(pluginTargetDirectory, resourceLoader);
resolver.setOrder(2);
resolver.setCacheable(false);
return resolver;
}
@Bean
public AsciiDoctorTemplateResolver asciiDoctorTemplateResolver(Language language) {
AsciiDoctorTemplateResolver resolver = new AsciiDoctorTemplateResolver(language);
resolver.setCacheable(false);
resolver.setOrder(3);
return resolver;
}
@Bean
public SpringTemplateEngine thymeleafTemplateEngine(TemplateResolver springThymeleafTemplateResolver,
LessonTemplateResolver lessonTemplateResolver,
AsciiDoctorTemplateResolver asciiDoctorTemplateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect(new SpringSecurityDialect());
engine.setTemplateResolvers(
Sets.newHashSet(springThymeleafTemplateResolver, lessonTemplateResolver, asciiDoctorTemplateResolver));
return engine;
}
/**
* This way we expose the plugins target directory as a resource within the web application.
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/plugin_lessons/**").addResourceLocations("file:///" + pluginTargetDirectory.toString() + "/");
registry.addResourceHandler("/images/**").addResourceLocations("classpath:/images/");
registry.addResourceHandler("/lesson_js/**").addResourceLocations("classpath:/js/");
registry.addResourceHandler("/lesson_css/**").addResourceLocations("classpath:/css/");
registry.addResourceHandler("/video/**").addResourceLocations("classpath:/video/");
super.addResourceHandlers(registry);
}
@Bean
public PluginMessages pluginMessages(Messages messages, Language language) {
PluginMessages pluginMessages = new PluginMessages(messages, language);
pluginMessages.setBasenames("i18n/WebGoatLabels");
return pluginMessages;
}
@Bean
public Language language(LocaleResolver localeResolver) {
return new Language(localeResolver);
}
@Bean
public Messages messageSource(Language language) {
Messages messages = new Messages(language);
messages.setBasename("classpath:i18n/messages");
return messages;
}
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
return slr;
}
@Bean
public LabelDebugger labelDebugger() {
return new LabelDebugger();
}
}

View File

@ -0,0 +1,118 @@
/**
* ************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @version $Id: $Id
* @since October 28, 2003
*/
package org.owasp.webgoat;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Context;
import org.owasp.webgoat.plugins.PluginEndpointPublisher;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.util.Arrays;
@SpringBootApplication
@Slf4j
public class WebGoat extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(WebGoat.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(WebGoat.class, args);
}
@Bean(name = "pluginTargetDirectory")
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
return new File(webgoatHome);
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public WebSession webSession(WebgoatContext webgoatContext) {
return new WebSession(webgoatContext);
}
@Bean
@Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserSessionData userSessionData() {
return new UserSessionData("test", "data");
}
@Bean
public PluginEndpointPublisher pluginEndpointPublisher(ApplicationContext applicationContext) {
return new PluginEndpointPublisher(applicationContext);
}
@Bean
public Course course(PluginEndpointPublisher pluginEndpointPublisher) {
return new PluginsLoader(pluginEndpointPublisher).loadPlugins();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setTomcatContextCustomizers(Arrays.asList(new CustomCustomizer()));
return factory;
}
static class CustomCustomizer implements TomcatContextCustomizer {
@Override
public void customize(Context context) {
context.setUseHttpOnly(false);
}
}
}

View File

@ -0,0 +1,95 @@
/**
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author WebGoat
* @version $Id: $Id
* @since December 12, 2015
*/
package org.owasp.webgoat;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.users.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
/**
* Security configuration for WebGoat.
*/
@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry security = http
.authorizeRequests()
.antMatchers("/css/**", "/images/**", "/js/**", "fonts/**", "/plugins/**", "/registration", "/register.mvc").permitAll()
.antMatchers("/servlet/AdminServlet/**").hasAnyRole("WEBGOAT_ADMIN", "SERVER_ADMIN") //
.antMatchers("/JavaSource/**").hasRole("SERVER_ADMIN") //
.anyRequest().authenticated();
security.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/welcome.mvc", true)
.usernameParameter("username")
.passwordParameter("password")
.permitAll();
security.and()
.logout().deleteCookies("JSESSIONID").invalidateHttpSession(true);
security.and().csrf().disable();
http.headers().cacheControl().disable();
http.exceptionHandling().authenticationEntryPoint(new AjaxAuthenticationEntryPoint("/login"));
}
//// TODO: 11/18/2016 make this a little bit more configurabe last part at least
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/plugin_lessons/**", "/XXE/**");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService); //.passwordEncoder(bCryptPasswordEncoder());
}
@Bean
@Override
public UserDetailsService userDetailsServiceBean() throws Exception {
return userDetailsService;
}
}

View File

@ -1,107 +0,0 @@
/*
* 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.application;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* Singleton which is created on context startup
*
* @author rlawson
* @version $Id: $Id
*/
public class Application {
private static final Application INSTANCE = new Application();
private Application() {
}
/**
* <p>getInstance.</p>
*
* @return a {@link org.owasp.webgoat.application.Application} object.
*/
public static final Application getInstance() {
return INSTANCE;
}
private String version = "SNAPSHOT";
private String build = "local";
private String name = "WebGoat";
/**
* <p>Getter for the field <code>version</code>.</p>
*
* @return the version
*/
public String getVersion() {
return version;
}
/**
* <p>Setter for the field <code>version</code>.</p>
*
* @param version the version to set
*/
public void setVersion(String version) {
if (StringUtils.isNotBlank(version)) {
this.version = version;
}
}
/**
* <p>Getter for the field <code>build</code>.</p>
*
* @return the build
*/
public String getBuild() {
return build;
}
/**
* <p>Setter for the field <code>build</code>.</p>
*
* @param build the build to set
*/
public void setBuild(String build) {
if (StringUtils.isNotBlank(build)) {
this.build = build;
}
}
/**
* <p>Getter for the field <code>name</code>.</p>
*
* @return the name
*/
public String getName() {
return name;
}
/**
* <p>Setter for the field <code>name</code>.</p>
*
* @param name the name to set
*/
public void setName(String name) {
if (StringUtils.isNotBlank(name)) {
this.name = name;
}
}
/** {@inheritDoc} */
@Override
public String toString() {
return new ToStringBuilder(this).
append("name", name).
append("version", version).
append("build", build).
toString();
}
}

View File

@ -1,123 +0,0 @@
/*
* 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.application;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRegistration;
import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.LessonServletMapping;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
/**
* Web application lifecycle listener.
*
* @author rlawson
* @version $Id: $Id
*/
public class WebGoatServletListener implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(HammerHead.class);
/** {@inheritDoc} */
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
context.log("WebGoat is starting");
setApplicationVariables(context);
context.log("Adding extra mappings for lessions");
loadPlugins(sce);
loadServlets(sce);
}
private void loadServlets(ServletContextEvent sce) {
final ServletContext servletContext = sce.getServletContext();
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(
false);
provider.addIncludeFilter(new AnnotationTypeFilter(LessonServletMapping.class));
Set<BeanDefinition> candidateComponents = provider.findCandidateComponents("org.owasp.webgoat");
try {
for (BeanDefinition beanDefinition : candidateComponents) {
Class controllerClass = Class.forName(beanDefinition.getBeanClassName());
LessonServletMapping pathAnnotation = (LessonServletMapping) controllerClass.getAnnotation(LessonServletMapping.class);
final ServletRegistration.Dynamic dynamic = servletContext.addServlet(controllerClass.getSimpleName(), controllerClass);
dynamic.addMapping(pathAnnotation.path());
}
} catch (Exception e) {
logger.error("Error", e);
}
}
private void loadPlugins(ServletContextEvent sce) {
String pluginPath = sce.getServletContext().getRealPath("plugin_lessons");
String targetPath = sce.getServletContext().getRealPath("plugin_extracted");
new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins();
}
/** {@inheritDoc} */
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
context.log("WebGoat is stopping");
// Unregister JDBC drivers in this context's ClassLoader:
// Get the webapp's ClassLoader
ClassLoader cl = Thread.currentThread().getContextClassLoader();
// Loop through all drivers
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
java.sql.Driver driver = drivers.nextElement();
if (driver.getClass().getClassLoader() == cl) {
// This driver was registered by the webapp's ClassLoader, so deregister it:
try {
context.log("Unregister JDBC driver {}");
DriverManager.deregisterDriver(driver);
} catch (SQLException ex) {
context.log("Error unregistering JDBC driver {}");
}
} else {
// driver was not registered by the webapp's ClassLoader and may be in use elsewhere
context.log("Not unregistering JDBC driver {} as it does not belong to this webapp's ClassLoader");
}
}
}
private void setApplicationVariables(ServletContext context) {
Application app = Application.getInstance();
try {
InputStream inputStream = context.getResourceAsStream("/META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(inputStream);
Attributes attr = manifest.getMainAttributes();
String name = attr.getValue("Specification-Title");
String version = attr.getValue("Specification-Version");
String build = attr.getValue("Implementation-Version");
app.setName(name);
app.setVersion(version);
app.setBuild(build);
} catch (IOException ioe) {
context.log("Error setting application variables", ioe);
}
}
}

View File

@ -0,0 +1,115 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.assignments;
import lombok.Getter;
import org.owasp.webgoat.i18n.PluginMessages;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.owasp.webgoat.session.WebSession;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Each lesson can define an endpoint which can support the lesson. So for example if you create a lesson which uses JavaScript and
* needs to call out to the server to fetch data you can define an endpoint in that lesson. WebGoat will pick up this endpoint and
* Spring will publish it.
* </p>
* Extend this class and implement the met
* </p>
* Note: each subclass should declare this annotation otherwise the WebGoat framework cannot find your endpoint.
*/
public abstract class AssignmentEndpoint extends Endpoint {
@Autowired
private UserTrackerRepository userTrackerRepository;
@Autowired
private WebSession webSession;
@Autowired
private UserSessionData userSessionData;
@Getter
@Autowired
private PluginMessages messages;
//// TODO: 11/13/2016 events better fit?
protected AttackResult trackProgress(AttackResult attackResult) {
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
if (userTracker == null) {
userTracker = new UserTracker(webSession.getUserName());
}
if (attackResult.assignmentSolved()) {
userTracker.assignmentSolved(webSession.getCurrentLesson(), this.getClass().getSimpleName());
} else {
userTracker.assignmentFailed(webSession.getCurrentLesson());
}
userTrackerRepository.save(userTracker);
return attackResult;
}
protected WebSession getWebSession() {
return webSession;
}
protected UserSessionData getUserSessionData() {
return userSessionData;
}
@Override
public final String getPath() {
return this.getClass().getAnnotationsByType(AssignmentPath.class)[0].value();
}
/**
* Convenience method for create a successful result:
*
* - Assignment is set to solved
* - Feedback message is set to 'assignment.solved'
*
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
*/
protected AttackResult.AttackResultBuilder success() {
return AttackResult.builder(messages).lessonCompleted(true).feedback("assignment.solved");
}
/**
* Convenience method for create a failed result:
*
* - Assignment is set to not solved
* - Feedback message is set to 'assignment.not.solved'
*
* Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
*/
protected AttackResult.AttackResultBuilder failed() {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved");
}
protected AttackResult.AttackResultBuilder informationMessage() {
return AttackResult.builder(messages).lessonCompleted(false);
}
}

View File

@ -0,0 +1,16 @@
package org.owasp.webgoat.assignments;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by nbaars on 1/14/17.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AssignmentHints {
String[] value() default {};
}

View File

@ -0,0 +1,16 @@
package org.owasp.webgoat.assignments;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by nbaars on 1/14/17.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AssignmentPath {
String value();
}

View File

@ -0,0 +1,104 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.assignments;
import lombok.Getter;
import org.apache.commons.lang3.StringEscapeUtils;
import org.owasp.webgoat.i18n.PluginMessages;
public class AttackResult {
public static class AttackResultBuilder {
private boolean lessonCompleted;
private PluginMessages messages;
private Object[] feedbackArgs;
private String feedbackResourceBundleKey;
private String output;
private Object[] outputArgs;
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
}
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
this.lessonCompleted = lessonCompleted;
this.feedbackResourceBundleKey = "lesson.completed";
return this;
}
public AttackResultBuilder lessonCompleted(boolean lessonCompleted, String resourceBundleKey) {
this.lessonCompleted = lessonCompleted;
this.feedbackResourceBundleKey = resourceBundleKey;
return this;
}
public AttackResultBuilder feedbackArgs(Object... args) {
this.feedbackArgs = args;
return this;
}
public AttackResultBuilder feedback(String resourceBundleKey) {
this.feedbackResourceBundleKey = resourceBundleKey;
return this;
}
public AttackResultBuilder output(String output) {
this.output = output;
return this;
}
public AttackResultBuilder outputArgs(Object... args) {
this.outputArgs = args;
return this;
}
public AttackResult build() {
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs));
}
}
@Getter
private boolean lessonCompleted;
@Getter
private String feedback;
@Getter
private String output;
public AttackResult(boolean lessonCompleted, String feedback, String output) {
this.lessonCompleted = lessonCompleted;
this.feedback = StringEscapeUtils.escapeJson(feedback);
this.output = StringEscapeUtils.escapeJson(output);
}
public static AttackResultBuilder builder(PluginMessages messages) {
return new AttackResultBuilder(messages);
}
public boolean assignmentSolved() {
return lessonCompleted;
}
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.assignments;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
public abstract class Endpoint implements MvcEndpoint {
@Override
public final boolean isSensitive() {
return false;
}
@Override
public final Class<? extends org.springframework.boot.actuate.endpoint.Endpoint> getEndpointType() {
return null;
}
}

View File

@ -1,59 +0,0 @@
/*
* 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;
/**
* <p>About class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class About {
final Logger logger = LoggerFactory.getLogger(About.class);
private static final String WELCOMED = "welcomed";
/**
* <p>welcome.</p>
*
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @param error a {@link java.lang.String} object.
* @param logout a {@link java.lang.String} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@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

@ -1,48 +0,0 @@
/*
* 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 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;
/**
* <p>Login class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class Login {
/**
* <p>login.</p>
*
* @param error a {@link java.lang.String} object.
* @param logout a {@link java.lang.String} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "login.mvc", method = RequestMethod.GET)
public ModelAndView login(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("login");
return model;
}
}

View File

@ -1,54 +0,0 @@
/*
* 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 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;
/**
* <p>Logout class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class Logout {
final Logger logger = LoggerFactory.getLogger(Logout.class);
/**
* <p>logout.</p>
*
* @param error a {@link java.lang.String} object.
* @param logout a {@link java.lang.String} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "logout.mvc", method = RequestMethod.GET)
public ModelAndView logout(
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
logger.info("Logging user out");
ModelAndView model = new ModelAndView();
if (error != null) {
model.addObject("error", "Invalid username and password!");
}
if (logout != null) {
model.addObject("msg", "You've been logged out successfully.");
}
model.setViewName("logout");
return model;
}
}

View File

@ -1,113 +0,0 @@
/*
* 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 java.util.Collection;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.application.Application;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
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;
/**
* <p>Start class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class Start {
final Logger logger = LoggerFactory.getLogger(Start.class);
private static final String WELCOMED = "welcomed";
@Autowired
private ServletContext servletContext;
/**
* <p>start.</p>
*
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @param error a {@link java.lang.String} object.
* @param logout a {@link java.lang.String} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "start.mvc", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView start(HttpServletRequest request,
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
ModelAndView model = new ModelAndView();
// make sure session is set up correctly
// if not redirect user to login
if (checkWebSession(request.getSession()) == false) {
model.setViewName("redirect:/login.mvc");
return model;
}
String role = getRole();
String user = request.getUserPrincipal().getName();
model.addObject("role", role);
model.addObject("user", user);
String contactEmail = servletContext.getInitParameter("email");
model.addObject("contactEmail", contactEmail);
String emailList = servletContext.getInitParameter("emaillist");
model.addObject("emailList", emailList);
Application app = Application.getInstance();
logger.info("Setting application properties: " + app);
model.addObject("version", app.getVersion());
model.addObject("build", app.getBuild());
// if everything ok then go to webgoat UI
model.setViewName("main_new");
return model;
}
private String getRole() {
Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) SecurityContextHolder.getContext().getAuthentication().getAuthorities();
String role = "N/A";
for (GrantedAuthority authority : authorities) {
authority.getAuthority();
role = authority.getAuthority();
role = StringUtils.lowerCase(role);
role = StringUtils.remove(role, "role_");
break;
}
return role;
}
/**
* <p>checkWebSession.</p>
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a boolean.
*/
public boolean checkWebSession(HttpSession session) {
Object o = session.getAttribute(WebSession.SESSION);
if (o == null) {
logger.error("No valid WebSession object found, has session timed out? [" + session.getId() + "]");
return false;
}
if (!(o instanceof WebSession)) {
logger.error("Invalid WebSession object found, this is probably a bug! [" + o.getClass() + " | " + session.getId() + "]");
return false;
}
return true;
}
}

View File

@ -0,0 +1,92 @@
/**
* ************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @version $Id: $Id
* @since October 28, 2003
*/
package org.owasp.webgoat.controller;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;
@Controller
public class StartLesson {
private final WebSession ws;
private final Course course;
public StartLesson(final WebSession ws, final Course course) {
this.ws = ws;
this.course = course;
}
/**
* <p>start.</p>
*
* @return a {@link ModelAndView} object.
*/
@RequestMapping(path = "startlesson.mvc", method = {RequestMethod.GET, RequestMethod.POST})
public ModelAndView start() {
ModelAndView model = new ModelAndView();
model.addObject("course", course);
model.addObject("lesson", ws.getCurrentLesson());
model.setViewName("lesson_content");
return model;
}
@RequestMapping(value = {"*.lesson"}, produces = "text/html")
public ModelAndView lessonPage(HttpServletRequest request) {
// I will set here the thymeleaf fragment location based on the resource requested.
ModelAndView model = new ModelAndView();
SecurityContext context = SecurityContextHolder.getContext(); //TODO this should work with the security roles of Spring
//GrantedAuthority authority = context.getAuthentication().getAuthorities().iterator().next();
String path = request.getRequestURL().toString(); // we now got /a/b/c/AccessControlMatrix.lesson
String lessonName = path.substring(path.lastIndexOf('/') + 1, path.indexOf(".lesson"));
List<AbstractLesson> lessons = course.getLessons();
Optional<AbstractLesson> lesson = lessons.stream()
.filter(l -> l.getId().equals(lessonName))
.findFirst();
ws.setCurrentLesson(lesson.get());
model.setViewName("lesson_content");
model.addObject("lesson", lesson.get());
return model;
}
}

View File

@ -1,20 +1,43 @@
/*
* 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.
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author WebGoat
* @since October 28, 2003
* @version $Id: $Id
*/
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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* <p>Welcome class.</p>
*
@ -24,21 +47,16 @@ import org.springframework.web.servlet.ModelAndView;
@Controller
public class Welcome {
final Logger logger = LoggerFactory.getLogger(Welcome.class);
private static final String WELCOMED = "welcomed";
/**
* <p>welcome.</p>
*
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @param error a {@link java.lang.String} object.
* @param logout a {@link java.lang.String} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "welcome.mvc", method = RequestMethod.GET)
public ModelAndView welcome(HttpServletRequest request,
@RequestParam(value = "error", required = false) String error,
@RequestParam(value = "logout", required = false) String logout) {
@RequestMapping(path = {"welcome.mvc", "/"}, method = RequestMethod.GET)
public ModelAndView welcome(HttpServletRequest request) {
// set the welcome attribute
// this is so the attack servlet does not also

View File

@ -0,0 +1,51 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.i18n;
import lombok.AllArgsConstructor;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.LocaleResolver;
import java.util.Locale;
/**
* Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the HttpRequest object
* when asking for a Locale.
*
* @author nbaars
* @date 2/7/17
*/
@AllArgsConstructor
public class Language {
private final LocaleResolver localeResolver;
public Locale getLocale() {
return localeResolver.resolveLocale(((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest());
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.i18n;
import lombok.AllArgsConstructor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import java.util.Properties;
/**
* <p>ExposedReloadableResourceMessageBundleSource class.</p>
* Extends the reloadable message source with a way to get all messages
*
* @author zupzup
*/
@AllArgsConstructor
public class Messages extends ReloadableResourceBundleMessageSource {
private final Language language;
/**
* Gets all messages for presented Locale.
*
* @return all messages
*/
public Properties getMessages() {
return getMergedProperties(language.getLocale()).getProperties();
}
public String getMessage(String code, Object... args) {
return getMessage(code, args, language.getLocale());
}
public String getMessage(String code, String defaultValue, Object... args) {
return super.getMessage(code, args, defaultValue, language.getLocale());
}
}

View File

@ -0,0 +1,80 @@
/*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 2017 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*/
package org.owasp.webgoat.i18n;
import lombok.SneakyThrows;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import java.net.URL;
import java.util.Enumeration;
import java.util.Properties;
/**
* Message resource bundle for plugins.
*
* @author nbaars
* @date 2/4/17
*/
public class PluginMessages extends ReloadableResourceBundleMessageSource {
private static final String PROPERTIES_SUFFIX = ".properties";
private Language language;
public PluginMessages(Messages messages, Language language) {
this.language = language;
this.setParentMessageSource(messages);
this.setBasename("WebGoatLabels");
}
@Override
@SneakyThrows
protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
Properties properties = new Properties();
long lastModified = System.currentTimeMillis();
Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources(filename + PROPERTIES_SUFFIX);
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
String sourcePath = resource.toURI().toString().replace(PROPERTIES_SUFFIX, "");
PropertiesHolder holder = super.refreshProperties(sourcePath, propHolder);
properties.putAll(holder.getProperties());
}
return new PropertiesHolder(properties, lastModified);
}
public Properties getMessages() {
return getMergedProperties(language.getLocale()).getProperties();
}
public String getMessage(String code, Object... args) {
return getMessage(code, args, language.getLocale());
}
public String getMessage(String code, String defaultValue, Object... args) {
return super.getMessage(code, args, defaultValue, language.getLocale());
}
}

View File

@ -1,45 +1,15 @@
package org.owasp.webgoat.lessons;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.Body;
import org.apache.ecs.html.Form;
import org.apache.ecs.html.Head;
import org.apache.ecs.html.Html;
import org.apache.ecs.html.IMG;
import org.apache.ecs.html.PRE;
import org.apache.ecs.html.Title;
import org.owasp.webgoat.session.ParameterNotFoundException;
import com.google.common.collect.Lists;
import lombok.Setter;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.session.WebgoatProperties;
import org.owasp.webgoat.util.BeanProvider;
import org.owasp.webgoat.util.LabelManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import static java.lang.Math.abs;
/**
* ************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
@ -68,66 +38,30 @@ import static java.lang.Math.abs;
*/
public abstract class AbstractLesson extends Screen implements Comparable<Object> {
private static final Logger logger = LoggerFactory.getLogger(AbstractLesson.class);
/**
* Description of the Field
*/
public final static String ADMIN_ROLE = "admin";
/**
* Constant <code>CHALLENGE_ROLE="challenge"</code>
*/
public final static String CHALLENGE_ROLE = "challenge";
/**
* Description of the Field
*/
public final static String HACKED_ADMIN_ROLE = "hacked_admin";
/**
* Description of the Field
*/
public final static String USER_ROLE = "user";
private static int count = 1;
private Integer id = null;
final static IMG nextGrey = new IMG("images/right16.gif").setAlt("Next").setBorder(0).setHspace(0).setVspace(0);
final static IMG previousGrey = new IMG("images/left14.gif").setAlt("Previous").setBorder(0).setHspace(0)
.setVspace(0);
private Integer ranking;
private Category category;
@Setter
private List<Assignment> assignments;
private boolean hidden;
private String sourceFileName;
private Map<String, String> lessonPlanFileName = new HashMap<String, String>();
private String lessonSolutionFileName;
private WebgoatContext webgoatContext;
private LinkedList<String> availableLanguages = new LinkedList<String>();
private String defaultLanguage = "en";
private LabelManager labelManager = null;
public List<Assignment> getAssignments() {
if (assignments == null) {
return Lists.newArrayList();
}
return assignments;
}
/**
* Constructor for the Lesson object
*/
public AbstractLesson() {
//based on the class name derive an id so the screenId is fixed, should not give clashes based on
//the fact we use the classname and the size is limited
id = abs(this.getClass().getSimpleName().hashCode());
id = new Integer(++count);
}
/**
* <p>getName.</p>
*
@ -147,46 +81,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
this.ranking = ranking;
}
/**
* <p>Setter for the field <code>hidden</code>.</p>
*
* @param hidden a boolean.
*/
public void setHidden(boolean hidden) {
this.hidden = hidden;
}
/**
* <p>update.</p>
*
* @param properties a {@link org.owasp.webgoat.session.WebgoatProperties} object.
*/
public void update(WebgoatProperties properties) {
String className = getClass().getName();
className = className.substring(className.lastIndexOf(".") + 1);
setRanking(new Integer(properties.getIntProperty("lesson." + className + ".ranking", getDefaultRanking()
.intValue())));
String categoryRankingKey = "category." + getDefaultCategory().getName() + ".ranking";
// System.out.println("Category ranking key: " + categoryRankingKey);
Category tempCategory = Category.getCategory(getDefaultCategory().getName());
tempCategory.setRanking(new Integer(properties.getIntProperty(categoryRankingKey, getDefaultCategory()
.getRanking().intValue())));
category = tempCategory;
setHidden(properties.getBooleanProperty("lesson." + className + ".hidden", getDefaultHidden()));
// System.out.println(className + " in " + tempCategory.getName() + "
// (Category Ranking: " + tempCategory.getRanking() + " Lesson ranking:
// " + getRanking() + ", hidden:" + hidden +")");
}
/**
* <p>isCompleted.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a boolean.
*/
public boolean isCompleted(WebSession s) {
return getLessonTracker(s, this).getCompleted();
}
/**
* {@inheritDoc}
@ -212,7 +106,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
* @return The category value
*/
public Category getCategory() {
return category;
return getDefaultCategory();
}
/**
@ -236,183 +130,21 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*/
protected abstract boolean getDefaultHidden();
/**
* <p>getSubmitMethod</p>
*
* @return a {@link java.lang.String} object.
*/
public abstract String getSubmitMethod();
/**
* Gets the fileMethod attribute of the Lesson class
*
* @param reader Description of the Parameter
* @param methodName Description of the Parameter
* @param numbers Description of the Parameter
* @return The fileMethod value
*/
public static String getFileMethod(BufferedReader reader, String methodName, boolean numbers) {
int count = 0;
StringBuffer sb = new StringBuffer();
boolean echo = false;
boolean startCount = false;
int parenCount = 0;
try {
String line;
while ((line = reader.readLine()) != null) {
if ((line.indexOf(methodName) != -1)
&& ((line.indexOf("public") != -1) || (line.indexOf("protected") != -1) || (line
.indexOf("private") != -1))) {
echo = true;
startCount = true;
}
if (echo && startCount) {
if (numbers) {
sb.append(pad(++count) + " ");
}
sb.append(line + "\n");
}
if (echo && (line.indexOf("{") != -1)) {
parenCount++;
}
if (echo && (line.indexOf("}") != -1)) {
parenCount--;
if (parenCount == 0) {
startCount = false;
echo = false;
}
}
}
reader.close();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
return (sb.toString());
}
/**
* Reads text from a file into an ElementContainer. Each line in the file is
* represented in the ElementContainer by a StringElement. Each
* StringElement is appended with a new-line character.
*
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @return Description of the Return Value
*/
public static String readFromFile(BufferedReader reader, boolean numbers) {
return (getFileText(reader, numbers));
}
/**
* Gets the fileText attribute of the Screen class
*
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @return The fileText value
*/
public static String getFileText(BufferedReader reader, boolean numbers) {
int count = 0;
StringBuffer sb = new StringBuffer();
try {
String line;
while ((line = reader.readLine()) != null) {
if (numbers) {
sb.append(pad(++count) + " ");
}
sb.append(line + System.getProperty("line.separator"));
}
reader.close();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
return (sb.toString());
}
/**
* Will this screen be included in an enterprise edition.
*
* @return The ranking value
*/
public boolean isEnterprise() {
return false;
}
/**
* Gets the hintCount attribute of the Lesson object
*
* @param s The user's WebSession
* @return The hintCount value
*/
public int getHintCount(WebSession s) {
return getHints(s).size();
public int getHintCount() {
return getHints().size();
}
/**
* <p>getHints.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.util.List} object.
*/
protected abstract List<String> getHints(WebSession s);
// @TODO we need to restrict access at the service layer
// rather than passing session object around
/**
* <p>getHintsPublic.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.util.List} object.
*/
public List<String> getHintsPublic(WebSession s) {
List<String> hints = getHints(s);
return hints;
}
/**
* Fill in a minor hint that will help people who basically get it, but are
* stuck on somthing silly.
*
* @param s The users WebSession
* @param hintNumber a int.
* @return The hint1 value
*/
public String getHint(WebSession s, int hintNumber) {
return "Hint: " + getHints(s).get(hintNumber);
}
/**
* Gets the instructions attribute of the AbstractLesson object
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return The instructions value
*/
public abstract String getInstructions(WebSession s);
/**
* Gets the lessonPlan attribute of the Lesson object
*
* @return The lessonPlan value
*/
public String getLessonName() {
return this.getClass().getSimpleName();
}
public abstract List<String> getHints();
/**
* Gets the title attribute of the HelloScreen object
@ -421,36 +153,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
*/
public abstract String getTitle();
/**
* Gets the content of lessonPlanURL
*
* @param s The user's WebSession
* @return The HTML content of the current lesson plan
*/
public String getLessonPlan(WebSession s) {
StringBuffer src = new StringBuffer();
String lang = s.getCurrrentLanguage();
try {
// System.out.println("Loading lesson plan file: " +
// getLessonPlanFileName());
String filename = getLessonPlanFileName(lang);
if (filename == null) {
filename = getLessonPlanFileName(getDefaultLanguage());
}
src.append(readFromFile(new BufferedReader(new FileReader(filename)), false));
} catch (Exception e) {
// s.setMessage( "Could not find lesson plan for " +
// getLessonName());
src = new StringBuffer("Could not find lesson plan for: " + getLessonName() + " and language " + lang);
}
return src.toString();
}
/**
* Gets the ranking attribute of the Lesson object
*
@ -464,33 +166,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
}
}
/**
* Gets the hidden value of the Lesson Object
*
* @return The hidden value
*/
public boolean getHidden() {
return this.hidden;
}
/**
* Gets the role attribute of the AbstractLesson object
*
* @return The role value
*/
public String getRole() {
// FIXME: Each lesson should have a role assigned to it. Each
// user/student
// should also have a role(s) assigned. The user would only be allowed
// to see lessons that correspond to their role. Eventually these roles
// will be stored in the internal database. The user will be able to
// hack
// into the database and change their role. This will allow the user to
// see the admin screens, once they figure out how to turn the admin
// switch on.
return USER_ROLE;
}
/**
* Gets the uniqueID attribute of the AbstractLesson object
*
@ -500,126 +175,10 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return id.intValue();
}
/**
* <p>getHtml_DELETE_ME.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getHtml_DELETE_ME(WebSession s) {
String html = null;
// FIXME: This doesn't work for the labs since they do not implement
// createContent().
String rawHtml = createContent(s).toString();
// System.out.println("Getting raw html content: " +
// rawHtml.substring(0, Math.min(rawHtml.length(), 100)));
html = convertMetachars(AbstractLesson.readFromFile(new BufferedReader(new StringReader(rawHtml)), true));
// System.out.println("Getting encoded html content: " +
// html.substring(0, Math.min(html.length(), 100)));
return html;
}
/**
* <p>getSource.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getSource(WebSession s) {
String source = null;
String src = null;
try {
// System.out.println("Loading source file: " +
// getSourceFileName());
src = convertMetacharsJavaCode(readFromFile(new BufferedReader(new FileReader(getSourceFileName())), true));
// TODO: For styled line numbers and better memory efficiency,
// use a custom FilterReader
// that performs the convertMetacharsJavaCode() transform plus
// optionally adds a styled
// line number. Wouldn't color syntax be great too?
} catch (Exception e) {
s.setMessage("Could not find source file");
src = ("Could not find the source file or source file does not exist.<br/>"
+ "Send this message to: <a href=\"mailto:" + s.getWebgoatContext().getFeedbackAddress()
+ "?subject=Source " + getSourceFileName() + " not found. Lesson: "
+ s.getCurrentLesson().getLessonName() + "\">" + s.getWebgoatContext()
.getFeedbackAddress() + "</a>");
}
Html html = new Html();
Head head = new Head();
head.addElement(new Title(getSourceFileName()));
Body body = new Body();
body.addElement(new StringElement(src));
html.addElement(head);
html.addElement(body);
source = html.toString();
return source;
}
/**
* <p>getRawSource.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getRawSource(WebSession s) {
String src;
try {
logger.debug("Loading source file: " + getSourceFileName());
src = readFromFile(new BufferedReader(new FileReader(getSourceFileName())), false);
} catch (FileNotFoundException e) {
s.setMessage("Could not find source file");
src = ("Could not find the source file or source file does not exist.<br/>"
+ "Send this message to: <a href=\"mailto:" + s.getWebgoatContext().getFeedbackAddress()
+ "?subject=Source " + getSourceFileName() + " not found. Lesson: "
+ s.getCurrentLesson().getLessonName() + "\">" + s.getWebgoatContext()
.getFeedbackAddress() + "</a>");
}
return src;
}
/**
* <p>getSolution.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getSolution(WebSession s) {
String src = null;
try {
// System.out.println("Solution: " + getLessonSolutionFileName());
src = readFromFile(new BufferedReader(new FileReader(getLessonSolutionFileName())), false);
} catch (Exception e) {
logger.error("Could not find solution for {}", getLessonSolutionFileName());
s.setMessage("Could not find the solution file");
src = ("Could not find the solution file or solution file does not exist.<br/>"
+ "Send this message to: <a href=\"mailto:" + s.getWebgoatContext().getFeedbackAddress()
+ "?subject=Solution " + getLessonSolutionFileName() + " not found. Lesson: "
+ s.getCurrentLesson().getLessonName() + "\">" + s.getWebgoatContext()
.getFeedbackAddress() + "</a>");
}
// Solutions are html files
return src;
}
/**
* <p>Returns the default "path" portion of a lesson's URL.</p>
* <p>
* <p>
* Legacy webgoat lesson links are of the form
* "attack?Screen=Xmenu=Ystage=Z". This method returns the path portion of
* the url, i.e., "attack" in the string above.
@ -630,7 +189,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
* @return a {@link java.lang.String} object.
*/
protected String getPath() {
return "#attack";
return "#lesson/";
}
/**
@ -646,242 +205,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
* @return a {@link java.lang.String} object.
*/
public String getLink() {
StringBuffer link = new StringBuffer(getPath());
// mvc update:
return link
.append("/").append(getScreenId())
.append("/").append(getCategory().getRanking()).toString();
}
/**
* Get the link to the target servlet.
* <p>
* Unlike getLink() this method does not require rendering the output of
* the request to the link in order to execute the servlet's method with
* conventional HTTP query parameters.
*
* @return a {@link java.lang.String} object.
*/
public String getServletLink() {
StringBuffer link = new StringBuffer("attack");
return link
.append("?Screen=").append(getScreenId())
.append("&menu=").append(getCategory().getRanking()).toString();
}
/**
* Get the link to the jsp page used to render this screen.
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getPage(WebSession s) {
return null;
}
/**
* Get the link to the jsp template page used to render this screen.
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getTemplatePage(WebSession s) {
return null;
}
/**
* <p>getCurrentAction.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public abstract String getCurrentAction(WebSession s);
/**
* Initiates lesson restart functionality
*/
public abstract void restartLesson();
/**
* <p>setCurrentAction.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param lessonScreen a {@link java.lang.String} object.
*/
public abstract void setCurrentAction(WebSession s, String lessonScreen);
/**
* Override this method to implement accesss control in a lesson.
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param functionId a {@link java.lang.String} object.
* @param employeeId a int.
* @return a boolean.
*/
public boolean isAuthorized(WebSession s, int employeeId, String functionId) {
return false;
}
/**
* Override this method to implement accesss control in a lesson.
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param functionId a {@link java.lang.String} object.
* @param role a {@link java.lang.String} object.
* @return a boolean.
*/
public boolean isAuthorized(WebSession s, String role, String functionId) {
logger.info("Checking if " + role + " authorized for: " + functionId);
boolean authorized = false;
try {
String query = "SELECT * FROM auth WHERE role = '" + role + "' and functionid = '" + functionId + "'";
try {
Statement answer_statement = WebSession.getConnection(s)
.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet answer_results = answer_statement.executeQuery(query);
authorized = answer_results.first();
logger.info("authorized: " + authorized);
} catch (SQLException sqle) {
s.setMessage("Error authorizing");
logger.error("Error authorizing", sqle);
}
} catch (Exception e) {
s.setMessage("Error authorizing");
logger.error("Error authorizing", e);
}
return authorized;
}
/**
* <p>getUserId.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a int.
* @throws org.owasp.webgoat.session.ParameterNotFoundException if any.
*/
public int getUserId(WebSession s) throws ParameterNotFoundException {
return -1;
}
/**
* <p>getUserName.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
* @throws org.owasp.webgoat.session.ParameterNotFoundException if any.
*/
public String getUserName(WebSession s) throws ParameterNotFoundException {
return null;
}
/**
* Description of the Method
*
* @param windowName Description of the Parameter
* @return Description of the Return Value
*/
public static String makeWindowScript(String windowName) {
// FIXME: make this string static
StringBuffer script = new StringBuffer();
script.append("<script language=\"JavaScript\">\n");
script.append(" <!--\n");
script.append(" function makeWindow(url) {\n");
script.append("\n");
script.append(" agent = navigator.userAgent;\n");
script.append("\n");
script.append(" params = \"\";\n");
script.append(" params += \"toolbar=0,\";\n");
script.append(" params += \"location=0,\";\n");
script.append(" params += \"directories=0,\";\n");
script.append(" params += \"status=0,\";\n");
script.append(" params += \"menubar=0,\";\n");
script.append(" params += \"scrollbars=1,\";\n");
script.append(" params += \"resizable=1,\";\n");
script.append(" params += \"width=500,\";\n");
script.append(" params += \"height=350\";\n");
script.append("\n");
script.append(" // close the window to vary the window size\n");
script.append(" if (typeof(win) == \"object\" && !win.closed){\n");
script.append(" win.close();\n");
script.append(" }\n");
script.append("\n");
script.append(" win = window.open(url, '" + windowName + "' , params);\n");
script.append("\n");
script.append(" // bring the window to the front\n");
script.append(" win.focus();\n");
script.append(" }\n");
script.append(" //-->\n");
script.append(" </script>\n");
return script.toString();
}
/**
* Simply reads a url into an Element for display. CAUTION: you might want
* to tinker with any non-https links (href)
*
* @param url Description of the Parameter
* @return Description of the Return Value
*/
public static Element readFromURL(String url) {
ElementContainer ec = new ElementContainer();
try {
URL u = new URL(url);
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(huc.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
ec.addElement(new StringElement(line));
}
reader.close();
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
return (ec);
}
/**
* Description of the Method
*
* @param reader Description of the Parameter
* @param numbers Description of the Parameter
* @param methodName Description of the Parameter
* @return Description of the Return Value
*/
public static Element readMethodFromFile(BufferedReader reader, String methodName, boolean numbers) {
PRE pre = new PRE().addElement(getFileMethod(reader, methodName, numbers));
return (pre);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
*/
public void handleRequest(WebSession s) {
// call createContent first so messages will go somewhere
Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType("");
form.addElement(createContent(s));
setContent(form);
s.getRequest().getRequestURL();
}
/**
* <p>getFormAction.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getFormAction() {
return getLink();
return String.format("%s%s.lesson", getPath(), getId());
}
/**
@ -893,115 +217,6 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object
return getTitle();
}
/**
* <p>Getter for the field <code>defaultLanguage</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getDefaultLanguage() {
return this.defaultLanguage;
}
/**
* <p>Getter for the field <code>lessonPlanFileName</code>.</p>
*
* @param lang a {@link java.lang.String} object.
* @return a {@link java.lang.String} object.
*/
public String getLessonPlanFileName(String lang) {
String ret = lessonPlanFileName.get(lang);
if (ret == null) {
ret = lessonPlanFileName.get(getDefaultLanguage());
}
return ret;
}
/**
* <p>Setter for the field <code>lessonPlanFileName</code>.</p>
*
* @param lang a {@link java.lang.String} object.
* @param lessonPlanFileName a {@link java.lang.String} object.
*/
public void setLessonPlanFileName(String lang, String lessonPlanFileName) {
this.lessonPlanFileName.put(lang, lessonPlanFileName);
this.availableLanguages.add(lang);
}
/**
* <p>Getter for the field <code>availableLanguages</code>.</p>
*
* @return a {@link java.util.List} object.
*/
public List<String> getAvailableLanguages() {
return this.availableLanguages;
}
/**
* <p>Getter for the field <code>lessonSolutionFileName</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getLessonSolutionFileName() {
return lessonSolutionFileName;
}
/**
* <p>Setter for the field <code>lessonSolutionFileName</code>.</p>
*
* @param lessonSolutionFileName a {@link java.lang.String} object.
*/
public void setLessonSolutionFileName(String lessonSolutionFileName) {
this.lessonSolutionFileName = lessonSolutionFileName;
}
/**
* <p>Getter for the field <code>sourceFileName</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getSourceFileName() {
return sourceFileName;
}
/**
* <p>Setter for the field <code>sourceFileName</code>.</p>
*
* @param sourceFileName a {@link java.lang.String} object.
*/
public void setSourceFileName(String sourceFileName) {
logger.debug("Setting source file of lesson " + this + " to: " + sourceFileName);
this.sourceFileName = sourceFileName;
}
/**
* <p>Getter for the field <code>webgoatContext</code>.</p>
*
* @return a {@link org.owasp.webgoat.session.WebgoatContext} object.
*/
public WebgoatContext getWebgoatContext() {
return webgoatContext;
}
/**
* <p>Setter for the field <code>webgoatContext</code>.</p>
*
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
*/
public void setWebgoatContext(WebgoatContext webgoatContext) {
this.webgoatContext = webgoatContext;
}
/**
* <p>Getter for the field <code>labelManager</code>.</p>
*
* @return a {@link org.owasp.webgoat.util.LabelManager} object.
*/
protected LabelManager getLabelManager() {
if (labelManager == null) {
labelManager = BeanProvider.getBean("labelManager", LabelManager.class);
}
return labelManager;
}
public abstract String getId();
}

View File

@ -0,0 +1,55 @@
package org.owasp.webgoat.lessons;
import lombok.*;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Transient;
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/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @since November 25, 2016
*/
@AllArgsConstructor
@RequiredArgsConstructor
@NoArgsConstructor
@Getter
@EqualsAndHashCode
@Entity
public class Assignment {
@NonNull
@Id
private String name;
@NonNull
private String path;
@Transient
private List<String> hints;
}

View File

@ -1,220 +1,79 @@
package org.owasp.webgoat.lessons;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import lombok.Getter;
/**
* *************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
* @since October 28, 2003
*/
public class Category implements Comparable {
public enum Category {
/** Constant <code>INTRODUCTION</code> */
public final static Category INTRODUCTION = new Category("Introduction", new Integer(5));
/** Constant <code>GENERAL</code> */
public final static Category GENERAL = new Category("General", new Integer(100));
/** Constant <code>ACCESS_CONTROL</code> */
public final static Category ACCESS_CONTROL = new Category("Access Control Flaws", new Integer(200));
/** Constant <code>AJAX_SECURITY</code> */
public final static Category AJAX_SECURITY = new Category("AJAX Security", new Integer(400));
/** Constant <code>AUTHENTICATION</code> */
public final static Category AUTHENTICATION = new Category("Authentication Flaws", new Integer(500));
/** Constant <code>BUFFER_OVERFLOW</code> */
public final static Category BUFFER_OVERFLOW = new Category("Buffer Overflows", new Integer(600));
/** Constant <code>CODE_QUALITY</code> */
public final static Category CODE_QUALITY = new Category("Code Quality", new Integer(700));
/** Constant <code>CONCURRENCY</code> */
public final static Category CONCURRENCY = new Category("Concurrency", new Integer(800));
/** Constant <code>XSS</code> */
public final static Category XSS = new Category("Cross-Site Scripting (XSS)", new Integer(900));
/** Constant <code>ERROR_HANDLING</code> */
public final static Category ERROR_HANDLING = new Category("Improper Error Handling", new Integer(1000));
/** Constant <code>INJECTION</code> */
public final static Category INJECTION = new Category("Injection Flaws", new Integer(1100));
/** Constant <code>DOS</code> */
public final static Category DOS = new Category("Denial of Service", new Integer(1200));
/** Constant <code>INSECURE_COMMUNICATION</code> */
public final static Category INSECURE_COMMUNICATION = new Category("Insecure Communication", new Integer(1300));
/** Constant <code>INSECURE_CONFIGURATION</code> */
public final static Category INSECURE_CONFIGURATION = new Category("Insecure Configuration", new Integer(1400));
/** Constant <code>INSECURE_STORAGE</code> */
public final static Category INSECURE_STORAGE = new Category("Insecure Storage", new Integer(1500));
/** Constant <code>MALICIOUS_EXECUTION</code> */
public final static Category MALICIOUS_EXECUTION = new Category("Malicious Execution", new Integer(1600));
/** Constant <code>PARAMETER_TAMPERING</code> */
public final static Category PARAMETER_TAMPERING = new Category("Parameter Tampering", new Integer(1700));
/** Constant <code>SESSION_MANAGEMENT</code> */
public final static Category SESSION_MANAGEMENT = new Category("Session Management Flaws", new Integer(1800));
/** Constant <code>WEB_SERVICES</code> */
public final static Category WEB_SERVICES = new Category("Web Services", new Integer(1900));
/** Constant <code>ADMIN_FUNCTIONS</code> */
public final static Category ADMIN_FUNCTIONS = new Category("Admin Functions", new Integer(2000));
/** Constant <code>CHALLENGE</code> */
public final static Category CHALLENGE = new Category("Challenge", new Integer(3000));
private static final List<Category> categories = new ArrayList<Category>();
private String category;
INTRODUCTION("Introduction", new Integer(5)),
GENERAL("General", new Integer(100)),
INJECTION("Injection Flaws", new Integer(200)),
AUTHENTICATION("Authentication Flaws", new Integer(300)),
XSS("Cross-Site Scripting (XSS)", new Integer(400)),
REQ_FORGERIES("Request Forgeries", new Integer(450)),
ACCESS_CONTROL("Access Control Flaws", new Integer(500)),
INSECURE_CONFIGURATION("Insecure Configuration", new Integer(600)),
INSECURE_COMMUNICATION("Insecure Communication", new Integer(700)),
INSECURE_STORAGE("Insecure Storage", new Integer(800)),
REQUEST_FORGERIES("Request Forgeries", new Integer(900)),
VULNERABLE_COMPONENTS("Vulnerable Components - A9", new Integer(950)),
AJAX_SECURITY("AJAX Security", new Integer(1000)),
BUFFER_OVERFLOW("Buffer Overflows", new Integer(1100)),
CODE_QUALITY("Code Quality", new Integer(1200)),
CONCURRENCY("Concurrency", new Integer(1300)),
ERROR_HANDLING("Improper Error Handling", new Integer(1400)),
DOS("Denial of Service", new Integer(1500)),
MALICIOUS_EXECUTION("Malicious Execution", new Integer(1600)),
CLIENT_SIDE("Client side", new Integer(1700)),
SESSION_MANAGEMENT("Session Management Flaws", new Integer(1800)),
WEB_SERVICES("Web Services", new Integer(1900)),
ADMIN_FUNCTIONS("Admin Functions", new Integer(2000)),
CHALLENGE("Challenges", new Integer(3000));
@Getter
private String name;
@Getter
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);
}
/**
* <p>addCategory.</p>
*
* @param c a {@link org.owasp.webgoat.lessons.Category} object.
*/
public static synchronized void addCategory(Category c) {
categories.add(c);
}
/**
* <p>Getter for the field <code>category</code>.</p>
*
* @param name a {@link java.lang.String} object.
* @return a {@link org.owasp.webgoat.lessons.Category} object.
*/
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;
}
/**
* <p>Constructor for Category.</p>
*
* @param category a {@link java.lang.String} object.
* @param ranking a {@link java.lang.Integer} object.
*/
public Category(String category, Integer ranking) {
this.category = category;
Category(String name, Integer ranking) {
this.name = name;
this.ranking = ranking;
}
/** {@inheritDoc} */
@Override
public int compareTo(Object obj) {
int value = 1;
if (obj instanceof Category) {
value = this.getRanking().compareTo(((Category) obj).getRanking());
}
return value;
}
/**
* <p>Getter for the field <code>ranking</code>.</p>
*
* @return a {@link java.lang.Integer} object.
* {@inheritDoc}
*/
public Integer getRanking() {
return ranking;
}
/**
* <p>Setter for the field <code>ranking</code>.</p>
*
* @param ranking a {@link java.lang.Integer} object.
* @return a {@link java.lang.Integer} object.
*/
public Integer setRanking(Integer ranking) {
return this.ranking = ranking;
}
/**
* <p>getName.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getName() {
return category;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object obj) {
return (obj instanceof Category) && getName().equals(((Category) obj).getName());
}
/** {@inheritDoc} */
@Override
public String toString() {
return getName();

View File

@ -1,41 +1,46 @@
package org.owasp.webgoat.lessons;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
*************************************************************************************************
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
*
* 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.
* <p>
*
* 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.
* <p>
*
* 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.
* <p>
*
* Getting Source ==============
* <p>
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author Nanne Baars
* @since December 12, 2015
*/
package org.owasp.webgoat.lessons;
import lombok.Getter;
import lombok.Setter;
/**
* <p>Hint class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface LessonServletMapping {
@Getter
@Setter
public class Hint {
String path();
private String hint;
private String lesson;
private String assignmentPath;
private int number;
}

View File

@ -1,26 +1,3 @@
package org.owasp.webgoat.lessons;
import com.google.common.base.Joiner;
import org.apache.commons.io.IOUtils;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.H3;
import org.apache.ecs.html.P;
import org.apache.ecs.html.PRE;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.WebSession;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
*************************************************************************************************
*
@ -51,59 +28,11 @@ import java.util.List;
* @since October 28, 2003
* @version $Id: $Id
*/
package org.owasp.webgoat.lessons;
//// TODO: 11/8/2016 remove
public abstract class LessonAdapter extends AbstractLesson {
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s) {
// Mark this lesson as completed.
makeSuccess(s);
ElementContainer ec = new ElementContainer();
ec.addElement(new Center().addElement(new H3().addElement(new StringElement(
"Detailed Lesson Creation Instructions."))));
ec.addElement(new P());
ec
.addElement(new StringElement(
"Lesson are simple to create and very little coding is required. &nbsp;&nbsp;"
+ "In fact, most lessons can be created by following the easy to use instructions by going to the WebGoat wiki page&nbsp;"
+ "<A HREF=https://github.com/WebGoat/WebGoat/wiki>WebGoat Wiki Page</A>&nbsp;&nbsp;"
+ "If you would prefer, send your lesson ideas to&nbsp;"
+ getWebgoatContext().getFeedbackAddressHTML())
+ " Note: you will need to register at "
+ "the following link to use the feedback tool:&nbsp;"
+ "<A HREF=https://lists.owasp.org/mailman/listinfo/owasp-webgoat>List Registration</A>&nbsp;&nbsp;"
+ "Finally, OWASP has a slack channel. You can register at the following link:&nbsp;"
+ "<A HREF=https://owasp.slack.com/>OWASP Slack Channel</A>");
try (InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream("New Lesson Instructions.txt")) {
if (is != null) {
PRE pre = new PRE();
pre.addElement(Joiner.on("\n").join(IOUtils.readLines(is)));
ec.addElement(pre);
}
} catch (IOException e) {
e.printStackTrace();
}
return (ec);
}
/**
* Gets the category attribute of the LessonAdapter object. The default
* category is "General" Only override this method if you wish to create a
* new category or if you wish this lesson to reside within a category other
* the "General"
*
* @return The category value
*/
protected Category getDefaultCategory() {
return Category.GENERAL;
}
/**
* <p>getDefaultHidden.</p>
@ -133,29 +62,6 @@ public abstract class LessonAdapter extends AbstractLesson {
return DEFAULT_RANKING;
}
/**
* {@inheritDoc}
*
* Gets the hintCount attribute of the LessonAdapter object
*/
public int getHintCount(WebSession s) {
return getHints(s).size();
}
/**
* {@inheritDoc}
*
* Fill in a minor hint that will help people who basically get it, but are
* stuck on somthing silly. Hints will be returned to the user in the order
* they appear below. The user must click on the "next hint" button before
* the hint will be displayed.
*/
protected List<String> getHints(WebSession s) {
List<String> hints = new ArrayList<String>();
hints.add("There are no hints defined.");
return hints;
}
/**
* provide a default submitMethod of lesson does not implement
*
@ -165,44 +71,6 @@ public abstract class LessonAdapter extends AbstractLesson {
return "GET";
}
/**
* {@inheritDoc}
*
* Gets the instructions attribute of the LessonAdapter object. Instructions
* will rendered as html and will appear below the control area and above
* the actual lesson area. Instructions should provide the user with the
* general setup and goal of the lesson.
*/
public String getInstructions(WebSession s) {
StringBuffer buff = new StringBuffer();
String lang = s.getCurrrentLanguage();
try {
String fileName = getLessonPlanFileName(lang);
if (fileName != null) {
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line = null;
boolean startAppending = false;
while ((line = in.readLine()) != null) {
if (line.indexOf("<!-- Start Instructions -->") != -1) {
startAppending = true;
continue;
}
if (line.indexOf("<!-- Stop Instructions -->") != -1) {
startAppending = false;
continue;
}
if (startAppending) {
buff.append(line + "\n");
}
}
}
} catch (Exception e) {
}
return buff.toString();
}
/**
* Fill in a descriptive title for this lesson. The title of the lesson.
* This will appear above the control area at the top of the page. This
@ -214,66 +82,5 @@ public abstract class LessonAdapter extends AbstractLesson {
return "Untitled Lesson " + getScreenId();
}
/** {@inheritDoc} */
public String getCurrentAction(WebSession s) {
return s.getLessonSession(this).getCurrentLessonScreen();
}
/** {@inheritDoc} */
public void setCurrentAction(WebSession s, String lessonScreen) {
s.getLessonSession(this).setCurrentLessonScreen(lessonScreen);
}
/**
* <p>getSessionAttribute.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param key a {@link java.lang.String} object.
* @return a {@link java.lang.Object} object.
*/
public Object getSessionAttribute(WebSession s, String key) {
return s.getRequest().getSession().getAttribute(key);
}
/**
* <p>setSessionAttribute.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param key a {@link java.lang.String} object.
* @param value a {@link java.lang.Object} object.
*/
public void setSessionAttribute(WebSession s, String key, Object value) {
s.getRequest().getSession().setAttribute(key, value);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeSuccess(WebSession s) {
getLessonTracker(s).setCompleted(true);
//s.setMessage(getLabelManager().get("LessonCompleted"));
return (null);
}
/**
* Gets the credits attribute of the AbstractLesson object
*
* @return The credits value
* @param text a {@link java.lang.String} object.
* @param e a {@link org.apache.ecs.Element} object.
*/
protected Element getCustomCredits(String text, Element e) {
Table t = new Table().setCellSpacing(0).setCellPadding(0).setBorder(0).setWidth("90%").setAlign("RIGHT");
TR tr = new TR();
tr.addElement(new TD(text).setVAlign("MIDDLE").setAlign("RIGHT").setWidth("100%"));
tr.addElement(new TD(e).setVAlign("MIDDLE").setAlign("RIGHT"));
t.addElement(tr);
return t;
}
}

View File

@ -0,0 +1,22 @@
package org.owasp.webgoat.lessons;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.session.WebSession;
/**
* <p>LessonInfoModel class.</p>
*
* @author dm
* @version $Id: $Id
*/
@Getter
@AllArgsConstructor
public class LessonInfoModel {
private String lessonTitle;
private boolean hasSource;
private boolean hasSolution;
private boolean hasPlan;
}

View File

@ -27,7 +27,7 @@
* https://github.com/WebGoat/WebGoat, a repository for free software projects.
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
import java.util.ArrayList;
import java.util.List;
@ -105,7 +105,7 @@ public class LessonMenuItem {
/**
* <p>addChild.</p>
*
* @param child a {@link org.owasp.webgoat.lessons.model.LessonMenuItem} object.
* @param child a {@link LessonMenuItem} object.
*/
public void addChild(LessonMenuItem child) {
children.add(child);

View File

@ -25,7 +25,7 @@
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
/**
* <p>LessonMenuItemType class.</p>

View File

@ -1,58 +1,51 @@
package org.owasp.webgoat.lessons;
package org.owasp.webgoat.session;
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/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author WebGoat
* @version $Id: $Id
* @author dm
* @since October 12, 2016
*/
public class ValidationException extends Exception
{
public abstract class NewLesson extends LessonAdapter {
/**
*
*/
private static final long serialVersionUID = -8358754606830400708L;
/**
* <p>Constructor for ValidationException.</p>
*/
public ValidationException()
{
super();
}
@Override
public abstract Category getDefaultCategory();
public abstract List<String> getHints();
@Override
public abstract Integer getDefaultRanking();
@Override
public abstract String getTitle();
@Override
public abstract String getId();
/**
* <p>Constructor for ValidationException.</p>
*
* @param message a {@link java.lang.String} object.
*/
public ValidationException(String message)
{
super(message);
}
}

View File

@ -1,143 +0,0 @@
package org.owasp.webgoat.lessons;
import org.owasp.webgoat.session.CreateDB;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.RandomLessonTracker;
import org.owasp.webgoat.session.WebSession;
import java.sql.Connection;
import java.sql.SQLException;
/**
* <p>Abstract RandomLessonAdapter class.</p>
*
* @version $Id: $Id
* @author dm
*/
public abstract class RandomLessonAdapter extends LessonAdapter
{
/**
* <p>getStages.</p>
*
* @return an array of {@link java.lang.String} objects.
*/
public abstract String[] getStages();
/**
* <p>setStage.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param stage a {@link java.lang.String} object.
* @param stage a {@link java.lang.String} object.
*/
public void setStage(WebSession s, String stage)
{
getLessonTracker(s).setStage(stage);
try
{
Connection connection = DatabaseUtilities.getConnection(s);
CreateDB db = new CreateDB();
db.makeDB(connection);
System.out.println("Successfully refreshed the database.");
} catch (SQLException sqle)
{
System.out.println("Error refreshing the database!");
sqle.printStackTrace();
}
}
/**
* <p>getStage.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
public String getStage(WebSession s)
{
return getLessonTracker(s).getStage();
}
/**
* <p>setStageComplete.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param stage a {@link java.lang.String} object.
* @param stage a {@link java.lang.String} object.
*/
public void setStageComplete(WebSession s, String stage)
{
RandomLessonTracker lt = getLessonTracker(s);
lt.setStageComplete(stage, true);
if (lt.getCompleted())
{
//s.setMessage("Congratulations, you have completed this lab");
}
else
{
s.setMessage("You have completed Stage " + (lt.getStageNumber(stage) + 1) + ": " + stage + ".");
if (!stage.equals(lt.getStage()))
s.setMessage(" Welcome to Stage " + (lt.getStageNumber(lt.getStage()) + 1) + ": " + lt.getStage());
}
try
{
Connection connection = DatabaseUtilities.getConnection(s);
CreateDB db = new CreateDB();
db.makeDB(connection);
System.out.println("Successfully refreshed the database.");
} catch (SQLException sqle)
{
System.out.println("Error refreshing the database!");
sqle.printStackTrace();
}
}
/**
* <p>isStageComplete.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param stage a {@link java.lang.String} object.
* @param stage a {@link java.lang.String} object.
* @return a boolean.
*/
public boolean isStageComplete(WebSession s, String stage)
{
return getLessonTracker(s).hasCompleted(stage);
}
/** {@inheritDoc} */
@Override
public RandomLessonTracker getLessonTracker(WebSession s)
{
return (RandomLessonTracker) super.getLessonTracker(s);
}
/** {@inheritDoc} */
@Override
public RandomLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson)
{
return (RandomLessonTracker) super.getLessonTracker(s, lesson);
}
/** {@inheritDoc} */
@Override
public RandomLessonTracker getLessonTracker(WebSession s, String userNameOverride)
{
return (RandomLessonTracker) super.getLessonTracker(s, userNameOverride);
}
/** {@inheritDoc} */
@Override
public LessonTracker createLessonTracker()
{
return new RandomLessonTracker(getStages());
}
}

View File

@ -27,7 +27,7 @@
* for free software projects.
*
*/
package org.owasp.webgoat.lessons.model;
package org.owasp.webgoat.lessons;
/**
* <p>RequestParameter class.</p>

View File

@ -1,214 +0,0 @@
package org.owasp.webgoat.lessons;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.SequentialLessonTracker;
import org.owasp.webgoat.session.WebSession;
/**
* <p>Abstract SequentialLessonAdapter class.</p>
*
* @version $Id: $Id
* @author dm
*/
public abstract class SequentialLessonAdapter extends LessonAdapter
{
/**
* <p>setStage.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param stage a int.
* @param stage a int.
*/
public void setStage(WebSession s, int stage)
{
// System.out.println("Changed to stage " + stage);
getLessonTracker(s).setStage(stage);
}
/*
* By default returns 1 stage. (non-Javadoc)
*/
/**
* <p>getStageCount.</p>
*
* @return a int.
*/
public int getStageCount()
{
return 1;
}
/**
* <p>getStage.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a int.
*/
public int getStage(WebSession s)
{
int stage = getLessonTracker(s).getStage();
// System.out.println("In stage " + stage);
return stage;
}
/** {@inheritDoc} */
@Override
public SequentialLessonTracker getLessonTracker(WebSession s)
{
return (SequentialLessonTracker) super.getLessonTracker(s);
}
/** {@inheritDoc} */
@Override
public SequentialLessonTracker getLessonTracker(WebSession s, AbstractLesson lesson)
{
return (SequentialLessonTracker) super.getLessonTracker(s, lesson);
}
/** {@inheritDoc} */
@Override
public SequentialLessonTracker getLessonTracker(WebSession s, String userNameOverride)
{
return (SequentialLessonTracker) super.getLessonTracker(s, userNameOverride);
}
/** {@inheritDoc} */
@Override
public LessonTracker createLessonTracker()
{
return new SequentialLessonTracker();
}
/**
* <p>createStagedContent.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
*/
protected Element createStagedContent(WebSession s)
{
try
{
int stage = getLessonTracker(s).getStage();
// int stage = Integer.parseInt(
// getLessonTracker(s).getLessonProperties().getProperty(WebSession.STAGE,"1"));
switch (stage)
{
case 1:
return (doStage1(s));
case 2:
return (doStage2(s));
case 3:
return (doStage3(s));
case 4:
return (doStage4(s));
case 5:
return (doStage5(s));
case 6:
return (doStage6(s));
default:
throw new Exception("Invalid stage");
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
// System.out.println(e);
e.printStackTrace();
}
return (new StringElement(""));
}
/**
* <p>doStage1.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage1(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 1 Stub");
return ec;
}
/**
* <p>doStage2.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage2(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 2 Stub");
return ec;
}
/**
* <p>doStage3.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage3(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 3 Stub");
return ec;
}
/**
* <p>doStage4.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage4(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 4 Stub");
return ec;
}
/**
* <p>doStage5.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage5(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 5 Stub");
return ec;
}
/**
* <p>doStage6.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
* @throws java.lang.Exception if any.
*/
protected Element doStage6(WebSession s) throws Exception
{
ElementContainer ec = new ElementContainer();
ec.addElement("Stage 6 Stub");
return ec;
}
}

View File

@ -1,159 +0,0 @@
package org.owasp.webgoat.lessons;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.Form;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.*;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class WelcomeScreen extends Screen
{
/**
* Constructor for the WelcomeScreen object
*
* @param s
* Description of the Parameter
*/
public WelcomeScreen(WebSession s)
{
setup(s);
}
/**
* Constructor for the WelcomeScreen object
*/
public WelcomeScreen()
{
}
/**
* <p>setup.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
*/
public void setup(WebSession s)
{
// call createContent first so messages will go somewhere
Form form = new Form("attack", Form.POST).setName("form").setEncType("");
form.addElement(wrapForm(s));
TD lowerright = new TD().setHeight("100%").setVAlign("top").setAlign("left").addElement(form);
TR row = new TR().addElement(lowerright);
Table layout = new Table().setBgColor(HtmlColor.WHITE).setCellSpacing(0).setCellPadding(0).setBorder(0);
layout.addElement(row);
setContent(layout);
}
/**
* <p>wrapForm.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
*/
protected Element wrapForm(WebSession s)
{
if (s == null) { return new StringElement("Invalid Session"); }
Table container = new Table().setWidth("100%").setCellSpacing(10).setCellPadding(0).setBorder(0);
// CreateContent can generate error messages so you MUST call it before makeMessages()
Element content = createContent(s);
container.addElement(new TR().addElement(new TD().setColSpan(2).setVAlign("TOP").addElement(makeMessages(s))));
container.addElement(new TR().addElement(new TD().setColSpan(2).addElement(content)));
container.addElement(new TR());
return (container);
}
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
Element b = ECSFactory.makeButton("Start the Course!");
ec.addElement(new Center(b));
return (ec);
}
/**
* Gets the instructions attribute of the WelcomeScreen object
*
* @return The instructions value
*/
protected String getInstructions()
{
String instructions = "Enter your name and learn how HTTP really works!";
return (instructions);
}
/**
* Gets the title attribute of the WelcomeScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Welcome to the Penetration Testing Course");
}
/*
* (non-Javadoc)
* @see session.Screen#getRole()
*/
/**
* <p>getRole.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getRole()
{
return AbstractLesson.USER_ROLE;
}
}

View File

@ -1,109 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public abstract class AdminScreen extends Screen
{
/**
* Description of the Field
*/
protected String query = null;
/**
* Constructor for the AdminScreen object
*
* @param s
* Description of the Parameter
* @param q
* Description of the Parameter
*/
public AdminScreen(WebSession s, String q)
{
setQuery(q);
// setupAdmin(s); FIXME: what was this supposed to do?
}
/**
* Constructor for the AdminScreen object
*
* @param s
* Description of the Parameter
*/
public AdminScreen(WebSession s)
{
}
/**
* Constructor for the AdminScreen object
*/
public AdminScreen()
{
}
/**
* Gets the title attribute of the AdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Admin Information");
}
/**
* <p>getRole.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getRole()
{
return AbstractLesson.ADMIN_ROLE;
}
/**
* Sets the query attribute of the AdminScreen object
*
* @param q
* The new query value
*/
public void setQuery(String q)
{
query = q;
}
}

View File

@ -1,162 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.BR;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.WebSession;
import java.net.URL;
import static org.springframework.util.StringUtils.getFilename;
import static org.springframework.util.StringUtils.stripFilenameExtension;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class MenuToLessonMapperScreen extends LessonAdapter
{
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new StringElement("This page describes an overview of all the lessons and maps the lesson to the WebGoat-Lessons project"));
ec.addElement(new BR());
ec.addElement(new BR());
ec.addElement(makeMenuToLessonMapping(s));
return ec;
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return ADMIN_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Lesson information");
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @return Description of the Return Value
*/
public Element makeMenuToLessonMapping(WebSession s)
{
ElementContainer ec = new ElementContainer();
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1);
t.addElement(makeHeaderRow());
for (AbstractLesson lesson : s.getCourse().getLessons(s, AbstractLesson.USER_ROLE)) {
TR tr = new TR();
tr.addElement(new TD().addElement(lesson.getName()));
URL jarLocation = lesson.getClass().getProtectionDomain().getCodeSource().getLocation();
String projectName = removeVersion(stripFilenameExtension(getFilename(jarLocation.getFile())));
tr.addElement(new TD().addElement(projectName));
tr.addElement(new TD().addElement(lesson.getClass().getName() + ".java"));
t.addElement(tr);
}
ec.addElement(t);
return (ec);
}
//Remove version number and last '-'
private static String removeVersion(String s) {
return s.replaceAll("[^a-z\\-]", "").replaceAll("-$", "");
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
private TR makeHeaderRow()
{
TR tr = new TR();
tr.addElement(new TH("Lesson menu item"));
tr.addElement(new TH("Lesson project"));
tr.addElement(new TH("Lesson source class"));
return tr;
}
}

View File

@ -1,124 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class ProductsAdminScreen extends LessonAdapter
{
private final static String QUERY = "SELECT * FROM product_system_data";
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
Connection connection = DatabaseUtilities.getConnection(s);
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(QUERY);
if (results != null)
{
makeSuccess(s);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the category attribute of the ProductsAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
/**
* Gets the role attribute of the ProductsAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the ProductsAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Product Information");
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
}

View File

@ -1,160 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.sql.Connection;
import org.owasp.webgoat.lessons.*;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.A;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.session.*;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class RefreshDBScreen extends LessonAdapter
{
private final static String REFRESH = "Refresh";
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
boolean refresh = s.getParser().getBooleanParameter(REFRESH, false);
if (refresh)
{
refreshDB(s);
ec.addElement(new StringElement("Successfully refreshed the database."));
}
else
{
Element label = new StringElement("Refresh the database? ");
A link1 = ECSFactory.makeLink("Yes", REFRESH, true);
A link2 = ECSFactory.makeLink("No", REFRESH, false);
TD td1 = new TD().addElement(label);
TD td2 = new TD().addElement(link1);
TD td3 = new TD().addElement(link2);
TR row = new TR().addElement(td1).addElement(td2).addElement(td3);
Table t = new Table().setCellSpacing(40).setWidth("50%");
if (s.isColor())
{
t.setBorder(1);
}
t.addElement(row);
ec.addElement(t);
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the category attribute of the RefreshDBScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the RefreshDBScreen object
*
* @return The role value
*/
public String getRole()
{
return ADMIN_ROLE;
}
/**
* Gets the title attribute of the RefreshDBScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Refresh Database");
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
*/
public void refreshDB(WebSession s)
{
try
{
Connection connection = DatabaseUtilities.getConnection(s);
CreateDB db = new CreateDB();
db.makeDB(connection);
System.out.println("Successfully refreshed the database.");
} catch (Exception e)
{
s.setMessage("Error refreshing database " + this.getClass().getName());
e.printStackTrace();
}
}
}

View File

@ -1,295 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.util.Iterator;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.H2;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class ReportCardScreen extends LessonAdapter
{
/**
* Description of the Field
*/
protected final static String USERNAME = "Username";
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String user = null;
try
{
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
{
user = s.getParser().getRawParameter(USERNAME);
}
else
{
user = s.getUserName();
}
} catch (Exception e)
{
}
if (user == null)
{
user = s.getUserName();
}
ec.addElement(makeFeedback(s));
ec.addElement(makeReportCard(s, user));
return ec;
}
private Element makeFeedback(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new StringElement("Comments and suggestions are welcome. "
+ getWebgoatContext().getFeedbackAddressHTML() + "<br><br>"));
return ec;
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return USER_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Report Card");
}
/**
* Description of the Method
*
* @param screen
* Description of the Parameter
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @return Description of the Return Value
*/
private TR makeLessonRow(WebSession s, String user, Screen screen)
{
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
TR tr = new TR();
if (lessonTracker.getCompleted())
{
tr.setBgColor(HtmlColor.LIGHTGREEN);
}
else if (lessonTracker.getNumVisits() == 0)
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
else if (!lessonTracker.getCompleted() && lessonTracker.getNumVisits() > 10)
{
tr.setBgColor(HtmlColor.RED);
}
else
{
tr.setBgColor(HtmlColor.YELLOW);
}
tr.addElement(new TD().addElement(screen.getTitle()));
tr.addElement(new TD().setAlign("CENTER").addElement(lessonTracker.getCompleted() ? "Y" : "N"));
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getNumVisits())));
tr.addElement(new TD().setAlign("CENTER").addElement(Integer.toString(lessonTracker.getMaxHintLevel())));
return tr;
}
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element makeMessages(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec);
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @return Description of the Return Value
*/
public Element makeReportCard(WebSession s, String user)
{
ElementContainer ec = new ElementContainer();
ec.addElement(makeUser(s, user));
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(1);
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
t.addElement(makeUserHeaderRow());
// These are all the user lesson
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Normal user lessons"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.USER_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
// The user figured out there was a hackable admin acocunt
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Hackable Admin Screens"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
// The user figured out how to actually hack the admin acocunt
tr = new TR();
tr.addElement(new TD().setAlign("CENTER").setColSpan(9).addElement("Actual Admin Screens"));
t.addElement(tr);
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
Screen screen = (Screen) lessonIter.next();
t.addElement(makeLessonRow(s, user, screen));
}
ec.addElement(t);
return (ec);
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeUser(WebSession s, String user)
{
H2 h2 = new H2();
// FIXME: The session is the current session, not the session of the user we are reporting.
// String type = s.isAdmin() ? " [Administrative User]" : s.isHackedAdmin() ?
// " [Normal User - Hacked Admin Access]" : " [Normal User]";
String type = "";
h2.addElement(new StringElement("Results for: " + user + type));
return h2;
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
private TR makeUserHeaderRow()
{
TR tr = new TR();
tr.addElement(new TH("Lesson"));
tr.addElement(new TH("Complete"));
tr.addElement(new TH("Visits"));
tr.addElement(new TH("Hints"));
return tr;
}
}

View File

@ -1,326 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.util.Enumeration;
import java.util.Iterator;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.HtmlColor;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.Input;
import org.apache.ecs.html.P;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.LessonTracker;
import org.owasp.webgoat.session.Screen;
import org.owasp.webgoat.session.UserTracker;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce mayhew <a href="http://code.google.com">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class SummaryReportCardScreen extends LessonAdapter
{
private int totalUsersNormalComplete = 0;
private int totalUsersAdminComplete = 0;
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
String selectedUser = null;
try
{
if (s.getRequest().isUserInRole(WebSession.WEBGOAT_ADMIN))
{
Enumeration e = s.getParser().getParameterNames();
while (e.hasMoreElements())
{
String key = (String) e.nextElement();
if (key.startsWith("View_"))
{
selectedUser = key.substring("View_".length());
ReportCardScreen reportCard = new ReportCardScreen();
return reportCard.makeReportCard(s, selectedUser);
}
if (key.startsWith("Delete_"))
{
selectedUser = key.substring("Delete_".length());
deleteUser(selectedUser);
}
}
}
} catch (Exception e)
{
e.printStackTrace();
}
ec.addElement(new Center().addElement(makeSummary(s)));
ec.addElement(new P());
Table t = new Table().setCellSpacing(0).setCellPadding(4).setBorder(1).setWidth("100%");
if (s.isColor())
{
t.setBorder(1);
}
t.addElement(makeUserSummaryHeader());
for (Iterator<String> userIter = UserTracker.instance().getAllUsers(WebSession.WEBGOAT_USER).iterator(); userIter
.hasNext();)
{
String user = userIter.next();
t.addElement(makeUserSummaryRow(s, user));
}
ec.addElement(new Center().addElement(t));
return ec;
}
/**
* <p>makeSummary.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.apache.ecs.Element} object.
*/
protected Element makeSummary(WebSession s)
{
Table t = new Table().setCellSpacing(0).setCellPadding(2).setBorder(0).setWidth("100%");
if (s.isColor())
{
t.setBorder(1);
}
TR tr = new TR();
// tr.addElement( new TH().addElement( "Summary").setColSpan(1));
// t.addElement( tr );
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users"));
tr.addElement(new TD().setAlign("LEFT").addElement(
Integer.toString(UserTracker.instance()
.getAllUsers(WebSession.WEBGOAT_USER).size())));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users that completed all normal lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(Integer.toString(totalUsersNormalComplete)));
t.addElement(tr);
tr = new TR();
tr.addElement(new TD().setWidth("60%").addElement("Total number of users that completed all admin lessons"));
tr.addElement(new TD().setAlign("LEFT").addElement(Integer.toString(totalUsersAdminComplete)));
t.addElement(tr);
return t;
}
private void deleteUser(String user)
{
UserTracker.instance().deleteUser(user);
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return ADMIN_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Summary Report Card");
}
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element makeMessages(WebSession s)
{
ElementContainer ec = new ElementContainer();
return (ec);
}
/**
* Description of the Method
*
* @return Description of the Return Value
*/
protected Element makeUserSummaryHeader()
{
TR tr = new TR();
tr.addElement(new TH("User Name"));
tr.addElement(new TH("Normal Complete"));
tr.addElement(new TH("Admin Complete"));
tr.addElement(new TH("View"));
tr.addElement(new TH("Delete"));
return tr;
}
/**
* Description of the Method
*
* @param s
* Description of the Parameter
* @param user
* Description of the Parameter
* @return Description of the Return Value
*/
protected Element makeUserSummaryRow(WebSession s, String user)
{
TR tr = new TR();
tr.addElement(new TD().setAlign("LEFT").addElement(user));
int lessonCount = 0;
int passedCount = 0;
boolean normalComplete = false;
boolean adminComplete = false;
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.USER_ROLE).iterator(); lessonIter
.hasNext();)
{
lessonCount++;
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
}
if (lessonCount == passedCount)
{
normalComplete = true;
totalUsersNormalComplete++;
}
String text = Integer.toString(passedCount) + " of " + Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
lessonCount = 0;
passedCount = 0;
for (Iterator lessonIter = s.getCourse().getLessons(s, AbstractLesson.HACKED_ADMIN_ROLE).iterator(); lessonIter
.hasNext();)
{
lessonCount++;
Screen screen = (Screen) lessonIter.next();
LessonTracker lessonTracker = UserTracker.instance().getLessonTracker(s, user, screen);
if (lessonTracker.getCompleted())
{
passedCount++;
}
}
if (lessonCount == passedCount)
{
adminComplete = true;
totalUsersAdminComplete++;
}
text = Integer.toString(passedCount) + " of " + Integer.toString(lessonCount);
tr.addElement(new TD().setAlign("CENTER").addElement(text));
tr.addElement(new TD().setAlign("CENTER").addElement(new Input(Input.SUBMIT, "View_" + user, "View")));
tr.addElement(new TD().setAlign("CENTER").addElement(new Input(Input.SUBMIT, "Delete_" + user, "Delete")));
if (normalComplete && adminComplete)
{
tr.setBgColor(HtmlColor.GREEN);
}
else if (normalComplete)
{
tr.setBgColor(HtmlColor.LIGHTGREEN);
}
else
{
tr.setBgColor(HtmlColor.LIGHTBLUE);
}
return (tr);
}
/**
* <p>isEnterprise.</p>
*
* @return a boolean.
*/
public boolean isEnterprise()
{
return true;
}
}

View File

@ -1,124 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.LessonAdapter;
import org.owasp.webgoat.session.DatabaseUtilities;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class UserAdminScreen extends LessonAdapter
{
private final static String QUERY = "SELECT * FROM user_system_data";
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
Connection connection = DatabaseUtilities.getConnection(s);
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(QUERY);
if (results != null)
{
makeSuccess(s);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the category attribute of the UserAdminScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* Gets the role attribute of the UserAdminScreen object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the UserAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("User Information");
}
}

View File

@ -1,165 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.owasp.webgoat.lessons.*;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.Input;
import org.owasp.webgoat.session.*;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class ViewDatabase extends LessonAdapter
{
private final static String SQL = "sql";
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
try
{
ec.addElement(new StringElement("Enter a SQL statement: "));
StringBuffer sqlStatement = new StringBuffer(s.getParser().getRawParameter(SQL, ""));
Input input = new Input(Input.TEXT, SQL, sqlStatement.toString());
ec.addElement(input);
Element b = ECSFactory.makeButton("Go!");
ec.addElement(b);
Connection connection = DatabaseUtilities.getConnection(s);
if (sqlStatement.length() > 0)
{
Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet results = statement.executeQuery(sqlStatement.toString());
if ((results != null) && (results.first() == true))
{
makeSuccess(s);
ResultSetMetaData resultsMetaData = results.getMetaData();
ec.addElement(DatabaseUtilities.writeTable(results, resultsMetaData));
}
}
} catch (Exception e)
{
s.setMessage("Error generating " + this.getClass().getName());
e.printStackTrace();
}
return (ec);
}
/**
* Gets the category attribute of the DatabaseScreen object
*
* @return The category value
*/
protected Category getDefaultCategory()
{
return Category.ADMIN_FUNCTIONS;
}
private final static Integer DEFAULT_RANKING = new Integer(1000);
/**
* <p>getDefaultRanking.</p>
*
* @return a {@link java.lang.Integer} object.
*/
protected Integer getDefaultRanking()
{
return DEFAULT_RANKING;
}
/**
* {@inheritDoc}
*
* Gets the hints attribute of the DatabaseScreen object
*/
protected List<String> getHints(WebSession s)
{
List<String> hints = new ArrayList<String>();
hints.add("There are no hints defined");
return hints;
}
/**
* {@inheritDoc}
*
* Gets the instructions attribute of the ViewDatabase object
*/
public String getInstructions(WebSession s)
{
String instructions = "Please post a message to to the WebGoat forum. Your messages will be available for everyone to read.";
return (instructions);
}
/**
* Gets the role attribute of the ViewDatabase object
*
* @return The role value
*/
public String getRole()
{
return HACKED_ADMIN_ROLE;
}
/**
* Gets the title attribute of the DatabaseScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Adhoc Query");
}
}

View File

@ -1,87 +0,0 @@
package org.owasp.webgoat.lessons.admin;
import org.owasp.webgoat.lessons.WelcomeScreen;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.html.Center;
import org.apache.ecs.html.H1;
import org.owasp.webgoat.session.WebSession;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class WelcomeAdminScreen extends WelcomeScreen
{
/**
* Constructor for the WelcomeAdminScreen object
*
* @param s
* Description of the Parameter
*/
public WelcomeAdminScreen(WebSession s)
{
super(s);
}
/**
* Constructor for the WelcomeAdminScreen object
*/
public WelcomeAdminScreen()
{
}
/**
* {@inheritDoc}
*
* Description of the Method
*/
protected Element createContent(WebSession s)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new Center(new H1("You are logged on as an administrator")));
ec.addElement(super.createContent(s));
return (ec);
}
/**
* Gets the title attribute of the WelcomeAdminScreen object
*
* @return The title value
*/
public String getTitle()
{
return ("Admin Welcome");
}
}

View File

@ -1,95 +0,0 @@
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
*/
package org.owasp.webgoat.lessons.model;
/**
* <p>Hint class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
public class Hint {
private String hint;
private String lesson;
private int number;
/**
* <p>Getter for the field <code>hint</code>.</p>
*
* @return the hint
*/
public String getHint() {
return hint;
}
/**
* <p>Setter for the field <code>hint</code>.</p>
*
* @param hint the hint to set
*/
public void setHint(String hint) {
this.hint = hint;
}
/**
* <p>Getter for the field <code>lesson</code>.</p>
*
* @return the lesson
*/
public String getLesson() {
return lesson;
}
/**
* <p>Setter for the field <code>lesson</code>.</p>
*
* @param lesson the lesson to set
*/
public void setLesson(String lesson) {
this.lesson = lesson;
}
/**
* <p>Getter for the field <code>number</code>.</p>
*
* @return the number
*/
public int getNumber() {
return number;
}
/**
* <p>Setter for the field <code>number</code>.</p>
*
* @param number the number to set
*/
public void setNumber(int number) {
this.number = number;
}
}

View File

@ -1,104 +0,0 @@
package org.owasp.webgoat.lessons.model;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.session.WebSession;
/**
* <p>LessonInfoModel class.</p>
*
* @author dm
* @version $Id: $Id
*/
public class LessonInfoModel {
private String lessonTitle;
private int numberHints;
private boolean hasSource;
private boolean hasSolution;
private boolean hasPlan;
private String submitMethod;
/**
* <p>Constructor for LessonInfoModel.</p>
*
* @param webSession a {@link org.owasp.webgoat.session.WebSession} object.
*/
public LessonInfoModel(WebSession webSession) {
AbstractLesson lesson = webSession.getCurrentLesson();
//TODO make these first class citizens of the lesson itself; and stop passing the session all over ... and generally tighten the checks up
this.hasSource = !lesson.getSource(webSession).contains("Could not find the source file or source file does not exist");
this.hasPlan = !lesson.getSource(webSession).contains("Could not find lesson plan");
this.hasSolution = !lesson.getSolution(webSession).contains("Could not find the solution file or solution file does not exist");
this.lessonTitle = lesson.getTitle();
this.numberHints = lesson.getHintCount(webSession);
this.submitMethod = lesson.getSubmitMethod();
if ( this.numberHints < 1 || lesson.getHint(webSession,0).equals("Hint: There are no hints defined.")) {
this.numberHints = 0;
}
//special challenge case
if (lesson.getCategory().equals(Category.CHALLENGE)) {
this.numberHints = (lesson.isAuthorized(webSession, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS)) ? lesson.getHintCount(webSession) : 0;
this.hasSource = (lesson.isAuthorized(webSession, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS));
this.hasSolution = (lesson.isAuthorized(webSession, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS)); //assuming we want this to fall in line with source and solution
this.hasPlan = (lesson.isAuthorized(webSession, AbstractLesson.CHALLENGE_ROLE, WebSession.SHOWHINTS)); //assuming we want this to fall in line with source and solutionn
}
}
// GETTERS
/**
* <p>Getter for the field <code>lessonTitle</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getLessonTitle() {
return lessonTitle;
}
/**
* <p>Getter for the field <code>numberHints</code>.</p>
*
* @return a int.
*/
public int getNumberHints() {
return numberHints;
}
/**
* <p>isHasSource.</p>
*
* @return a boolean.
*/
public boolean isHasSource() {
return hasSource;
}
/**
* <p>isHasSolution.</p>
*
* @return a boolean.
*/
public boolean isHasSolution() {
return hasSolution;
}
/**
* <p>isHasPlan.</p>
*
* @return a boolean.
*/
public boolean isHasPlan() {
return hasPlan;
}
/**
* <p>Getter for the field <code>submitMethod</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getSubmitMethod() {
return submitMethod;
}
}

View File

@ -1,37 +0,0 @@
/*
* 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.lessons.model;
/**
* <p>SourceListing class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
public class SourceListing {
private String source;
/**
* <p>Getter for the field <code>source</code>.</p>
*
* @return the source
*/
public String getSource() {
return source;
}
/**
* <p>Setter for the field <code>source</code>.</p>
*
* @param source the source to set
*/
public void setSource(String source) {
this.source = source;
}
}

View File

@ -1,260 +0,0 @@
package org.owasp.webgoat.plugins;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.WebgoatContext;
import org.owasp.webgoat.session.WebgoatProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import java.io.File;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
*/
public class LegacyLoader {
final Logger logger = LoggerFactory.getLogger(LegacyLoader.class);
private final List<String> files = new LinkedList<String>();
/**
* <p>Constructor for LegacyLoader.</p>
*/
public LegacyLoader() {
}
/**
* 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.contains("/")) {
fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
}
if (fileName.contains(".")) {
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) {
StringBuilder sb = new StringBuilder();
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;
}
// skip over plugins and/or extracted plugins
if ( fileName.indexOf("lessons/plugin") >= 0 || fileName.indexOf("plugin_extracted") >= 0) {
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;
}
/**
* Load all of the filenames into a temporary cache
*
* @param context a {@link javax.servlet.ServletContext} object.
* @param path a {@link java.lang.String} object.
*/
public void loadFiles(ServletContext context, String path) {
logger.debug("Loading files into cache, path: " + path);
Set resourcePaths = context.getResourcePaths(path);
if (resourcePaths == null) {
logger.error("Unable to load file cache for courses, this is probably a bug or configuration issue");
return;
}
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 a {@link java.lang.String} object.
* @param context a {@link javax.servlet.ServletContext} object.
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
* @param properties a {@link org.owasp.webgoat.session.WebgoatProperties} object.
* @return a {@link java.util.List} object.
*/
public List<AbstractLesson> loadLessons(WebgoatContext webgoatContext, ServletContext context, String path, WebgoatProperties properties ) {
loadFiles(context, path);
List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
for (String file : files) {
String className = getClassFile(file, path);
if (className != null && !className.endsWith("_i") && className.startsWith("org.owasp.webgoat.lessons.admin")) {
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) {
// Bruce says:
// I don't think we want to log the exception here. We could
// be potentially showing a lot of exceptions that don't matter.
// We would only care if the lesson extended AbstractLesson and we
// can't tell that because it threw the exception. Catch 22
// logger.error("Error in loadLessons: ", e);
}
}
}
loadResources(lessons);
return lessons;
}
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 langStr;
}
/**
* For each lesson, set the source file and lesson file
*
* @param lessons a {@link java.util.List} object.
*/
public void loadResources(List<AbstractLesson> lessons ) {
for (AbstractLesson lesson : lessons) {
logger.info("Loading resources for lesson -> " + lesson.getName());
String className = lesson.getClass().getName();
String classFile = getSourceFile(className);
logger.info("Lesson classname: " + className);
logger.info("Lesson java file: " + classFile);
for (String absoluteFile : files) {
String fileName = getFileName(absoluteFile);
//logger.debug("Course: looking at file: " + absoluteFile);
if (absoluteFile.endsWith(classFile)) {
logger.info("Set source file for " + classFile);
lesson.setSourceFileName(absoluteFile);
}
if (absoluteFile.startsWith("/lesson_plans") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName)) {
logger.info("setting lesson plan file " + absoluteFile + " for lesson "
+ lesson.getClass().getName());
logger.info("fileName: " + fileName + " == className: " + className);
String language = getLanguageFromFileName("/lesson_plans", absoluteFile);
lesson.setLessonPlanFileName(language, absoluteFile);
}
if (absoluteFile.startsWith("/lesson_solutions") && absoluteFile.endsWith(".html")
&& className.endsWith(fileName)) {
logger.info("setting lesson solution file " + absoluteFile + " for lesson "
+ lesson.getClass().getName());
logger.info("fileName: " + fileName + " == className: " + className);
lesson.setLessonSolutionFileName(absoluteFile);
}
}
}
}
}

View File

@ -1,176 +0,0 @@
package org.owasp.webgoat.plugins;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import org.apache.catalina.loader.WebappClassLoader;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith;
import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName;
import static org.owasp.webgoat.plugins.PluginFileUtils.replaceInFiles;
/**
* <p>Plugin class.</p>
*
* @version $Id: $Id
* @author dm
*/
public class Plugin {
private static final String NAME_LESSON_SOLUTION_DIRECTORY = "lessonSolutions";
private static final String NAME_LESSON_PLANS_DIRECTORY = "lessonPlans";
private Class<AbstractLesson> lesson;
private Map<String, File> solutionLanguageFiles = new HashMap<>();
private Map<String, File> lessonPlansLanguageFiles = new HashMap<>();
private List<File> pluginFiles = Lists.newArrayList();
private File lessonSourceFile;
/**
* <p>findLesson.</p>
*
* @param classes a {@link java.util.List} object.
*/
public void findLesson(List<String> classes) {
for (String clazzName : classes) {
findLesson(clazzName);
}
}
private void findLesson(String name) {
String realClassName = StringUtils.trimLeadingCharacter(name, '/').replaceAll("/", ".").replaceAll(".class", "");
//TODO should be passed in (refactor)
WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader();
try {
Class clazz = cl.loadClass(realClassName, true);
if (AbstractLesson.class.isAssignableFrom(clazz)) {
this.lesson = clazz;
}
} catch (ClassNotFoundException ce) {
throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce);
}
}
/**
* <p>loadFiles.</p>
*
* @param file a {@link java.nio.file.Path} object.
*/
public void loadFiles(Path file) {
if (fileEndsWith(file, ".html") && hasParentDirectoryWithName(file, NAME_LESSON_SOLUTION_DIRECTORY)) {
solutionLanguageFiles.put(file.getParent().getFileName().toString(), file.toFile());
}
if (fileEndsWith(file, ".html") && hasParentDirectoryWithName(file, NAME_LESSON_PLANS_DIRECTORY)) {
lessonPlansLanguageFiles.put(file.getParent().getFileName().toString(), file.toFile());
}
if (fileEndsWith(file, ".java")) {
lessonSourceFile = file.toFile();
}
if (fileEndsWith(file, ".css", ".jsp", ".js")) {
pluginFiles.add(file.toFile());
}
}
/**
* <p>rewritePaths.</p>
*
* @param pluginTarget a {@link java.nio.file.Path} object.
*/
public void rewritePaths(Path pluginTarget) {
try {
replaceInFiles(this.lesson.getSimpleName() + "_files",
pluginTarget.getFileName().toString() + "/plugin/" + this.lesson
.getSimpleName() + "/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files",
solutionLanguageFiles.values());
replaceInFiles(this.lesson.getSimpleName() + "_files",
pluginTarget.getFileName().toString() + "/plugin/" + this.lesson
.getSimpleName() + "/lessonPlans/en/" + this.lesson.getSimpleName() + "_files",
lessonPlansLanguageFiles.values());
String[] replacements = {"jsp", "js"};
for (String replacement : replacements) {
String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement);
String r = String.format("%s/plugin/%s/%s/", pluginTarget.getFileName().toString(),
this.lesson.getSimpleName(), replacement);
replaceInFiles(s, r, pluginFiles);
replaceInFiles(s, r, Arrays.asList(lessonSourceFile));
}
//CSS with url('/plugin/images') should not begin with / otherwise image cannot be found
String s = String.format("/plugin/%s/images/", this.lesson.getSimpleName());
String r = String
.format("%s/plugin/%s/images/", pluginTarget.getFileName().toString(), this.lesson.getSimpleName());
replaceInFiles(s, r, pluginFiles);
replaceInFiles(s, r, Arrays.asList(lessonSourceFile));
} catch (IOException e) {
throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e);
}
}
/**
* Lesson is optional, it is also possible that the supplied jar contains only helper classes.
*
* @return a {@link com.google.common.base.Optional} object.
*/
public Optional<AbstractLesson> getLesson() {
try {
if (lesson != null) {
return Optional.of(lesson.newInstance());
}
} catch (IllegalAccessException | InstantiationException e) {
throw new PluginLoadingFailure("Unable to instantiate the lesson " + lesson.getName(), e);
}
return Optional.absent();
}
/**
* <p>getLessonSolution.</p>
*
* @param language a {@link java.lang.String} object.
* @return a {@link com.google.common.base.Optional} object.
*/
public Optional<File> getLessonSolution(String language) {
return Optional.fromNullable(this.solutionLanguageFiles.get(language));
}
/**
* <p>getLessonSolutions.</p>
*
* @return a {@link java.util.Map} object.
*/
public Map<String, File> getLessonSolutions() {
return this.solutionLanguageFiles;
}
/**
* <p>getLessonSource.</p>
*
* @return a {@link com.google.common.base.Optional} object.
*/
public Optional<File> getLessonSource() {
return Optional.fromNullable(lessonSourceFile);
}
/**
* <p>getLessonPlans.</p>
*
* @return a {@link java.util.Map} object.
*/
public Map<String, File> getLessonPlans() {
return this.lessonPlansLanguageFiles;
}
}

View File

@ -0,0 +1,66 @@
package org.owasp.webgoat.plugins;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.Endpoint;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
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/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @since October 16, 2016
*/
@Slf4j
public class PluginEndpointPublisher {
private AbstractApplicationContext applicationContext;
public PluginEndpointPublisher(ApplicationContext applicationContext) {
this.applicationContext = (AbstractApplicationContext) applicationContext;
}
public void publish(List<Class<Endpoint>> endpoints) {
endpoints.forEach(e -> publishEndpoint(e));
}
private void publishEndpoint(Class<? extends MvcEndpoint> e) {
try {
BeanDefinition beanDefinition = new RootBeanDefinition(e, Autowire.BY_TYPE.value(), true);
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(beanDefinition.getBeanClassName(), beanDefinition);
} catch (Exception ex) {
log.error("Failed to register " + e.getSimpleName() + " as endpoint with Spring, skipping...");
}
}
}

View File

@ -1,119 +0,0 @@
package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import org.apache.commons.fileupload.util.Streams;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* Extract the jar file and place them in the system temp directory in the folder webgoat and collect the files
* and classes.
*
* @author dm
* @version $Id: $Id
*/
public class PluginExtractor {
private final List<String> classes = Lists.newArrayList();
private final List<Path> files = new ArrayList<>();
/**
* <p>extractJarFile.</p>
*
* @param archive a {@link java.io.File} object.
* @param targetDirectory a {@link java.io.File} object.
* @return a {@link org.owasp.webgoat.plugins.Plugin} object.
* @throws java.io.IOException if any.
*/
public Plugin extractJarFile(final File archive, final File targetDirectory) throws IOException {
ZipFile zipFile = new ZipFile(archive);
Plugin plugin = new Plugin();
try {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
final ZipEntry zipEntry = entries.nextElement();
if (shouldProcessFile(zipEntry)) {
boolean processed = processClassFile(zipEntry);
if (!processed) {
processed = processPropertyFile(zipFile, zipEntry, targetDirectory);
}
if (!processed) {
processFile(plugin, zipFile, zipEntry, targetDirectory);
}
}
}
} finally {
plugin.findLesson(this.classes);
if (plugin.getLesson().isPresent()) {
plugin.rewritePaths(targetDirectory.toPath());
}
zipFile.close();
}
return plugin;
}
private void processFile(Plugin plugin, ZipFile zipFile, ZipEntry zipEntry, File targetDirectory)
throws IOException {
final File targetFile = new File(targetDirectory, zipEntry.getName());
copyFile(zipFile, zipEntry, targetFile, false);
plugin.loadFiles(targetFile.toPath());
}
private boolean processPropertyFile(ZipFile zipFile, ZipEntry zipEntry, File targetDirectory)
throws IOException {
if (zipEntry.getName().endsWith(".properties")) {
final File targetFile = new File(targetDirectory, zipEntry.getName());
copyFile(zipFile, zipEntry, targetFile, true);
return true;
}
return false;
}
private boolean processClassFile(ZipEntry zipEntry) {
if (zipEntry.getName().endsWith(".class")) {
classes.add(zipEntry.getName());
return true;
}
return false;
}
private boolean shouldProcessFile(ZipEntry zipEntry) {
return !zipEntry.isDirectory() && !zipEntry.getName().startsWith("META-INF");
}
private File copyFile(ZipFile zipFile, ZipEntry zipEntry, File targetFile, boolean append) throws IOException {
Files.createParentDirs(targetFile);
try (FileOutputStream fos = new FileOutputStream(targetFile, append)) {
Streams.copy(zipFile.getInputStream(zipEntry), fos, true);
}
return targetFile;
}
/**
* <p>Getter for the field <code>classes</code>.</p>
*
* @return a {@link java.util.List} object.
*/
public List<String> getClasses() {
return this.classes;
}
/**
* <p>Getter for the field <code>files</code>.</p>
*
* @return a {@link java.util.List} object.
*/
public List<Path> getFiles() {
return this.files;
}
}

View File

@ -1,119 +0,0 @@
package org.owasp.webgoat.plugins;
import com.google.common.base.Preconditions;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
/**
* <p>PluginFileUtils class.</p>
*
* @version $Id: $Id
* @author dm
*/
public class PluginFileUtils {
/**
* <p>fileEndsWith.</p>
*
* @param p a {@link java.nio.file.Path} object.
* @param s a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean fileEndsWith(Path p, String s) {
return p.getFileName().toString().endsWith(s);
}
/**
* <p>fileEndsWith.</p>
*
* @param p a {@link java.nio.file.Path} object.
* @param suffixes a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean fileEndsWith(Path p, String... suffixes) {
for (String suffix : suffixes) {
if (fileEndsWith(p, suffix)) {
return true;
}
}
return false;
}
/**
* <p>hasParentDirectoryWithName.</p>
*
* @param p a {@link java.nio.file.Path} object.
* @param s a {@link java.lang.String} object.
* @return a boolean.
*/
public static boolean hasParentDirectoryWithName(Path p, String s) {
if (p == null || p.getParent() == null || p.getParent().equals(p.getRoot())) {
return false;
}
if (p.getParent().getFileName().toString().equals(s)) {
return true;
}
return hasParentDirectoryWithName(p.getParent(), s);
}
/**
* <p>createDirsIfNotExists.</p>
*
* @param p a {@link java.nio.file.Path} object.
* @return a {@link java.nio.file.Path} object.
* @throws java.io.IOException if any.
*/
public static Path createDirsIfNotExists(Path p) throws IOException {
if (Files.notExists(p)) {
Files.createDirectories(p);
}
return p;
}
/**
* <p>replaceInFiles.</p>
*
* @param replace a {@link java.lang.String} object.
* @param with a {@link java.lang.String} object.
* @param files a {@link java.util.Collection} object.
* @throws java.io.IOException if any.
*/
public static void replaceInFiles(String replace, String with, Collection<File> files) throws IOException {
Preconditions.checkNotNull(replace);
Preconditions.checkNotNull(with);
Preconditions.checkNotNull(files);
for (File file : files) {
replaceInFile(replace, with, file);
}
}
/**
* <p>replaceInFile.</p>
*
* @param replace a {@link java.lang.String} object.
* @param with a {@link java.lang.String} object.
* @param file a {@link java.nio.file.Path} object.
* @throws java.io.IOException if any.
*/
public static void replaceInFile(String replace, String with, File file) throws IOException {
Preconditions.checkNotNull(replace);
Preconditions.checkNotNull(with);
Preconditions.checkNotNull(file);
String fileAsString = "";
try (FileInputStream fis = new FileInputStream(file);) {
fileAsString = IOUtils.toString(fis, StandardCharsets.UTF_8.name());
fileAsString = fileAsString.replaceAll(replace, with);
}
Files.write(file.toPath(), fileAsString.getBytes());
}
}

View File

@ -8,6 +8,15 @@ package org.owasp.webgoat.plugins;
*/
public class PluginLoadingFailure extends RuntimeException {
/**
* <p>Constructor for PluginLoadingFailure.</p>
*
* @param message a {@link java.lang.String} object.
*/
public PluginLoadingFailure(String message) {
super(message);
}
/**
* <p>Constructor for PluginLoadingFailure.</p>
*

View File

@ -0,0 +1,46 @@
package org.owasp.webgoat.plugins;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.Endpoint;
import org.owasp.webgoat.lessons.NewLesson;
import java.net.URL;
import java.util.List;
import java.util.stream.Collectors;
/**
* Plugin resource
*
* @author nbaars
* @since 3/4/17.
*/
@AllArgsConstructor
@Getter
public class PluginResource {
private final URL location;
private final List<Class> classes;
public List<Class> getLessons() {
return classes.stream().filter(c -> c.getSuperclass() == NewLesson.class).collect(Collectors.toList());
}
public List<Class<Endpoint>> getEndpoints() {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class || c.getSuperclass() == Endpoint.class).
map(c -> (Class<Endpoint>) c).
collect(Collectors.toList());
}
public List<Class<AssignmentEndpoint>> getAssignments(Class lesson) {
return classes.stream().
filter(c -> c.getSuperclass() == AssignmentEndpoint.class).
filter(c -> c.getPackage().equals(lesson.getPackage())).
map(c -> (Class<AssignmentEndpoint>) c).
collect(Collectors.toList());
}
}

View File

@ -1,148 +1,134 @@
package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists;
import org.apache.catalina.loader.WebappClassLoader;
import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.util.LabelProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.NewLesson;
import org.owasp.webgoat.session.Course;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import java.io.IOException;
import java.net.URL;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toList;
/**
* <p>PluginsLoader class.</p>
* ************************************************************************************************
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
* <p>
*
* @author nbaars
* @version $Id: $Id
* @author dm
* @since November 25, 2016
*/
@AllArgsConstructor
@Slf4j
public class PluginsLoader {
private static final String WEBGOAT_PLUGIN_EXTENSION = "jar";
private static boolean alreadyLoaded = false;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Path pluginSource;
private Path pluginTarget;
private final PluginEndpointPublisher pluginEndpointPublisher;
/**
* <p>Constructor for PluginsLoader.</p>
*
* @param pluginSource a {@link java.nio.file.Path} object.
* @param pluginTarget a {@link java.nio.file.Path} object.
* <p>createLessonsFromPlugins.</p>
*/
public PluginsLoader(Path pluginSource, Path pluginTarget) {
this.pluginSource = Objects.requireNonNull(pluginSource, "plugin source cannot be null");
this.pluginTarget = Objects.requireNonNull(pluginTarget, "plugin target cannot be null");
}
/**
* Copy jars to the lib directory
*/
public void copyJars() {
public Course loadPlugins() {
List<AbstractLesson> lessons = Lists.newArrayList();
for (PluginResource plugin : findPluginResources()) {
try {
if (!alreadyLoaded) {
WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader();
List<URL> jars = listJars();
for (URL jar : jars) {
cl.addRepository(jar.toString());
}
alreadyLoaded = true;
}
plugin.getLessons().forEach(c -> {
NewLesson lesson = null;
try {
lesson = (NewLesson) c.newInstance();
log.trace("Lesson loaded: {}", lesson.getId());
} catch (Exception e) {
logger.error("Copying plugins failed", e);
log.error("Error while loading:" + c, e);
}
}
/**
* <p>loadPlugins.</p>
*
* @return a {@link java.util.List} object.
*/
public List<Plugin> loadPlugins() {
copyJars();
List<Plugin> plugins = Lists.newArrayList();
try {
PluginFileUtils.createDirsIfNotExists(pluginTarget);
cleanupExtractedPluginsDirectory();
List<URL> jars = listJars();
plugins = processPlugins(jars);
List<Class<AssignmentEndpoint>> assignments = plugin.getAssignments(c);
lesson.setAssignments(createAssignment(assignments));
lessons.add(lesson);
pluginEndpointPublisher.publish(plugin.getEndpoints());
});
} catch (Exception e) {
logger.error("Loading plugins failed", e);
log.error("Error in loadLessons: ", e);
}
return plugins;
}
if (lessons.isEmpty()) {
log.error("No lessons found if you downloaded an official release of WebGoat please take the time to");
log.error("create a new issue at https://github.com/WebGoat/WebGoat/issues/new");
log.error("For developers run 'mvn package' first from the root directory.");
}
return new Course(lessons);
}
private void cleanupExtractedPluginsDirectory() {
Path i18nDirectory = pluginTarget.resolve("plugin/i18n/");
FileUtils.deleteQuietly(i18nDirectory.toFile());
private List<Assignment> createAssignment(List<Class<AssignmentEndpoint>> endpoints) {
return endpoints.stream().map(e -> new Assignment(e.getSimpleName(), getPath(e), getHints(e))).collect(toList());
}
private List<URL> listJars() throws IOException {
final List<URL> jars = Lists.newArrayList();
Files.walkFileTree(pluginSource, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) {
jars.add(file.toUri().toURL());
}
return FileVisitResult.CONTINUE;
}
});
return jars;
private String getPath(Class<AssignmentEndpoint> e) {
return e.getAnnotationsByType(AssignmentPath.class)[0].value();
}
private List<Plugin> processPlugins(List<URL> jars) throws Exception {
final ExecutorService executorService = Executors.newFixedThreadPool(10);
try {
final List<Plugin> plugins = Lists.newArrayList();
final CompletionService<Plugin> completionService = new ExecutorCompletionService<>(executorService);
final List<Callable<Plugin>> callables = extractJars(jars);
for (Callable<Plugin> s : callables) {
completionService.submit(s);
}
int n = callables.size();
for (int i = 0; i < n; i++) {
Plugin plugin = completionService.take().get();
if (plugin.getLesson().isPresent()) {
plugins.add(plugin);
}
}
LabelProvider.updatePluginResources(pluginTarget.resolve("plugin/i18n/WebGoatLabels.properties"));
return plugins;
} finally {
executorService.shutdown();
private List<String> getHints(Class<AssignmentEndpoint> e) {
if (e.isAnnotationPresent(AssignmentHints.class)) {
return Lists.newArrayList(e.getAnnotationsByType(AssignmentHints.class)[0].value());
}
return Lists.newArrayList();
}
private List<Callable<Plugin>> extractJars(List<URL> jars) {
List<Callable<Plugin>> extractorCallables = Lists.newArrayList();
for (final URL jar : jars) {
extractorCallables.add(new Callable<Plugin>() {
@Override
public Plugin call() throws Exception {
PluginExtractor extractor = new PluginExtractor();
return extractor.extractJarFile(ResourceUtils.getFile(jar), pluginTarget.toFile());
@SneakyThrows
public List<PluginResource> findPluginResources() {
final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
final Set<BeanDefinition> classes = provider.findCandidateComponents("org.owasp.webgoat.plugin");
Map<URL, List<Class>> pluginClasses = Maps.newHashMap();
for (BeanDefinition bean : classes) {
Class<?> clazz = Class.forName(bean.getBeanClassName());
URL location = clazz.getProtectionDomain().getCodeSource().getLocation();
List<Class> classFiles = pluginClasses.get(location);
if (classFiles == null) {
classFiles = Lists.newArrayList(clazz);
} else {
classFiles.add(clazz);
}
});
pluginClasses.put(location, classFiles);
}
return extractorCallables;
return pluginClasses.entrySet().parallelStream()
.map(e -> new PluginResource(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
}

View File

@ -1,108 +0,0 @@
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
*/
package org.owasp.webgoat.service;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* <p>Abstract BaseService class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@RequestMapping("/service")
public abstract class BaseService {
private static final Logger logger = LoggerFactory.getLogger(BaseService.class);
/**
* <p>handleException.</p>
*
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @param ex a {@link java.lang.Exception} object.
* @return a {@link org.owasp.webgoat.service.ExceptionInfo} object.
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.I_AM_A_TEAPOT)
public @ResponseBody
ExceptionInfo handleException(HttpServletRequest request, Exception ex) {
String url = request.getRequestURL().toString();
logger.error("Exception handler for service caught exception when processing: " + url, ex);
ExceptionInfo response = new ExceptionInfo();
response.setUrl(url);
response.setMessage(getStringStackTrace(ex));
return response;
}
/**
* <p>getWebSession.</p>
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.owasp.webgoat.session.WebSession} object.
*/
public WebSession getWebSession(HttpSession session) {
WebSession ws;
Object o = session.getAttribute(WebSession.SESSION);
if (o == null) {
throw new IllegalArgumentException("No valid WebSession object found, has session timed out? [" + session.getId() + "]");
}
if (!(o instanceof WebSession)) {
throw new IllegalArgumentException("Invalid WebSession object found, this is probably a bug! [" + o.getClass() + " | " + session.getId() + "]");
}
ws = (WebSession) o;
return ws;
}
/**
* <p>getStringStackTrace.</p>
*
* @param t a {@link java.lang.Throwable} object.
* @return a {@link java.lang.String} object.
*/
public String getStringStackTrace(Throwable t){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return sw.toString();
}
}

View File

@ -29,16 +29,14 @@
*/
package org.owasp.webgoat.service;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.lessons.model.RequestParameter;
import org.owasp.webgoat.session.WebSession;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* <p>CookieService class.</p>
@ -47,7 +45,7 @@ import org.springframework.web.servlet.ModelAndView;
* @version $Id: $Id
*/
@Controller
public class CookieService extends BaseService {
public class CookieService {
/**
* Returns cookies for last attack
@ -55,30 +53,11 @@ public class CookieService extends BaseService {
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.util.List} object.
*/
@RequestMapping(value = "/cookie.mvc", produces = "application/json")
@RequestMapping(path = "/service/cookie.mvc", produces = "application/json")
public @ResponseBody
List<Cookie> showCookies(HttpSession session) {
WebSession ws = getWebSession(session);
List<Cookie> cookies = ws.getCookiesOnLastRequest();
List<Cookie> showCookies() {
//// TODO: 11/6/2016 to be decided
List<Cookie> cookies = Lists.newArrayList();
return cookies;
}
/**
* Returns cookies and params for current lesson
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "/cookies_widget.mvc", produces = "text/html")
public ModelAndView showCookiesAndParamsAsHtml(HttpSession session) {
ModelAndView model = new ModelAndView();
WebSession ws = getWebSession(session);
List<Cookie> cookies = ws.getCookiesOnLastRequest();
List<RequestParameter> listParms = ws.getParmsOnLastRequest();
Collections.sort(listParms);
model.addObject("wgcookies", cookies);
model.addObject("wgparams", listParms);
model.setViewName("widgets/cookies_and_params");
return model;
}
}

View File

@ -1,75 +0,0 @@
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
*/
package org.owasp.webgoat.service;
/**
* <p>ExceptionInfo class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
public class ExceptionInfo {
private String url;
private String message;
/**
* <p>Getter for the field <code>url</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getUrl() {
return url;
}
/**
* <p>Setter for the field <code>url</code>.</p>
*
* @param url a {@link java.lang.String} object.
*/
public void setUrl(String url) {
this.url = url;
}
/**
* <p>Getter for the field <code>message</code>.</p>
*
* @return a {@link java.lang.String} object.
*/
public String getMessage() {
return message;
}
/**
* <p>Setter for the field <code>message</code>.</p>
*
* @param message a {@link java.lang.String} object.
*/
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -5,17 +5,18 @@
*/
package org.owasp.webgoat.service;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.model.Hint;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.Hint;
import org.owasp.webgoat.session.WebSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static java.util.stream.Collectors.toList;
/**
* <p>HintService class.</p>
@ -23,74 +24,59 @@ import org.springframework.web.servlet.ModelAndView;
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class HintService extends BaseService {
@RestController
public class HintService {
public static final String URL_HINTS_MVC = "/service/hint.mvc";
private final WebSession webSession;
public HintService(WebSession webSession) {
this.webSession = webSession;
}
/**
* Returns hints for current lesson
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.util.List} object.
*/
@RequestMapping(value = "/hint.mvc", produces = "application/json")
public @ResponseBody
List<Hint> showHint(HttpSession session) {
List<Hint> listHints = new ArrayList<Hint>();
WebSession ws = getWebSession(session);
AbstractLesson l = ws.getCurrentLesson();
if (l == null) {
return listHints;
}
List<String> hints = (l.getCategory().equals(Category.CHALLENGE)) ? null : l.getHintsPublic(ws);
@GetMapping(path = URL_HINTS_MVC, produces = "application/json")
@ResponseBody
public List<Hint> showHint() {
AbstractLesson l = webSession.getCurrentLesson();
List<Hint> hints = createLessonHints(l);
hints.addAll(createAssignmentHints(l));
return hints;
if (hints == null) {
return listHints;
}
int idx = 0;
for (String h : hints) {
private List<Hint> createLessonHints(AbstractLesson l) {
if ( l != null ) {
return l.getHints().stream().map(h -> createHint(h, l.getName(), null)).collect(toList());
}
return Lists.newArrayList();
}
private List<Hint> createAssignmentHints(AbstractLesson l) {
List<Hint> hints = Lists.newArrayList();
if ( l != null) {
List<Assignment> assignments = l.getAssignments();
assignments.stream().forEach(a -> { a.getHints(); createHints(a, hints);});
}
return hints;
}
private void createHints(Assignment a, List<Hint> hints) {
hints.addAll(a.getHints().stream().map(h -> createHint(h, null, a.getPath())).collect(toList()));
}
private Hint createHint(String hintText, String lesson, String assignmentName) {
Hint hint = new Hint();
hint.setHint(h);
hint.setLesson(l.getName());
hint.setNumber(idx);
listHints.add(hint);
idx++;
hint.setHint(hintText);
if (lesson != null) {
hint.setLesson(lesson);
} else {
hint.setAssignmentPath(assignmentName);
}
return listHints;
}
/**
* <p>showHintsAsHtml.</p>
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.springframework.web.servlet.ModelAndView} object.
*/
@RequestMapping(value = "/hint_widget.mvc", produces = "text/html")
public
ModelAndView showHintsAsHtml(HttpSession session) {
ModelAndView model = new ModelAndView();
List<Hint> listHints = new ArrayList<Hint>();
model.addObject("hints", listHints);
WebSession ws = getWebSession(session);
AbstractLesson l = ws.getCurrentLesson();
if (l == null) {
return model;
}
List<String> hints;
hints = l.getHintsPublic(ws);
if (hints == null) {
return model;
}
int idx = 0;
for (String h : hints) {
Hint hint = new Hint();
hint.setHint(h);
hint.setLesson(l.getName());
hint.setNumber(idx);
listHints.add(hint);
idx++;
}
model.setViewName("widgets/hints");
return model;
return hint;
}
}

View File

@ -29,13 +29,9 @@
*/
package org.owasp.webgoat.service;
import java.util.HashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.session.LabelDebugger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -44,6 +40,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
/**
* <p>LabelDebugService class.</p>
*
@ -51,29 +50,27 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @version $Id: $Id
*/
@Controller
public class LabelDebugService extends BaseService {
@Slf4j
@AllArgsConstructor
public class LabelDebugService {
private static final String URL_DEBUG_LABELS_MVC = "/debug/labels.mvc";
private static final String URL_DEBUG_LABELS_MVC = "/service/debug/labels.mvc";
private static final String KEY_ENABLED = "enabled";
private static final String KEY_SUCCESS = "success";
private static final Logger logger = LoggerFactory.getLogger(LabelDebugService.class);
@Autowired
private LabelDebugger labelDebugger;
/**
* Checks if debugging of labels is enabled or disabled
*
* @return a {@link org.springframework.http.ResponseEntity} object.
*/
@RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(path = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
ResponseEntity<Map<String, Object>> checkDebuggingStatus() {
logger.debug("Checking label debugging, it is " + labelDebugger.isEnabled()); // FIXME parameterize
log.debug("Checking label debugging, it is {}", labelDebugger.isEnabled());
Map<String, Object> result = createResponse(labelDebugger.isEnabled());
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**
@ -85,10 +82,10 @@ public class LabelDebugService extends BaseService {
@RequestMapping(value = URL_DEBUG_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE, params = KEY_ENABLED)
public @ResponseBody
ResponseEntity<Map<String, Object>> setDebuggingStatus(@RequestParam("enabled") Boolean enabled) throws Exception {
logger.debug("Setting label debugging to " + labelDebugger.isEnabled()); // FIXME parameterize
log.debug("Setting label debugging to {} ", labelDebugger.isEnabled());
Map<String, Object> result = createResponse(enabled);
labelDebugger.setEnabled(enabled);
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
return new ResponseEntity<>(result, HttpStatus.OK);
}
/**

View File

@ -0,0 +1,92 @@
/**
* *************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*/
package org.owasp.webgoat.service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.i18n.Messages;
import org.owasp.webgoat.i18n.PluginMessages;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Properties;
/**
* <p>LabelService class.</p>
*
* @author zupzup
*/
@RestController
@Slf4j
@AllArgsConstructor
public class LabelService {
public static final String URL_LABELS_MVC = "/service/labels.mvc";
private LocaleResolver localeResolver;
private Messages messages;
private PluginMessages pluginMessages;
/**
* We use Springs session locale resolver which also gives us the option to change the local later on. For
* now it uses the accept-language from the HttpRequest. If this language is not found it will default back
* to messages.properties.
*
* Note although it is possible to use Spring language interceptor we for now opt for this solution, the UI
* will always need to fetch the labels with the new language set by the user. So we don't need to intercept each
* and every request to see if the language param has been set in the request.
*
* @param lang the language to fetch labels for (optional)
* @return a map of labels
* @throws Exception
*/
@GetMapping(path = URL_LABELS_MVC, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<Properties> fetchLabels(@RequestParam(value = "lang", required = false) String lang, HttpServletRequest request) {
if (!StringUtils.isEmpty(lang)) {
Locale locale = Locale.forLanguageTag(lang);
((SessionLocaleResolver)localeResolver).setDefaultLocale(locale);
log.debug("Language provided: {} leads to Locale: {}", lang, locale);
}
Properties allProperties = new Properties();
allProperties.putAll(messages.getMessages());
allProperties.putAll(pluginMessages.getMessages());
return new ResponseEntity<>(allProperties, HttpStatus.OK);
}
}

View File

@ -1,66 +1,36 @@
package org.owasp.webgoat.service;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.model.LessonInfoModel;
import org.owasp.webgoat.lessons.model.LessonMenuItem;
import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@Controller
/**
* <p>LessonInfoService class.</p>
*
* @author dm
* @version $Id: $Id
*/
public class LessonInfoService extends BaseService {
@RestController
@AllArgsConstructor
public class LessonInfoService {
private static final Logger logger = LoggerFactory.getLogger(LessonMenuService.class);
private final WebSession webSession;
/**
* <p>getLessonInfo.</p>
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.owasp.webgoat.lessons.model.LessonInfoModel} object.
* @return a {@link LessonInfoModel} object.
*/
@RequestMapping(value = "/lessoninfo.mvc", produces = "application/json")
@RequestMapping(path = "/service/lessoninfo.mvc", produces = "application/json")
public @ResponseBody
LessonInfoModel getLessonInfo(HttpSession session) {
WebSession webSession = getWebSession(session);
return new LessonInfoModel(webSession);
LessonInfoModel getLessonInfo() {
AbstractLesson lesson = webSession.getCurrentLesson();
return new LessonInfoModel(lesson.getTitle(), false, false, false);
}
/**
* <p>handleException.</p>
*
* @param ex a {@link java.lang.Exception} object.
* @return a {@link java.lang.String} object.
*/
@ExceptionHandler(Exception.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public String handleException(Exception ex) {
return "An error occurred retrieving the LessonInfoModel:" + ex.getMessage();
}
/**
* <p>getLessonInfoModel.</p>
*
* @param webSession a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link org.owasp.webgoat.lessons.model.LessonInfoModel} object.
*/
protected LessonInfoModel getLessonInfoModel(WebSession webSession) {
return new LessonInfoModel(webSession);
}
}

View File

@ -1,50 +1,52 @@
/**
* *************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at
* https://github.com/WebGoat/WebGoat, a repository for free software projects.
*
*/
package org.owasp.webgoat.service;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.lessons.RandomLessonAdapter;
import org.owasp.webgoat.lessons.model.LessonMenuItem;
import org.owasp.webgoat.lessons.model.LessonMenuItemType;
import org.owasp.webgoat.lessons.LessonMenuItem;
import org.owasp.webgoat.lessons.LessonMenuItemType;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.owasp.webgoat.users.LessonTracker;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>LessonMenuService class.</p>
*
@ -52,65 +54,42 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @version $Id: $Id
*/
@Controller
public class LessonMenuService extends BaseService {
@AllArgsConstructor
public class LessonMenuService {
private static final Logger logger = LoggerFactory.getLogger(LessonMenuService.class);
public static final String URL_LESSONMENU_MVC = "/service/lessonmenu.mvc";
private final Course course;
private final WebSession webSession;
private UserTrackerRepository userTrackerRepository;
/**
* Returns the lesson menu which is used to build the left nav
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.util.List} object.
*/
@RequestMapping(value = "/lessonmenu.mvc", produces = "application/json")
public @ResponseBody
List<LessonMenuItem> showLeftNav(HttpSession session) {
List<LessonMenuItem> menu = new ArrayList<LessonMenuItem>();
WebSession ws = getWebSession(session);
// Get the categories, these are the main menu items
Course course = ws.getCourse();
@RequestMapping(path = URL_LESSONMENU_MVC, produces = "application/json")
public
@ResponseBody
List<LessonMenuItem> showLeftNav() {
List<LessonMenuItem> menu = new ArrayList<>();
List<Category> categories = course.getCategories();
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
for (Category category : categories) {
LessonMenuItem categoryItem = new LessonMenuItem();
categoryItem.setName(category.getName());
categoryItem.setType(LessonMenuItemType.CATEGORY);
// check for any lessons for this category
List<AbstractLesson> lessons = ws.getLessons(category);
String role = ws.getRole();
logger.info("Role: " + role);
List<AbstractLesson> lessons = course.getLessons(category);
lessons = lessons.stream().sorted(Comparator.comparing(l -> l.getTitle())).collect(Collectors.toList());
for (AbstractLesson lesson : lessons) {
LessonMenuItem lessonItem = new LessonMenuItem();
lessonItem.setName(lesson.getTitle());
lessonItem.setLink(lesson.getLink());
lessonItem.setType(LessonMenuItemType.LESSON);
if (lesson.isCompleted(ws)) {
lessonItem.setComplete(true);
}
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
lessonItem.setComplete(lessonTracker.isLessonSolved());
categoryItem.addChild(lessonItem);
// Does the lesson have stages
if (lesson instanceof RandomLessonAdapter) {
RandomLessonAdapter rla = (RandomLessonAdapter) lesson;
String[] stages = rla.getStages();
if (stages != null) {
String lessonLink = lesson.getLink();
int stageIdx = 1;
for (String stage : stages) {
LessonMenuItem stageItem = new LessonMenuItem();
stageItem.setName("Stage " + stageIdx + ": " + stage);
// build the link for the stage
String stageLink = lessonLink + "/" + stageIdx;
stageItem.setLink(stageLink);
stageItem.setType(LessonMenuItemType.STAGE);
if (rla.isStageComplete(ws, stage)) {
stageItem.setComplete(true);
}
lessonItem.addChild(stageItem);
stageIdx++;
}
}
}
}
menu.add(categoryItem);
}

View File

@ -29,15 +29,11 @@
*/
package org.owasp.webgoat.service;
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;
import javax.servlet.http.HttpSession;
/**
* <p>LessonPlanService class.</p>
*
@ -45,42 +41,33 @@ import javax.servlet.http.HttpSession;
* @version $Id: $Id
*/
@Controller
public class LessonPlanService extends BaseService {
//TODO remove
public class LessonPlanService {
private final WebSession webSession;
public LessonPlanService(WebSession webSession) {
this.webSession = webSession;
}
/**
* Returns source for current attack
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(value = "/lessonplan.mvc", produces = "application/html")
@RequestMapping(path = "/service/lessonplan.mvc", produces = "application/html")
public @ResponseBody
String showPlan(HttpSession session) {
WebSession ws = getWebSession(session);
String plan = getPlan(ws);
String showPlan() {
String plan = getPlan();
return plan;
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected String getPlan(WebSession s) {
String plan = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isAdmin()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
plan = lesson.getLessonPlan(s);
}
}
if (plan == null) {
plan = "Plan is not available for this lesson.";
}
return plan;
protected String getPlan() {
return "Plan is not available for this lesson.";
}
}

View File

@ -1,54 +1,95 @@
package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.RandomLessonAdapter;
import org.owasp.webgoat.lessons.model.LessonInfoModel;
import org.owasp.webgoat.lessons.Assignment;
import org.owasp.webgoat.lessons.LessonInfoModel;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.util.LabelManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.owasp.webgoat.users.LessonTracker;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Controller
/**
* <p>LessonProgressService class.</p>
*
* @author webgoat
*/
public class LessonProgressService extends BaseService {
@Controller
@AllArgsConstructor
public class LessonProgressService {
private static final Logger logger = LoggerFactory.getLogger(LessonMenuService.class);
private LabelManager labelManager;
@Autowired
public LessonProgressService(final LabelManager labelManager) {
this.labelManager = labelManager;
}
private UserTrackerRepository userTrackerRepository;
private WebSession webSession;
/**
* <p>LessonProgressService.</p>
*
* @param session a {@link HttpSession} object.
* @return a {@link LessonInfoModel} object.
*/
@RequestMapping(value = "/lessonprogress.mvc", produces = "application/json")
@RequestMapping(value = "/service/lessonprogress.mvc", produces = "application/json")
@ResponseBody
public Map getLessonInfo(HttpSession session) {
WebSession webSession = getWebSession(session);
AbstractLesson lesson = webSession.getCurrentLesson();
boolean lessonCompleted = lesson.isCompleted(webSession);
String successMessage = lesson instanceof RandomLessonAdapter ? "Congratulations, you have completed this lab" : labelManager
.get("LessonCompleted");
public Map getLessonInfo() {
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
LessonTracker lessonTracker = userTracker.getLessonTracker(webSession.getCurrentLesson());
Map json = Maps.newHashMap();
String successMessage = "";
boolean lessonCompleted = false;
if (lessonTracker != null) {
lessonCompleted = lessonTracker.isLessonSolved();
successMessage = "LessonCompleted"; //@todo we still use this??
}
json.put("lessonCompleted", lessonCompleted);
json.put("successMessage", successMessage);
return json;
}
/**
* Endpoint for fetching the complete lesson overview which informs the user about whether all the assignments are solved.
* Used as the last page of the lesson to generate a lesson overview.
*
* @return list of assignments
*/
@RequestMapping(value = "/service/lessonoverview.mvc", produces = "application/json")
@ResponseBody
public List<LessonOverview> lessonOverview() {
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
AbstractLesson currentLesson = webSession.getCurrentLesson();
List<LessonOverview> result = Lists.newArrayList();
if ( currentLesson != null ) {
LessonTracker lessonTracker = userTracker.getLessonTracker(currentLesson);
result = toJson(lessonTracker.getLessonOverview());
}
return result;
}
private List<LessonOverview> toJson(Map<Assignment, Boolean> map) {
ArrayList<LessonOverview> result = Lists.newArrayList();
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
result.add(new LessonOverview(entry.getKey(), entry.getValue()));
}
return result;
}
@AllArgsConstructor
@Getter
//Jackson does not really like returning a map of <Assignment, Boolean> directly, see http://stackoverflow.com/questions/11628698/can-we-make-object-as-key-in-map-when-using-json
//so creating intermediate object is the easiest solution
private static class LessonOverview {
private Assignment assignment;
private Boolean solved;
}
}

View File

@ -1,46 +1,38 @@
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
/**
* <p>LessonTitleService class.</p>
*
* @version $Id: $Id
* @author dm
* @version $Id: $Id
*/
public class LessonTitleService extends BaseService {
@Controller
public class LessonTitleService {
private final WebSession webSession;
public LessonTitleService(final WebSession webSession) {
this.webSession = webSession;
}
/**
* Returns the title for the current attack
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.lang.String} object.
*/
@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;
@RequestMapping(path = "/service/lessontitle.mvc", produces = "application/html")
public
@ResponseBody
String showPlan() {
AbstractLesson lesson = webSession.getCurrentLesson();
return lesson != null ? lesson.getTitle() : "";
}
}

View File

@ -29,18 +29,16 @@
*/
package org.owasp.webgoat.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.lessons.model.RequestParameter;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import org.owasp.webgoat.lessons.RequestParameter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.util.Collections;
import java.util.List;
/**
* <p>ParameterService class.</p>
*
@ -48,9 +46,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @version $Id: $Id
*/
@Controller
public class ParameterService extends BaseService {
final Logger logger = LoggerFactory.getLogger(ParameterService.class);
public class ParameterService {
/**
* Returns request parameters for last attack
@ -58,11 +54,11 @@ public class ParameterService extends BaseService {
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.util.List} object.
*/
@RequestMapping(value = "/parameter.mvc", produces = "application/json")
@RequestMapping(path = "/service/parameter.mvc", produces = "application/json")
public @ResponseBody
List<RequestParameter> showParameters(HttpSession session) {
WebSession ws = getWebSession(session);
List<RequestParameter> listParms = ws.getParmsOnLastRequest();
//// TODO: 11/6/2016 to decide not sure about the role in WebGoat 8
List<RequestParameter> listParms = Lists.newArrayList();
Collections.sort(listParms);
return listParms;
}

View File

@ -29,16 +29,6 @@
*/
package org.owasp.webgoat.service;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -46,6 +36,10 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* <p>PluginReloadService class.</p>
*
@ -53,9 +47,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @version $Id: $Id
*/
@Controller
public class PluginReloadService extends BaseService {
private static final Logger logger = LoggerFactory.getLogger(PluginReloadService.class);
public class PluginReloadService {
/**
* Reload all the plugins
@ -63,20 +55,21 @@ public class PluginReloadService extends BaseService {
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link org.springframework.http.ResponseEntity} object.
*/
@RequestMapping(value = "/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE)
@RequestMapping(path = "/service/reloadplugins.mvc", produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
ResponseEntity<Map<String, Object>> reloadPlugins(HttpSession session) {
WebSession webSession = (WebSession) session.getAttribute(WebSession.SESSION);
logger.debug("Loading plugins into cache");
String pluginPath = session.getServletContext().getRealPath("plugin_lessons");
String targetPath = session.getServletContext().getRealPath("plugin_extracted");
new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).copyJars();
webSession.getCourse().loadLessonFromPlugin(session.getServletContext());
// WebSession webSession = (WebSession) session.getAttribute(WebSession.SESSION);
//
// logger.debug("Loading plugins into cache");
// String pluginPath = session.getServletContext().getRealPath("plugin_lessons");
// String targetPath = session.getServletContext().getRealPath("plugin_extracted");
// //TODO fix me
// //new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).copyJars();
// //webSession.getCourse().createLessonsFromPlugins();
Map<String, Object> result = new HashMap<String, Object>();
result.put("success", true);
result.put("message", "Plugins reloaded");
return new ResponseEntity<Map<String, Object>>(result, HttpStatus.OK);
return new ResponseEntity<>(result, HttpStatus.OK);
}
}

View File

@ -0,0 +1,104 @@
/**
* *************************************************************************************************
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* Getting Source ==============
* <p>
* Source for this application is maintained at
* https://github.com/WebGoat/WebGoat, a repository for free software projects.
*/
package org.owasp.webgoat.service;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.Course;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.LessonTracker;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
/**
* <p>ReportCardService</p>
*
* @author nbaars
* @version $Id: $Id
*/
@Controller
@AllArgsConstructor
public class ReportCardService {
private final WebSession webSession;
private final UserTrackerRepository userTrackerRepository;
private final Course course;
/**
* Endpoint which generates the report card for the current use to show the stats on the solved lessons
*/
@GetMapping(path = "/service/reportcard.mvc", produces = "application/json")
@ResponseBody
public ReportCard reportCard() {
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
List<AbstractLesson> lessons = course.getLessons();
ReportCard reportCard = new ReportCard();
reportCard.setTotalNumberOfLessons(course.getTotalOfLessons());
reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments());
reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved());
reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved());
for (AbstractLesson lesson : lessons) {
LessonTracker lessonTracker = userTracker.getLessonTracker(lesson);
LessonStatistics lessonStatistics = new LessonStatistics();
lessonStatistics.setName(lesson.getTitle());
lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts());
lessonStatistics.setSolved(lessonTracker.isLessonSolved());
reportCard.lessonStatistics.add(lessonStatistics);
}
return reportCard;
}
@Getter
@Setter
private class ReportCard {
private int totalNumberOfLessons;
private int totalNumberOfAssignments;
private int solvedLessons;
private int numberOfAssignmentsSolved;
private int numberOfLessonsSolved;
private List<LessonStatistics> lessonStatistics = Lists.newArrayList();
}
@Setter
@Getter
private class LessonStatistics {
private String name;
private boolean solved;
private int numberOfAttempts;
}
}

View File

@ -1,39 +1,39 @@
/***************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
*/
package org.owasp.webgoat.service;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.session.WebSession;
import org.owasp.webgoat.users.UserTracker;
import org.owasp.webgoat.users.UserTrackerRepository;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpSession;
/**
* <p>RestartLessonService class.</p>
*
@ -41,20 +41,26 @@ import javax.servlet.http.HttpSession;
* @version $Id: $Id
*/
@Controller
public class RestartLessonService extends BaseService {
@AllArgsConstructor
@Slf4j
public class RestartLessonService {
private final WebSession webSession;
private UserTrackerRepository userTrackerRepository;
/**
* Returns current lesson
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(value = "/restartlesson.mvc")
@RequestMapping(path = "/service/restartlesson.mvc", produces = "text/text")
@ResponseStatus(value = HttpStatus.OK)
public void restartLesson(HttpSession session) {
WebSession ws = getWebSession(session);
int currentScreen = ws.getCurrentScreen();
if(currentScreen > 0){
ws.restartLesson(currentScreen);
}
public void restartLesson() {
AbstractLesson al = webSession.getCurrentLesson();
log.debug("Restarting lesson: " + al);
UserTracker userTracker = userTrackerRepository.findOne(webSession.getUserName());
userTracker.reset(al);
userTrackerRepository.save(userTracker);
}
}

View File

@ -5,16 +5,17 @@
*/
package org.owasp.webgoat.service;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* <p>SessionService class.</p>
@ -23,7 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
* @version $Id: $Id
*/
@Controller
public class SessionService extends BaseService {
public class SessionService {
/**
* Returns hints for current lesson
@ -32,7 +33,7 @@ public class SessionService extends BaseService {
* @param request a {@link javax.servlet.http.HttpServletRequest} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(value = "/session.mvc", produces = "application/json")
@RequestMapping(path = "/service/session.mvc", produces = "application/json")
public @ResponseBody
String showSession(HttpServletRequest request, HttpSession session) {
StringBuilder sb = new StringBuilder();

View File

@ -1,86 +0,0 @@
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
*/
package org.owasp.webgoat.service;
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;
import javax.servlet.http.HttpSession;
/**
* <p>SolutionService class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class SolutionService extends BaseService {
/**
* Returns solution for current attack
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(value = "/solution.mvc", produces = "text/html")
public @ResponseBody
String showSolution(HttpSession session) {
WebSession ws = getWebSession(session);
String source = getSolution(ws);
return source;
}
/**
* <p>getSolution.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @return a {@link java.lang.String} object.
*/
protected String getSolution(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isAdmin()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getSolution(s);
}
}
if (source == null) {
return "Solution is not available. Contact " + s.getWebgoatContext().getFeedbackAddressHTML();
}
return source;
}
}

View File

@ -1,94 +0,0 @@
/**
* *************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project
* utility. For details, please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository
* for free software projects.
*
*/
package org.owasp.webgoat.service;
import org.apache.commons.lang3.StringEscapeUtils;
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;
import javax.servlet.http.HttpSession;
import static org.owasp.webgoat.LessonSource.END_SOURCE_SKIP;
import static org.owasp.webgoat.LessonSource.START_SOURCE_SKIP;
/**
* <p>SourceService class.</p>
*
* @author rlawson
* @version $Id: $Id
*/
@Controller
public class SourceService extends BaseService {
/**
* Returns source for current attack
*
* @param session a {@link javax.servlet.http.HttpSession} object.
* @return a {@link java.lang.String} object.
*/
@RequestMapping(value = "/source.mvc", produces = "application/text")
public @ResponseBody
String showSource(HttpSession session) {
WebSession ws = getWebSession(session);
String source = getSource(ws);
if (source == null) {
source = "No source listing found";
}
return StringEscapeUtils.escapeHtml4(source);
}
/**
* Description of the Method
*
* @param s Description of the Parameter
* @return Description of the Return Value
*/
protected String getSource(WebSession s) {
String source = null;
int scr = s.getCurrentScreen();
Course course = s.getCourse();
if (s.isUser() || s.isAdmin()) {
AbstractLesson lesson = course.getLesson(s, scr, AbstractLesson.USER_ROLE);
if (lesson != null) {
source = lesson.getRawSource(s);
}
}
if (source == null) {
return "Source code is not available for this lesson.";
}
return source.replaceAll("(?s)" + START_SOURCE_SKIP + ".*" + END_SOURCE_SKIP,
"Code Section Deliberately Omitted");
}
}

View File

@ -1,175 +1,58 @@
package org.owasp.webgoat.session;
import org.owasp.webgoat.HammerHead;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.plugins.Plugin;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContext;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.owasp.webgoat.HammerHead;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.plugins.LegacyLoader;
import org.owasp.webgoat.plugins.Plugin;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.stream.Collectors.toList;
/**
* ************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Bruce Mayhew <a href="http://code.google.com/p/webgoat">WebGoat</a>
* @since October 28, 2003
* @version $Id: $Id
* @since October 28, 2003
*/
@Slf4j
@AllArgsConstructor
public class Course {
final Logger logger = LoggerFactory.getLogger(Course.class);
private final List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
private WebgoatProperties properties = null;
private WebgoatContext webgoatContext;
/**
* <p>Constructor for Course.</p>
*/
public Course() {
try {
properties = new WebgoatProperties(PROPERTIES_FILENAME);
} catch (IOException e) {
logger.error("Error loading webgoat properties", e);
}
}
/**
* 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.contains("/")) {
fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length());
}
if (fileName.contains(".")) {
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) {
StringBuilder sb = new StringBuilder();
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;
}
private List<AbstractLesson> lessons = new LinkedList<>();
/**
* Gets the categories attribute of the Course object
*
* @return The categories value
*/
public List getCategories() {
List<Category> categories = new ArrayList<Category>();
for (AbstractLesson lesson : lessons) {
if (!categories.contains(lesson.getCategory())) {
categories.add(lesson.getCategory());
}
}
Collections.sort(categories);
return categories;
public List<Category> getCategories() {
return lessons.parallelStream().map(l -> l.getCategory()).distinct().sorted().collect(toList());
}
/**
@ -178,202 +61,42 @@ public class Course {
* @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 normally 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 s a {@link org.owasp.webgoat.session.WebSession} object.
* @param lessonId Description of the Parameter
* @param roles a {@link java.util.List} object.
* @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();
if (lesson.getScreenId() == lessonId && roles.contains(lesson.getRole())) {
return lesson;
}
}
return null;
}
/**
* <p>getLesson.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param lessonId a int.
* @param role a {@link java.lang.String} object.
* @return a {@link org.owasp.webgoat.lessons.AbstractLesson} object.
*/
public AbstractLesson getLesson(WebSession s, int lessonId, String role) {
List<String> roles = new ArrayList<String>();
roles.add(role);
return getLesson(s, lessonId, roles);
return getLessons(getCategories().get(0)).get(0);
}
/**
* <p>Getter for the field <code>lessons</code>.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param role a {@link java.lang.String} object.
* @return a {@link java.util.List} object.
*/
public List<AbstractLesson> getLessons(WebSession s, String role) {
List<String> roles = new ArrayList<String>();
roles.add(role);
return getLessons(s, roles);
}
/**
* Gets the lessons attribute of the Course object
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param roles a {@link java.util.List} object.
* @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>();
for (AbstractLesson lesson : lessons) {
if (lesson.getCategory().equals(category) && roles.contains(lesson.getRole())) {
lessonList.add(lesson);
}
}
Collections.sort(lessonList);
return lessonList;
public List<AbstractLesson> getLessons() {
return this.lessons;
}
/**
* <p>Getter for the field <code>lessons</code>.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param category a {@link org.owasp.webgoat.lessons.Category} object.
* @param role a {@link java.lang.String} object.
* @return a {@link java.util.List} object.
*/
public List getLessons(WebSession s, Category category, String role) {
List<String> roles = new ArrayList<String>();
roles.add(role);
return getLessons(s, category, roles);
public List<AbstractLesson> getLessons(Category category) {
return this.lessons.stream().filter(l -> l.getCategory() == category).sorted().collect(toList());
}
/**
* <p>Getter for the field <code>lessons</code>.</p>
*
* @param s a {@link org.owasp.webgoat.session.WebSession} object.
* @param category a {@link org.owasp.webgoat.lessons.Category} object.
* @param roles a {@link java.util.List} object.
* @return a {@link java.util.List} object.
*/
public List<AbstractLesson> getLessons(WebSession s, Category category, List<String> roles) {
if (s.isHackedAdmin()) {
roles.add(AbstractLesson.HACKED_ADMIN_ROLE);
}
return getLessons(category, roles);
public void setLessons(List<AbstractLesson> lessons) {
this.lessons = lessons;
}
/**
* <p>getLesson.</p>
*
* @param lessonId a int.
* @return a {@link org.owasp.webgoat.lessons.AbstractLesson} object.
*/
public AbstractLesson getLesson(int lessonId) {
for (AbstractLesson l : lessons) {
if (l.getScreenId() == lessonId) {
return l;
}
}
return null;
public int getTotalOfLessons() {
return this.lessons.size();
}
/**
* <p>loadLessonFromPlugin.</p>
*
* @param context a {@link javax.servlet.ServletContext} object.
*/
public void loadLessonFromPlugin(ServletContext context) {
logger.debug("Loading plugins into cache");
String pluginPath = context.getRealPath("plugin_lessons");
String targetPath = context.getRealPath("plugin_extracted");
if (pluginPath == null) {
logger.error("Plugins directory {} not found", pluginPath);
return;
}
lessons.clear();
List<Plugin> plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins();
for (Plugin plugin : plugins) {
try {
AbstractLesson lesson = plugin.getLesson().get();
lesson.setWebgoatContext(webgoatContext);
lesson.update(properties);
if (!lesson.getHidden()) {
lessons.add(lesson);
}
for(Map.Entry<String, File> lessonPlan : plugin.getLessonPlans().entrySet()) {
lesson.setLessonPlanFileName(lessonPlan.getKey(), lessonPlan.getValue().toString());
}
if (plugin.getLessonSolution("en").isPresent()) {
lesson.setLessonSolutionFileName(plugin.getLessonSolution("en").get().toString());
}
if (plugin.getLessonSource().isPresent()) {
lesson.setSourceFileName(plugin.getLessonSource().get().toString());
}
} catch (Exception e) {
logger.error("Error in loadLessons: ", e);
}
}
public int getTotalOfAssignments() {
final int[] total = {0};
this.lessons.stream().forEach(l -> total[0] = total[0] + l.getAssignments().size());
return total[0];
}
/**
* Description of the Method
*
* @param webgoatContext a {@link org.owasp.webgoat.session.WebgoatContext} object.
* @param path Description of the Parameter
* @param context Description of the Parameter
*/
public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path) {
logger.info("Loading courses: " + path);
this.webgoatContext = webgoatContext;
loadLessonFromPlugin(context);
LegacyLoader loader = new LegacyLoader();
lessons.addAll(loader.loadLessons(webgoatContext, context, path, properties));
}
}

View File

@ -4,73 +4,108 @@ package org.owasp.webgoat.session;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import org.owasp.webgoat.lessons.AbstractLesson;
/**
* ************************************************************************************************
*
*
* <p>
* <p>
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* <p>
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* 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.
*
* <p>
* Getting Source ==============
*
* <p>
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @version $Id: $Id
*/
public class CreateDB
{
public class CreateDB {
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
*
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createMessageTable(Connection connection) throws SQLException
{
private void createServersTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Drop servers table
try {
String dropTable = "DROP TABLE servers";
statement.executeUpdate(dropTable);
} catch (SQLException e) {
System.out.println("Info - Could not drop servers table");
}
// Create the new table
try {
String createTableStatement = "CREATE TABLE servers"
+ " (" + "id varchar(10),"
+ "hostname varchar(20),"
+ "ip varchar(20),"
+ "mac varchar(20),"
+ "status varchar(20),"
+ "description varchar(40)"
+ ")";
statement.executeUpdate(createTableStatement);
String insertData1 = "INSERT INTO servers VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server')";
String insertData2 = "INSERT INTO servers VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server')";
String insertData3 = "INSERT INTO servers VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server')";
String insertData4 = "INSERT INTO servers VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server')";
String insertData5 = "INSERT INTO servers VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server')";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
statement.executeUpdate(insertData3);
statement.executeUpdate(insertData4);
statement.executeUpdate(insertData5);
} catch (SQLException e) {
System.out.println("Error creating product table " + e.getLocalizedMessage());
}
}
/**
* Description of the Method
*
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createMessageTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Drop admin user table
try
{
try {
String dropTable = "DROP TABLE messages";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop message database");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE messages (" + "num int not null," + "title varchar(50),"
+ "message varchar(200)," + "user_name varchar(50) not null, " + "lesson_type varchar(50) not null"
+ ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating message database " + e.getLocalizedMessage());
}
}
@ -79,35 +114,27 @@ public class CreateDB
* Description of the Method
*
* @param connection Description of the Parameter
*
* @exception SQLException Description of the Exception
* @throws SQLException Description of the Exception
*/
private void createMFEImagesTable(Connection connection) throws SQLException
{
private void createMFEImagesTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Drop mfe_images table
try
{
try {
String dropTable = "DROP TABLE mfe_images";
statement.executeUpdate(dropTable);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop mfe_images table from database");
}
// Create the new mfe_images table
try
{
try {
String createTableStatement = "CREATE TABLE mfe_images ("
+ "user_name varchar(50) not null, "
+ "image_relative_url varchar(50) not null"
+ ")";
statement.executeUpdate(createTableStatement);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating mfe_images table in database " + e.getLocalizedMessage());
}
@ -116,35 +143,27 @@ public class CreateDB
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
*
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createProductTable(Connection connection) throws SQLException
{
private void createProductTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Drop admin user table
try
{
try {
String dropTable = "DROP TABLE product_system_data";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop product table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE product_system_data ("
+ "productid varchar(6) not null primary key," + "product_name varchar(20)," + "price varchar(10)"
+ ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating product table " + e.getLocalizedMessage());
}
@ -164,34 +183,26 @@ public class CreateDB
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
*
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createUserAdminTable(Connection connection) throws SQLException
{
private void createUserAdminTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Drop admin user table
try
{
try {
String dropTable = "DROP TABLE user_system_data";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop user admin table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE user_system_data (" + "userid varchar(5) not null primary key,"
+ "user_name varchar(12)," + "password varchar(10)," + "cookie varchar(30)" + ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating user admin table " + e.getLocalizedMessage());
}
@ -211,35 +222,27 @@ public class CreateDB
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
*
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createUserDataTable(Connection connection) throws SQLException
{
private void createUserDataTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE user_data";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop user table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE user_data (" + "userid int not null,"
+ "first_name varchar(20)," + "last_name varchar(20)," + "cc_number varchar(30),"
+ "cc_type varchar(10)," + "cookie varchar(20)," + "login_count int" + ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating user table " + e.getLocalizedMessage());
}
@ -257,6 +260,8 @@ public class CreateDB
String insertData11 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','123609789','MC',' ',0)";
String insertData12 = "INSERT INTO user_data VALUES (15603,'Peter','Sand','338893453333','AMEX',' ',0)";
String insertData13 = "INSERT INTO user_data VALUES (15613,'Joesph','Something','33843453533','AMEX',' ',0)";
String insertData14 = "INSERT INTO user_data VALUES (15837,'Chaos','Monkey','32849386533','CM',' ',0)";
String insertData15 = "INSERT INTO user_data VALUES (19204,'Mr','Goat','33812953533','VISA',' ',0)";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
statement.executeUpdate(insertData3);
@ -270,64 +275,54 @@ public class CreateDB
statement.executeUpdate(insertData11);
statement.executeUpdate(insertData12);
statement.executeUpdate(insertData13);
statement.executeUpdate(insertData14);
statement.executeUpdate(insertData15);
}
private void createLoginTable(Connection connection) throws SQLException
{
private void createLoginTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE user_login";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop user_login table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE user_login (" + "userid varchar(5),"
+ "webgoat_user varchar(20)" + ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating user_login table " + e.getLocalizedMessage());
}
}
// creates the table pins which is used in the blind sql injection lesson
private void createBlindSQLLessonTable(Connection connection) throws SQLException
{
private void createBlindSQLLessonTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE pins";
statement.executeUpdate(dropTable);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop pins table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE pins ("
+ "cc_number varchar(30),"
+ "pin int,"
+ "name varchar(20)"
+ ")";
statement.executeUpdate(createTableStatement);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating pins table " + e.getLocalizedMessage());
}
@ -348,32 +343,25 @@ public class CreateDB
// creates the table salaries which is used in the lessons
// which add or modify data using sql injection
private void createModifyWithSQLLessonTable(Connection connection) throws SQLException
{
private void createModifyWithSQLLessonTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE salaries";
statement.executeUpdate(dropTable);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop salaries table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE salaries ("
+ "userid varchar(50),"
+ "salary int"
+ ")";
statement.executeUpdate(createTableStatement);
}
catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating salaries table " + e.getLocalizedMessage());
}
@ -395,35 +383,27 @@ public class CreateDB
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
*
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
*/
private void createWeatherDataTable(Connection connection) throws SQLException
{
private void createWeatherDataTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE weather_data";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop weather table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE weather_data (" + "station int not null,"
+ "name varchar(20) not null," + "state char(2) not null," + "min_temp int not null,"
+ "max_temp int not null" + ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating weather table " + e.getLocalizedMessage());
}
@ -448,30 +428,25 @@ public class CreateDB
* @param connection
* @throws SQLException
*/
private void createTanUserDataTable(Connection connection) throws SQLException
{
private void createTanUserDataTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE user_data_tan";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop user_data_tan table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE user_data_tan (" + "userid int not null,"
+ "first_name varchar(20)," + "last_name varchar(20)," + "cc_number varchar(30),"
+ "cc_type varchar(10)," + "cookie varchar(20)," + "login_count int," + "password varchar(20)"
+ ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating user_data_tan table " + e.getLocalizedMessage());
}
@ -491,28 +466,23 @@ public class CreateDB
* @param connection
* @throws SQLException
*/
private void createTanTable(Connection connection) throws SQLException
{
private void createTanTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
// Delete table if there is one
try
{
try {
String dropTable = "DROP TABLE tan";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop tan table");
}
// Create the new table
try
{
try {
String createTableStatement = "CREATE TABLE tan (" + "userid int not null," + "tanNr int," + "tanValue int"
+ ")";
statement.executeUpdate(createTableStatement);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error creating tan table " + e.getLocalizedMessage());
}
@ -553,22 +523,18 @@ public class CreateDB
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
private void createEmployeeTable(Connection connection) throws SQLException
{
private void createEmployeeTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
try
{
try {
String dropTable = "DROP TABLE employee";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop employee table");
}
// Create Table
try
{
try {
String createTable = "CREATE TABLE employee ("
// + "userid INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"
+ "userid INT NOT NULL PRIMARY KEY," + "first_name VARCHAR(20)," + "last_name VARCHAR(20),"
@ -583,8 +549,7 @@ public class CreateDB
+ ")";
statement.executeUpdate(createTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error: unable to create employee table " + e.getLocalizedMessage());
}
@ -650,27 +615,22 @@ public class CreateDB
}
private void createRolesTable(Connection connection) throws SQLException
{
private void createRolesTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
try
{
try {
String dropTable = "DROP TABLE roles";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop roles table");
}
try
{
try {
String createTable = "CREATE TABLE roles (" + "userid INT NOT NULL," + "role VARCHAR(10) NOT NULL,"
+ "PRIMARY KEY (userid, role)" + ")";
statement.executeUpdate(createTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error: Unable to create role table: " + e.getLocalizedMessage());
}
@ -701,27 +661,22 @@ public class CreateDB
statement.executeUpdate(insertData12);
}
private void createAuthTable(Connection connection) throws SQLException
{
private void createAuthTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
try
{
try {
String dropTable = "DROP TABLE auth";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop auth table");
}
try
{
try {
String createTable = "CREATE TABLE auth (" + "role VARCHAR(10) NOT NULL,"
+ "functionid VARCHAR(20) NOT NULL," + "PRIMARY KEY (role, functionid)" + ")";
statement.executeUpdate(createTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error: unable to create auth table: " + e.getLocalizedMessage());
}
@ -759,16 +714,16 @@ public class CreateDB
String insertData25_1 = "INSERT INTO auth VALUES('admin', 'SearchStaff')";
String insertData25_2 = "INSERT INTO auth VALUES('admin', 'FindProfile')";
// Add a permission for the webgoat role to see the source.
// The challenge(s) will change the default role to "challenge"
String insertData26 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOURCE
+ "')";
String insertData27 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWHINTS
+ "')";
// // Add a permission for the webgoat role to see the source.
// // The challenge(s) will change the default role to "challenge"
// String insertData26 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOURCE
// + "')";
// String insertData27 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWHINTS
// + "')";
// Add a permission for the webgoat role to see the solution.
// The challenge(s) will change the default role to "challenge"
String insertData28 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOLUTION
+ "')";
// String insertData28 = "INSERT INTO auth VALUES('" + AbstractLesson.USER_ROLE + "','" + WebSession.SHOWSOLUTION
// + "')";
statement.executeUpdate(insertData1);
statement.executeUpdate(insertData2);
@ -803,32 +758,27 @@ public class CreateDB
statement.executeUpdate(insertData25);
statement.executeUpdate(insertData25_1);
statement.executeUpdate(insertData25_2);
statement.executeUpdate(insertData26);
statement.executeUpdate(insertData27);
statement.executeUpdate(insertData28);
//statement.executeUpdate(insertData26);
//statement.executeUpdate(insertData27);
//statement.executeUpdate(insertData28);
}
private void createOwnershipTable(Connection connection) throws SQLException
{
private void createOwnershipTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
try
{
try {
String dropTable = "DROP TABLE ownership";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop ownership table");
}
try
{
try {
String createTable = "CREATE TABLE ownership (" + "employer_id INT NOT NULL," + "employee_id INT NOT NULL,"
+ "PRIMARY KEY (employee_id, employer_id)" + ")";
statement.executeUpdate(createTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error: unable to create ownership table: " + e.getLocalizedMessage());
}
@ -952,29 +902,24 @@ public class CreateDB
* Start creation of data for WebServices labs
*/
private void createTransactionTable(Connection connection) throws SQLException
{
private void createTransactionTable(Connection connection) throws SQLException {
Statement statement = connection.createStatement();
try
{
try {
String dropTable = "DROP TABLE transactions";
statement.executeUpdate(dropTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Info - Could not drop transactions table");
}
try
{
try {
String createTable = "CREATE TABLE Transactions (" + "userName VARCHAR(16) NOT NULL, "
+ "sequence INTEGER NOT NULL, " + "from_account VARCHAR(16) NOT NULL, "
+ "to_account VARCHAR(16) NOT NULL, " + "transactionDate TIMESTAMP NOT NULL, "
+ "description VARCHAR(255) NOT NULL, " + "amount INTEGER NOT NULL" + ")";
statement.executeUpdate(createTable);
} catch (SQLException e)
{
} catch (SQLException e) {
System.out.println("Error: unable to create transactions table: " + e.getLocalizedMessage());
throw e;
}
@ -989,34 +934,31 @@ public class CreateDB
"'jeff', 6, '934-2002-3485', '783-2409-8234', '2008-02-01 21:40:00', 'Vet', '250'",
"'jeff', 7, '934-2002-3485', '634-5879-0345', '2008-02-19 21:41:00', 'Doctor', '800'",
"'jeff', 8, '934-2002-3485', '435-4325-3358', '2008-02-20 21:42:00', 'X-rays', '200'",};
try
{
for (int i = 0; i < data.length; i++)
{
try {
for (int i = 0; i < data.length; i++) {
statement.executeUpdate("INSERT INTO Transactions VALUES (" + data[i] + ");");
}
} catch (SQLException sqle)
{
} catch (SQLException sqle) {
System.out.println("Error: Unable to insert transactions: " + sqle.getLocalizedMessage());
int errorCode = sqle.getErrorCode();
System.out.println("Error Code: " + errorCode);
// ignore exceptions for Oracle and SQL Server
if (errorCode != 911 && errorCode != 273) { throw sqle; }
if (errorCode != 911 && errorCode != 273) {
throw sqle;
}
}
}
/**
* Description of the Method
*
* @param connection
* Description of the Parameter
* @exception SQLException
* Description of the Exception
* @param connection Description of the Parameter
* @throws SQLException Description of the Exception
* @throws java.sql.SQLException if any.
*/
public void makeDB(Connection connection) throws SQLException
{
public void makeDB(Connection connection) throws SQLException {
System.out.println("Successful connection to database");
createServersTable(connection);
createUserDataTable(connection);
createLoginTable(connection);
createBlindSQLLessonTable(connection);

View File

@ -1,19 +1,11 @@
package org.owasp.webgoat.session;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.ecs.MultiPartElement;
import org.apache.ecs.html.B;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.Table;
/**
@ -45,6 +37,8 @@ import org.apache.ecs.html.Table;
* @author Jeff Williams <a href="http://www.aspectsecurity.com">Aspect Security</a>
* @version $Id: $Id
*/
//TODO: class we need to refactor to new structure, we can put the connection in the current session of the user
// start using jdbc template
public class DatabaseUtilities
{
@ -128,76 +122,8 @@ public class DatabaseUtilities
private static Connection getHsqldbConnection(String user, WebgoatContext context) throws ClassNotFoundException,
SQLException
{
String url = context.getDatabaseConnectionString().replaceAll("\\$\\{USER\\}", user);
String url = context.getDatabaseConnectionString().replace("{USER}", user);
return DriverManager.getConnection(url, "sa", "");
}
/**
* Description of the Method
*
* @param results
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @param resultsMetaData
* Description of the Parameter
* @return Description of the Return Value
* @exception IOException
* Description of the Exception
* @exception SQLException
* Description of the Exception
* @throws java.io.IOException if any.
* @throws java.sql.SQLException if any.
*/
public static MultiPartElement writeTable(ResultSet results, ResultSetMetaData resultsMetaData) throws IOException,
SQLException
{
int numColumns = resultsMetaData.getColumnCount();
results.beforeFirst();
if (results.next())
{
Table t = new Table(1); // 1 = with border
t.setCellPadding(1);
TR tr = new TR();
for (int i = 1; i < (numColumns + 1); i++)
{
tr.addElement(new TD(new B(resultsMetaData.getColumnName(i))));
}
t.addElement(tr);
results.beforeFirst();
while (results.next())
{
TR row = new TR();
for (int i = 1; i < (numColumns + 1); i++)
{
String str = results.getString(i);
if (str == null) str = "";
row.addElement(new TD(str.replaceAll(" ", "&nbsp;")));
}
t.addElement(row);
}
return (t);
}
else
{
return (new B("Query Successful; however no data was returned from this query."));
}
}
}

View File

@ -1,754 +0,0 @@
package org.owasp.webgoat.session;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.ecs.Element;
import org.apache.ecs.ElementContainer;
import org.apache.ecs.StringElement;
import org.apache.ecs.html.A;
import org.apache.ecs.html.BR;
import org.apache.ecs.html.H3;
import org.apache.ecs.html.Input;
import org.apache.ecs.html.Label;
import org.apache.ecs.html.Option;
import org.apache.ecs.html.P;
import org.apache.ecs.html.Select;
import org.apache.ecs.html.TD;
import org.apache.ecs.html.TH;
import org.apache.ecs.html.TR;
import org.apache.ecs.html.U;
/**
*************************************************************************************************
*
*
* This file is part of WebGoat, an Open Web Application Security Project utility. For details,
* please see http://www.owasp.org/
*
* Copyright (c) 2002 - 20014 Bruce Mayhew
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Getting Source ==============
*
* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software
* projects.
*
* @author Jeff Williams (jeff.williams@aspectsecurity.com)
* @since October 29, 2003
* @version $Id: $Id
*/
public class ECSFactory
{
/**
* Description of the Field
*/
public final static String ON = "On";
/**
* Description of the Field
*/
public final static String PASSWORD = "Password";
/**
* Don't let anyone instantiate this class
*/
private ECSFactory()
{
}
/**
* Description of the Method
*
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeBox(String name, String value)
{
Input i = new Input(Input.CHECKBOX, name, ON);
i.setChecked(value.equals(ON));
return (i);
}
/**
* Description of the Method
*
* @param text
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeButton(String text)
{
Input b = new Input();
b.setType(Input.SUBMIT);
b.setValue(text);
b.setName(Input.SUBMIT);
return (b);
}
/**
* <p>makeButton.</p>
*
* @param text a {@link java.lang.String} object.
* @param onClickFunction a {@link java.lang.String} object.
* @return a {@link org.apache.ecs.Element} object.
*/
public static Element makeButton(String text, String onClickFunction)
{
Input b = (Input) makeButton(text);
b.setOnClick(onClickFunction);
return (b);
}
/**
* Description of the Method
*
* @param labeltext
* Description of the Parameter
* @param value
* Description of the Parameter
* @param e
* Description of the Parameter
* @return Description of the Return Value
*/
public static TR makeField(String labeltext, String value, Element e)
{
TD left = new TD().setAlign("right");
Label label = new Label().addElement(labeltext);
left.addElement(label);
TD right = new TD().setAlign("left");
right.addElement(e);
TR row = new TR();
row.addElement(left);
row.addElement(right);
return (row);
}
/**
* Description of the Method
*
* @param labeltext
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @param size
* Description of the Parameter
* @return Description of the Return Value
*/
public static TR makeField(String labeltext, String name, String value, int size)
{
Input field = new Input().setName(name).setValue(value).setSize(size).setMaxlength(size);
// double check in case someone means to make a * starred out password field
if (name.equals(PASSWORD))
{
field.setType(Input.PASSWORD);
}
return (makeField(labeltext, value, field));
}
/**
* Description of the Method
*
* @param label
* Description of the Parameter
* @param type
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @param alignment
* Description of the Parameter
* @param selected
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeInput(String label, String type, String name, boolean value, boolean selected,
String alignment)
{
return makeInput(label, type, name, new Boolean(value).toString(), selected, alignment);
}
/**
* Description of the Method
*
* @param label
* Description of the Parameter
* @param type
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeInput(String label, String type, String name, String value)
{
return makeInput(label, type, name, value, new Boolean(value).booleanValue(), "RIGHT");
}
/**
* Description of the Method
*
* @param label
* Description of the Parameter
* @param type
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @param alignment
* Description of the Parameter
* @param selected
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeInput(String label, String type, String name, String value, boolean selected,
String alignment)
{
ElementContainer ec = new ElementContainer();
if (!alignment.equalsIgnoreCase("LEFT"))
{
ec.addElement(new StringElement(label));
}
Input input = new Input(type, name, value);
ec.addElement(input);
if (alignment.equalsIgnoreCase("LEFT"))
{
ec.addElement(new StringElement(label));
}
if (type.equalsIgnoreCase("CHECKBOX"))
{
input.setChecked(selected);
}
return (ec);
}
/**
* Description of the Method
*
* @param text
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static A makeLink(String text, String name, String value)
{
String href = "attack?" + name;
if (value.length() > 0)
{
href = href + "=" + value;
}
A a = new A(href);
a.addElement(new U().addElement(text));
a.addAttribute("style", "cursor:hand");
return (a);
}
/**
* Description of the Method
*
* @param text
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static A makeLink(String text, String name, int value)
{
return (makeLink(text, name, Integer.toString(value)));
}
/**
* Description of the Method
*
* @param text
* Description of the Parameter
* @param name
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static A makeLink(String text, String name, boolean value)
{
return (makeLink(text, name, new Boolean(value).toString()));
}
/**
* Description of the Method
*
* @param text
* Description of the Parameter
* @param clickAction
* Description of the Parameter
* @param type
* Description of the Parameter
* @return Description of the Return Value
*/
public static Input makeOnClickInput(String text, String clickAction, String type)
{
Input b = new Input();
b.setType(type);
b.setValue(text);
b.setOnClick(clickAction);
return (b);
}
/**
* Description of the Method
*
* @param labeltext
* Description of the Parameter
* @param value
* Description of the Parameter
* @param e
* Description of the Parameter
* @return Description of the Return Value
*/
public static TR makeOption(String labeltext, String value, Element e)
{
TD left = new TD().setAlign("left").setWidth("10%");
left.addElement(e);
TD right = new TD().setAlign("right");
Label label = new Label().addElement(labeltext);
right.addElement(label);
TR row = new TR();
row.addElement(right);
row.addElement(left);
return (row);
}
/**
* Description of the Method
*
* @param label
* Description of the Parameter
* @param value
* Description of the Parameter
* @return Description of the Return Value
*/
public static Option makeOption(String label, boolean value)
{
Option option = new Option(label, new Boolean(value).toString());
option.setSelected(value);
return option;
}
/**
* Description of the Method
*
* @param line
* Description of the Parameter
* @return Description of the Return Value
*/
private static org.apache.ecs.html.Option makeOption(String line)
{
StringTokenizer st = new StringTokenizer(line, "|");
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option();
String token = "";
if (st.hasMoreTokens())
{
token = st.nextToken();
}
o.addElement(token);
return (o);
}
/**
* Description of the Method
*
* @param name
* Description of the Parameter
* @param options
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makePulldown(String name, List<String> options)
{
Select s = new Select(name);
s.addElement(options.toArray(new String[options.size()]));
return (s);
}
/**
* Description of the Method
*
* @param results
* Description of the Parameter
* @return Description of the Return Value
* @param name a {@link java.lang.String} object.
*/
public static Element makePulldown(String name, String results)
{
Select select = new Select(name);
StringTokenizer st = new StringTokenizer(results, "\n");
if (!st.hasMoreTokens()) {
return (new StringElement("")); }
while (st.hasMoreTokens())
{
String line = st.nextToken();
select.addElement(makeOption(line));
}
select.addElement("-------------------------");
return (select);
}
/**
* Description of the Method
*
* @param name
* Description of the Parameter
* @param list
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param rowsShowing
* Description of the Parameter
* @return Description of the Return Value
*/
public static Select makePulldown(String name, Object[] list, String selected, int rowsShowing)
{
Select select = new Select(name);
for (int loop = 0; loop < list.length; loop++)
{
String value = list[loop].toString();
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option(value, value, value);
if (value.equals(selected))
{
o.setSelected(true);
}
select.addElement(o);
}
select.setSize(rowsShowing);
return select;
}
/**
* Default size of 1 for rows showing in select box.
*
* @param diffNames
* Description of the Parameter
* @param select
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param name
* Description of the Parameter
* @param options
* Description of the Parameter
* @param list
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeSelect(boolean diffNames, Select select, String name, Vector<Option> options,
String[] list, String selected)
{
return makeSelect(diffNames, select, name, options, list, selected, 1);
}
/**
* Description of the Method
*
* @param diffNames
* Description of the Parameter
* @param select
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param name
* Description of the Parameter
* @param options
* Description of the Parameter
* @param list
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param selected
* Description of the Parameter
* @param rowsShowing
* Description of the Parameter
* @return Description of the Return Value
*/
public static Select makeSelect(boolean diffNames, Select select, String name, Vector<Option> options,
String[] list, String selected, int rowsShowing)
{
if (select == null)
{
select = new Select(name);
if (diffNames)
{
for (int loop = 0; loop < list.length; loop += 2)
{
String value = list[loop];
String label = list[loop + 1];
Option o = new Option(value);
if (loop == 0)
{
o.setSelected(true);
}
options.addElement(o);// add to Vector containing all options
select.addElement(o);
select.addElement(label);
}
}
else
{
for (int loop = 0; loop < list.length; loop++)
{
String value = list[loop];
org.apache.ecs.html.Option o = new org.apache.ecs.html.Option(value);
if (loop == 0)
{
o.setSelected(true);
}
options.addElement(o);// add to Vector containing all options
select.addElement(o);
select.addElement(value);
}
}
}
// find selected option and set selected
Iterator i = options.iterator();
while (i.hasNext())
{
org.apache.ecs.html.Option o = (org.apache.ecs.html.Option) i.next();
if (selected.equalsIgnoreCase(o.getAttribute("value")))
{
o.setSelected(true);
}
}
select.setSize(rowsShowing);
return (select);
}
/**
* Description of the Method
*
* @param title
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeTallHeader(String title)
{
StringBuffer buff = new StringBuffer();
for (int i = 0; i < title.length(); i++)
{
buff.append(title.charAt(i));
buff.append("<BR>");
}
return new TH(buff.toString());
}
/**
* Description of the Method
*
* @param title
* Description of the Parameter
* @param text
* Description of the Parameter
* @return Description of the Return Value
*/
public static Element makeTextArea(String title, String text)
{
ElementContainer ec = new ElementContainer();
ec.addElement(new BR());
ec.addElement(new H3().addElement(title));
ec.addElement(new P());
ec.addElement("<CENTER><TEXTAREA ROWS=10 COLS=90 READONLY>" + text + "</TEXTAREA></CENTER>");
ec.addElement(new BR());
ec.addElement(new BR());
return (ec);
}
}

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