Compare commits

...

12 Commits

Author SHA1 Message Date
bf02077427 chore: bump org.wiremock:wiremock-standalone from 3.9.1 to 3.9.2 (#1947)
Bumps [org.wiremock:wiremock-standalone](https://github.com/wiremock/wiremock) from 3.9.1 to 3.9.2.
- [Release notes](https://github.com/wiremock/wiremock/releases)
- [Commits](https://github.com/wiremock/wiremock/compare/3.9.1...3.9.2)

---
updated-dependencies:
- dependency-name: org.wiremock:wiremock-standalone
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-07 15:46:43 +01:00
e1e00bca73 fix: JWT kid/jku lessons (#1949)
* refactor: rewrite hints

Use active voice and fix grammar issues.

* fix: use Thymeleaf `th:action`

* fix: JWT kid/jku lessons

Split the JavaScript into two files they pointed to the same URL

The JWTs are now valid, they parse successfully.

The paths now include `/kid` and `/jku` to make sure the hints match accordingly in the UI. Otherwise `/delete` would pick up both hints from both assignments as the paths overlap.

Closes: #1715

* fix: update to latest pre-commit version

* fix: increase timeouts for server to start during integration tests
2024-11-07 15:45:33 +01:00
d59153d6d7 Fix password reset lesson (#1941)
* docs: improve text

* fix: use correct POST url
2024-10-29 17:32:51 +01:00
87fae00f03 chore: bump commons-io:commons-io from 2.16.1 to 2.17.0 (#1937)
Bumps commons-io:commons-io from 2.16.1 to 2.17.0.

---
updated-dependencies:
- dependency-name: commons-io:commons-io
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-29 16:30:32 +01:00
3f6a74ad86 chore(gh-actions): update dependency 2024-10-28 22:02:02 +01:00
1d37ee0877 ci: run pre-commit checks first
Create a dependency between the jobs.
2024-10-28 21:59:10 +01:00
4f6ab25ebd ci: run pre-commit checks first 2024-10-28 21:57:43 +01:00
af687e71fe chore: bump com.google.guava:guava from 33.3.0-jre to 33.3.1-jre (#1939) 2024-10-28 20:02:09 +01:00
83ed4c3d5c chore: bump org.testcontainers:testcontainers from 1.20.1 to 1.20.3 (#1935) 2024-10-28 15:05:33 +01:00
62cdfd0824 chore: bump com.github.terma:javaniotcpproxy from 1.5 to 1.6 (#1936) 2024-10-28 15:04:15 +01:00
e7457f4821 chore: bump org.apache.maven.plugins:maven-checkstyle-plugin (#1938) 2024-10-28 15:04:01 +01:00
4efaf87c7e Fix passing command line arguments (#1933)
* fix: use banners correctly

* fix: passing command line arguments

Since we already have `webwolf.port` it makes sense to also define `webwolf.port` explicitly and not rely on `server.port`

Closes: #1910
2024-10-27 08:39:02 +01:00
58 changed files with 205 additions and 206 deletions

View File

@ -11,8 +11,28 @@ on:
- main
jobs:
pre-commit:
name: Pre-commit check
runs-on: ubuntu-latest
steps:
- name: Checkout git repository
uses: actions/checkout@v4.1.6
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: "3.9"
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Pre-commit checks
uses: pre-commit/action@v3.0.1
- name: pre-commit-ci-lite
uses: pre-commit-ci/lite-action@v1.1.0
if: always()
build:
runs-on: ${{ matrix.os }}
needs: [ pre-commit ]
strategy:
fail-fast: true
matrix:
@ -26,11 +46,6 @@ jobs:
distribution: 'temurin'
java-version: 21
architecture: x64
- name: Cache Maven packages
uses: actions/cache@v4.1.1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-
cache: 'maven'
- name: Build with Maven
run: mvn --no-transfer-progress verify

View File

@ -1,29 +0,0 @@
name: Pre-commit check
on:
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
pre-commit:
name: Pre-commit check
runs-on: ubuntu-latest
steps:
- name: Checkout git repository
uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v5
with:
python-version: "3.9"
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Pre-commit checks
uses: pre-commit/action@v3.0.0
- name: pre-commit-ci-lite
uses: pre-commit-ci/lite-action@v1.1.0
if: always()

View File

@ -21,13 +21,7 @@ jobs:
distribution: 'temurin'
java-version: 21
architecture: x64
- name: Cache Maven packages
uses: actions/cache@v4.1.1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2
cache: 'maven'
- name: "Set labels for ${{ github.ref }}"
run: |

View File

@ -35,13 +35,7 @@ jobs:
distribution: 'temurin'
java-version: 21
architecture: x64
#Uses an action to set up a cache using a certain key based on the hash of the dependencies
- name: Cache Maven packages
uses: actions/cache@v4.1.1
with:
path: ~/.m2
key: ubuntu-latest-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ubuntu-latest-m2-
cache: 'maven'
- uses: BSFishy/pip-action@v1
with:
packages: |

View File

@ -85,6 +85,16 @@ java -Dfile.encoding=UTF-8 -jar webgoat-2023.8.jar
Click the link in the log to start WebGoat.
### 3.1 Running on a different port
If for some reason you want to run WebGoat on a different port, you can do so by adding the following parameter:
```shell
java -jar webgoat-2023.8.jar --webgoat.port=8001 --webwolf.port=8002
```
For a full overview of all the parameters you can use, please check the [WebGoat properties file](webgoat-container/src/main/resources/application-{webgoat, webwolf}.properties).
## 4. Run from the sources
### Prerequisites:

14
pom.xml
View File

@ -66,13 +66,13 @@
<bootstrap.version>5.3.3</bootstrap.version>
<cglib.version>3.3.0</cglib.version>
<!-- do not update necessary for lesson -->
<checkstyle.version>3.4.0</checkstyle.version>
<checkstyle.version>3.6.0</checkstyle.version>
<commons-collections.version>3.2.1</commons-collections.version>
<commons-compress.version>1.27.1</commons-compress.version>
<commons-io.version>2.16.1</commons-io.version>
<commons-io.version>2.17.0</commons-io.version>
<commons-lang3.version>3.14.0</commons-lang3.version>
<commons-text.version>1.12.0</commons-text.version>
<guava.version>33.3.0-jre</guava.version>
<guava.version>33.3.1-jre</guava.version>
<jacoco.version>0.8.11</jacoco.version>
<java.version>21</java.version>
<jaxb.version>2.3.1</jaxb.version>
@ -93,13 +93,13 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
<waittimeForServerStart>30</waittimeForServerStart>
<waittimeForServerStart>60</waittimeForServerStart>
<webdriver.version>5.9.2</webdriver.version>
<webgoat.context>/</webgoat.context>
<webgoat.sslenabled>false</webgoat.sslenabled>
<webjars-locator-core.version>0.59</webjars-locator-core.version>
<webwolf.context>/</webwolf.context>
<wiremock.version>3.9.1</wiremock.version>
<wiremock.version>3.9.2</wiremock.version>
<xml-resolver.version>1.2</xml-resolver.version>
<xstream.version>1.4.5</xstream.version>
<!-- do not update necessary for lesson -->
@ -235,7 +235,7 @@
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.20.1</version>
<version>1.20.3</version>
<scope>test</scope>
</dependency>
<dependency>
@ -374,7 +374,7 @@
<dependency>
<groupId>com.github.terma</groupId>
<artifactId>javaniotcpproxy</artifactId>
<version>1.5</version>
<version>1.6</version>
<scope>test</scope>
</dependency>

View File

@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/JWT/jku")
@RequestMapping("/JWT/")
@RestController
@AssignmentHints({
"jwt-jku-hint1",
@ -30,7 +30,7 @@ import org.springframework.web.bind.annotation.RestController;
})
public class JWTHeaderJKUEndpoint extends AssignmentEndpoint {
@PostMapping("/follow/{user}")
@PostMapping("jku/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) {
return "Following yourself seems redundant";
@ -39,7 +39,7 @@ public class JWTHeaderJKUEndpoint extends AssignmentEndpoint {
}
}
@PostMapping("/delete")
@PostMapping("jku/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build();

View File

@ -52,7 +52,7 @@ import org.springframework.web.bind.annotation.RestController;
"jwt-kid-hint5",
"jwt-kid-hint6"
})
@RequestMapping("/JWT/kid")
@RequestMapping("/JWT/")
public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
private final LessonDataSource dataSource;
@ -61,7 +61,7 @@ public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
this.dataSource = dataSource;
}
@PostMapping("/follow/{user}")
@PostMapping("kid/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) {
return "Following yourself seems redundant";
@ -70,7 +70,7 @@ public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
}
}
@PostMapping("/delete")
@PostMapping("kid/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build();

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.passwordreset;
import static org.springframework.util.StringUtils.hasText;
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.HashMap;
@ -117,7 +119,7 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
BindingResult bindingResult,
@CurrentUsername String username) {
ModelAndView modelAndView = new ModelAndView();
if (!org.springframework.util.StringUtils.hasText(form.getPassword())) {
if (!hasText(form.getPassword())) {
bindingResult.rejectValue("password", "not.empty");
}
if (bindingResult.hasErrors()) {

View File

@ -1,8 +1,6 @@
package org.owasp.webgoat.server;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("org.owasp.webgoat.server")
public class ParentConfig {}

View File

@ -28,23 +28,30 @@ package org.owasp.webgoat.server;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.container.WebGoat;
import org.owasp.webgoat.webwolf.WebWolf;
import org.springframework.boot.Banner;
import org.springframework.boot.ResourceBanner;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
@Slf4j
public class StartWebGoat {
public static void main(String[] args) {
var parentBuilder =
new SpringApplicationBuilder()
.parent(ParentConfig.class)
.web(WebApplicationType.NONE)
.bannerMode(Banner.Mode.OFF);
parentBuilder.child(WebWolf.class).web(WebApplicationType.SERVLET).run(args);
new SpringApplicationBuilder().parent(ParentConfig.class).web(WebApplicationType.NONE);
parentBuilder
.child(WebWolf.class)
.banner(new ResourceBanner(new ClassPathResource("banner-webwolf.txt")))
.web(WebApplicationType.SERVLET)
.run(args);
ApplicationContext webGoatContext =
parentBuilder.child(WebGoat.class).web(WebApplicationType.SERVLET).run(args);
parentBuilder
.child(WebGoat.class)
.banner(new ResourceBanner(new ClassPathResource("banner-webgoat.txt")))
.web(WebApplicationType.SERVLET)
.run(args);
printStartUpMessage(webGoatContext);
}

View File

@ -2,7 +2,7 @@ server.error.include-stacktrace=always
server.error.path=/error.html
server.servlet.context-path=${WEBGOAT_CONTEXT:/WebGoat}
server.servlet.session.persistent=false
server.port=${WEBGOAT_PORT:8080}
server.port=${webgoat.port}
server.address=${WEBGOAT_HOST:127.0.0.1}
webgoat.host=${WEBGOAT_HOST:127.0.0.1}
webgoat.port=${WEBGOAT_PORT:8080}
@ -15,7 +15,6 @@ server.ssl.key-store-password=${WEBGOAT_KEYSTORE_PASSWORD:password}
server.ssl.key-alias=${WEBGOAT_KEY_ALIAS:goat}
server.ssl.enabled=${WEBGOAT_SSLENABLED:false}
spring.banner.location=classpath:banner.txt
spring.datasource.url=jdbc:hsqldb:file:${webgoat.server.directory}/webgoat
spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.jpa.open-in-view=false

View File

@ -0,0 +1,5 @@
__ __ _ ____ _
\ \ / /__| |__ / ___| ___ __ _| |_
\ \ /\ / / _ \ '_ \| | _ / _ \ / _` | __|
\ V V / __/ |_) | |_| | (_) | (_| | |_
\_/\_/ \___|_.__/ \____|\___/ \__,_|\__|

View File

@ -0,0 +1,5 @@
__ __ _ __ __ _ __
\ \ / /__| |_\ \ / /__ | |/ _|
\ \ /\ / / _ \ '_ \ \ /\ / / _ \| | |_
\ V V / __/ |_) \ V V / (_) | | _|
\_/\_/ \___|_.__/ \_/\_/ \___/|_|_|

View File

@ -1,6 +0,0 @@
__ __ _ _____ _
\ \ / / | | / ____| | |
\ \ /\ / / ___ | |__ | | __ ___ __ _ | |_
\ \/ \/ / / _ \ | '_ \ | | |_ | / _ \ / _' | | __|
\ /\ / | __/ | |_) | | |__| | | (_) | | (_| | | |_
\/ \/ \___| |_.__/ \_____| \___/ \__,_| \__|

View File

@ -23,7 +23,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="verify-account-form"
method="POST" name="form"
successCallback="onBypassResponse"
action="auth-bypass/verify-account">
th:action="@{/auth-bypass/verify-account}">
<p>Verify Your Account by answering the questions below:</p>
<p>What is the name of your favorite teacher?</p>
@ -43,7 +43,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="change-password-form"
method="POST" name="form"
successCallback="onBypassResponse"
action="auth-bypass/verify-account"
th:action="@{/auth-bypass/verify-account}"
style="display:none"><!-- start off hidden -->
<p>Please provide a new password for your account</p>

View File

@ -18,7 +18,7 @@
<div class="container-fluid">
<form class="attack-form" accept-charset="UNKNOWN" name="fieldRestrictions"
method="POST"
action="BypassRestrictions/FieldRestrictions">
th:action="@{/BypassRestrictions/FieldRestrictions}">
<div class="bypass-input-container"><b>Select field with two possible value</b>
<div class="input-group">

View File

@ -17,7 +17,7 @@
<div class="panel-body">
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="challenge/1"
th:action="@{/challenge/1}"
style="width: 200px;">
<div class="form-group">
@ -37,7 +37,7 @@
</div>
</div>
<form class="attack-form" method="POST" name="form" action="challenge/flag/1">
<form class="attack-form" method="POST" name="form" th:action="@{/challenge/flag/1}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -25,7 +25,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="challenge/5" role="form">
th:action="@{/challenge/5}" role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -66,7 +66,7 @@
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="challenge/flag/5">
<form class="attack-form" method="POST" name="form" th:action="@{/challenge/flag/5}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -29,7 +29,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="challenge/6" role="form">
th:action="@{/challenge/6}" role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -64,7 +64,7 @@
</form>
<form id="register-form" class="attack-form" accept-charset="UNKNOWN"
method="PUT" name="form"
action="challenge/6" style="display: none;" role="form">
th:action="@{/challenge/6}" style="display: none;" role="form">
<div class="form-group">
<input type="text" name="username_reg" id="username" tabindex="1"
class="form-control" placeholder="Username" value=""/>
@ -99,7 +99,7 @@
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="challenge/flag/6">
<form class="attack-form" method="POST" name="form" th:action="@{/challenge/flag/6}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -28,7 +28,7 @@ f94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="challenge/7" role="form">
th:action="@{/challenge/7}" role="form">
<div class="form-group">
<div class="input-group">
@ -57,7 +57,7 @@ f94008f801fceb8833a30fe56a8b26976347edcf First version of WebGoat Cloud website
</div>
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="challenge/flag/7">
<form class="attack-form" method="POST" name="form" th:action="@{/challenge/flag/7}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -231,7 +231,7 @@
</div>
<br/>
<form class="attack-form" method="POST" name="form" action="challenge/flag/8">
<form class="attack-form" method="POST" name="form" th:action="@{/challenge/flag/8}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"

View File

@ -24,7 +24,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="ChromeDevTools/dummy">
th:action="@{/ChromeDevTools/dummy}">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>
@ -45,7 +45,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="ChromeDevTools/network">
th:action="@{/chromeDevTools/network}">
<script>
// sample custom javascript in the recommended way ...
// a namespace has been assigned for it, but you can roll your own if you prefer
@ -66,7 +66,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="ChromeDevTools/network">
th:action="@{/chromeDevTools/network}">
<table>
<tr>
<td>What is the number you found: </td>

View File

@ -29,7 +29,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="cia/quiz" role="form">
th:action="@{/cia/quiz}" role="form">
<div id="q_container"></div>
<br />
<input name="Quiz_solutions" value="Submit answers" type="SUBMIT"/>

View File

@ -14,7 +14,7 @@
<input type="hidden" id="user_id" value="102"/>
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form"
action="clientSideFiltering/attack1">
th:action="@{/clientSideFiltering/attack1}">
<link rel="stylesheet" type="text/css"
th:href="@{/lesson_css/clientSideFiltering-stage1.css}"/>
<script th:src="@{/lesson_js/clientSideFiltering.js}"

View File

@ -28,7 +28,7 @@ $(document).ready(initialise);
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
Now suppose you have intercepted the following header:<br/>
<div id="basicauthtoken" ></div><br/>
<form class="attack-form" method="POST" name="form" action="crypto/encoding/basic-auth">
<form class="attack-form" method="POST" name="form" th:action="@{/crypto/encoding/basic-auth}">
Then what was the username
<input name="answer_user" value="" type="TEXT"/>
and what was the password:
@ -45,7 +45,7 @@ $(document).ready(initialise);
<!-- 3. assignment xor -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="crypto/encoding/xor">
<form class="attack-form" method="POST" name="form" th:action="@{/crypto/encoding/xor}">
Suppose you found the database password encoded as {xor}Oz4rPj0+LDovPiwsKDAtOw==<br/>
What would be the actual password
<input name="answer_pwd1" value="" type="TEXT"/><br/>
@ -62,7 +62,7 @@ $(document).ready(initialise);
<!-- 4. weak hashing exercise -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="crypto/hashing">
<form class="attack-form" method="POST" name="form" th:action="@{/crypto/hashing}">
Which password belongs to this hash: <div id="md5token" ></div>
<input name="answer_pwd1" value="" type="TEXT"/><br/>
Which password belongs to this hash: <div id="sha256token" ></div>
@ -87,7 +87,7 @@ $(document).ready(initialise);
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
Now suppose you have the following private key:<br/>
<pre><div id="privatekey" ></div></pre><br/>
<form class="attack-form" method="POST" name="form" action="crypto/signing/verify">
<form class="attack-form" method="POST" name="form" th:action="@{/crypto/signing/verify}">
Then what was the modulus of the public key
<input name="modulus" value="" type="TEXT"/>
and now provide a signature for us based on that modulus
@ -110,7 +110,7 @@ $(document).ready(initialise);
<!-- 8. assignment -->
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="crypto/secure/defaults">
<form class="attack-form" method="POST" name="form" th:action="@{/crypto/secure/defaults}">
What is the unencrypted message<br/>
<input name="secretText" value="" type="TEXT"/><br/>
and what is the name of the file that stored the password <br/>

View File

@ -17,7 +17,7 @@
method="POST" name="form1"
target="_blank"
successCallback=""
action="csrf/basic-get-flag">
th:action="@{/csrf/basic-get-flag}">
<input name="csrf" type="hidden" value="false"/>
<input type="submit" name="submit"/>
@ -35,7 +35,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-1"
method="POST" name="form2"
successCallback=""
action="csrf/confirm-flag-1">
th:action="@{/csrf/confirm-flag-1}">
Confirm Flag Value:
<input type="text" length="6" name="confirmFlagVal" value=""/>
@ -93,7 +93,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="csrf-review"
method="POST" name="review-form"
successCallback=""
action="csrf/review">
th:action="@{/csrf/review}">
<input class="form-control" id="reviewText" name="reviewText" placeholder="Add a Review"
type="text"/>
<input class="form-control" id="reviewStars" name="stars" type="text"/>
@ -146,7 +146,7 @@
<form class="attack-form" accept-charset="UNKNOWN" id="csrf-feedback"
method="POST"
prepareData="feedback"
action="csrf/feedback/message"
th:action="@{/csrf/feedback/message}"
contentType="application/json">
<div class="row">
<div class="col-md-6">
@ -212,7 +212,7 @@
</div>
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-feedback"
method="POST" name="form2"
action="csrf/feedback">
th:action="@{/csrf/feedback}">
Confirm Flag Value:
<input type="text" length="6" name="confirmFlagVal" value=""/>
@ -236,7 +236,7 @@
</div>
<form class="attack-form" accept-charset="UNKNOWN" id="confirm-flag-login"
method="POST" name="form2"
action="csrf/login">
th:action="@{/csrf/login}">
Press the button below when your are logged in as the other user<br/>

View File

@ -25,7 +25,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="InsecureDeserialization/task">
th:action="@{/InsecureDeserialization/task}">
<input type="textarea" rows="4" cols="40" value="" name="token" placeholder="token"/>
<input type="submit" value="Submit" />

View File

@ -1,7 +1,7 @@
<div class="row">
<div class="col-md-4">
<form class="attack-form" accept-charset="UNKNOWN" method="POST"
action="HijackSession/login">
th:action="@{/HijackSession/login}">
<div style="padding: 20px;" id="password-login">
<h4 style="border-bottom: 1px solid #c5c5c5;">Account Access</h4>
<fieldset>

View File

@ -13,7 +13,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" id="task" name="task"
method="POST"
action="HtmlTampering/task">
th:action="@{/HtmlTampering/task}">
<script>
var regex = /^2999.99$/;
var price = 2999.99;

View File

@ -21,10 +21,10 @@
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="HttpBasics/attack1">
th:action="@{/HttpBasics/attack1}">
<div id="lessonContent">
<form accept-charset="UNKNOWN" method="POST" name="form"
action="#attack/307/100">
th:action="@{/#attack/307/100}">
Enter Your Name: <input name="person" value="" type="TEXT"/><input
name="SUBMIT" value="Go!" type="SUBMIT"/>
</form>
@ -51,7 +51,7 @@
<!-- of course, you can write your own ajax submission /handling in your own javascript if you like -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="HttpBasics/attack2">
th:action="@{/HttpBasics/attack2}">
<script>
// sample custom javascript in the recommended way ...
// a namespace has been assigned for it, but you can roll your own if you prefer

View File

@ -24,7 +24,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="intercept-request"
method="POST"
action="HttpProxies/intercept-request">
th:action="@{/HttpProxies/intercept-request}">
<input type="text" value="doesn't matter really" name="changeMe" />
<input type="submit" value="Submit" />

View File

@ -22,7 +22,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="IDOR/login">
th:action="@{/IDOR/login}">
<table>
<tr>
<td>user/pass</td>
@ -57,7 +57,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="GET" name="form"
action="IDOR/profile">
th:action="@{/IDOR/profile}">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="button" onclick="onViewProfile();" />
@ -80,7 +80,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form"
method="POST" name="diff-form"
action="IDOR/diff-attributes">
th:action="@{/IDOR/diff-attributes}">
<input name="attributes" type="text" />
<input name="Submit Diffs" value="Submit Diffs" type="submit" />
</form>
@ -107,7 +107,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="IDOR/profile/alt-path">
th:action="@{/IDOR/profile/alt-path}">
<div class="adoc-content" th:replace="~{doc:lessons/idor/documentation/IDOR_inputAltPath.adoc}"></div>
<input name="url" value="WebGoat/" type="text"/>
<input name="submit" value="Submit" type="SUBMIT"/>
@ -134,7 +134,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN" id="view-other"
method="GET" name="view-other-profile"
action="IDOR/profile/{userId}">
th:action="@{/IDOR/profile/{userId}}">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="submit" />
@ -158,7 +158,7 @@
<!-- modify the action to point to the intended endpoint -->
<form class="attack-form" accept-charset="UNKNOWN" id="edit-other"
method="GET" name="edit-other-profile"
action="IDOR/profile/{userId}">
th:action="@{/IDOR/profile/{userId}}">
<script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="submit" />

View File

@ -17,7 +17,7 @@
<script th:src="@{/lesson_js/credentials.js}"></script>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="InsecureLogin/task">
th:action="@{/InsecureLogin/task}">
<button onclick="javascript:submit_secret_credentials();return false;">Log in</button>
@ -25,7 +25,7 @@
<br></br>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="InsecureLogin/task">
th:action="@{/InsecureLogin/task}">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password" />

View File

@ -17,7 +17,7 @@
<div class="adoc-content" th:replace="~{doc:lessons/jwt/documentation/JWT_decode.adoc}"></div>
<div class="attack-container">
<img th:src="@{/images/wolf-enabled.png}" class="webwolf-enabled"/>
<form id="decode" class="attack-form" method="POST" name="form" action="JWT/decode">
<form id="decode" class="attack-form" method="POST" name="form" th:action="@{/JWT/decode}">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<br>
<div class="row">
@ -53,7 +53,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
successCallback="jwtSigningCallback"
action="JWT/votings">
th:action="@{/JWT/votings}">
<div class="container-fluid">
<div class="row">
@ -124,7 +124,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="JWT/quiz"
th:action="@{/JWT/quiz}"
role="form">
<div id="q_container"></div>
<br/>
@ -155,7 +155,7 @@
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" method="POST" name="form" action="JWT/secret">
<form class="attack-form" method="POST" name="form" th:action="@{/JWT/secret}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-flag-checkered" aria-hidden="true"
@ -192,7 +192,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
additionalHeaders="addBearerToken"
action="JWT/refresh/checkout">
th:action="@{/JWT/refresh/checkout}">
<div class="container-fluid">
<div class="row">
<div class="col-sm-12 col-md-10 col-md-offset-1">
@ -314,12 +314,13 @@
<div class="adoc-content" th:replace="~{doc:lessons/jwt/documentation/JWT_claim_misuse_jku_assignment.adoc}"></div>
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/jwt.css}"/>
<script th:src="@{/lesson_js/bootstrap.min.js}" language="JavaScript"></script>
<script th:src="@{/lesson_js/jwt-jku.js}"></script>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="JWT/final/delete?token=eyJ0eXAiOiJKV1QiLCJqa3UiOiJodHRwczovL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3dlYmdvYXQvLndlbGwta25vd24vandrcy5qc29uIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.SabvRaYSCW7xI0ueca19TL1e66cJIJaxRiydK2G5lgFMIbL5gQQjE6022HEha9HcprqFXyHbtXrQWRXAp6Gjaf5zs8LUMBMARWjEr8TS43ihguarmLLmvBCoqjiZY39o4EcEjEH9xAoyIYR_Trh7kXn6JVU-8MM76l9IOcYIJ9c8LqT1ERNmbCqtI4PP0tdqCy99nHhqlxSCVXaGDF0jMHV5kjCDSHNYib9riy9xZ63Sztify-bwPqRvxmaShPYtG4BBM_wOGlg-BYTTuws-6yISMfTB5U1WBDwLr6dLU123TGO26wCVBgTKbA0KKG94-ToOcneWLOTEacEfQQOlIQ">
th:action="@{/JWT/jku/delete?token=eyJ0eXAiOiJKV1QiLCJqa3UiOiJodHRwczovL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL3dlYmdvYXQvLndlbGwta25vd24vandrcy5qc29uIiwiYWxnIjoiUlMyNTYifQ.ewogICJpc3MiOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwKICAiaWF0IjogMTUyNDIxMDkwNCwKICAiZXhwIjogMTYxODkwNTMwNCwKICAiYXVkIjogIndlYmdvYXQub3JnIiwKICAic3ViIjogImplcnJ5QHdlYmdvYXQuY29tIiwKICAidXNlcm5hbWUiOiAiSmVycnkiLAogICJFbWFpbCI6ICJqZXJyeUB3ZWJnb2F0LmNvbSIsCiAgIlJvbGUiOiBbCiAgICAiQ2F0IgogIF0KfQ.SabvRaYSCW7xI0ueca19TL1e66cJIJaxRiydK2G5lgFMIbL5gQQjE6022HEha9HcprqFXyHbtXrQWRXAp6Gjaf5zs8LUMBMARWjEr8TS43ihguarmLLmvBCoqjiZY39o4EcEjEH9xAoyIYR_Trh7kXn6JVU-8MM76l9IOcYIJ9c8LqT1ERNmbCqtI4PP0tdqCy99nHhqlxSCVXaGDF0jMHV5kjCDSHNYib9riy9xZ63Sztify-bwPqRvxmaShPYtG4BBM_WOGlg-bYTTuws-6yISMfTB5U1WBDwLr6dLU123TGO26wCVBgTKbA0KKG94-ToOcneWLOTEacEfQQOlIQ}">
<div class="container-fluid">
<div id="toast"></div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
@ -380,12 +381,12 @@
<div class="adoc-content" th:replace="~{doc:lessons/jwt/documentation/JWT_claim_misuse_kid_assignment.adoc}"></div>
<link rel="stylesheet" type="text/css" th:href="@{/lesson_css/jwt.css}"/>
<script th:src="@{/lesson_js/bootstrap.min.js}" language="JavaScript"></script>
<script th:src="@{/lesson_js/jwt-kid.js}"></script>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST"
action="JWT/kid/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.eyJpc3MiOiJXZWJHb2F0IFRva2VuIEJ1aWxkZXIiLCJpYXQiOjE1MjQyMTA5MDQsImV4cCI6MTYxODkwNTMwNCwiYXVkIjoid2ViZ29hdC5vcmciLCJzdWIiOiJqZXJyeUB3ZWJnb2F0LmNvbSIsInVzZXJuYW1lIjoiSmVycnkiLCJFbWFpbCI6ImplcnJ5QHdlYmdvYXQuY29tIiwiUm9sZSI6WyJDYXQiXX0.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8">
th:action="@{/JWT/kid/delete?token=eyJ0eXAiOiJKV1QiLCJraWQiOiJ3ZWJnb2F0X2tleSIsImFsZyI6IkhTMjU2In0.ewogICJpc3MiOiAiV2ViR29hdCBUb2tlbiBCdWlsZGVyIiwKICAiaWF0IjogMTUyNDIxMDkwNCwKICAiZXhwIjogMTYxODkwNTMwNCwKICAiYXVkIjogIndlYmdvYXQub3JnIiwKICAic3ViIjogImplcnJ5QHdlYmdvYXQuY29tIiwKICAidXNlcm5hbWUiOiAiSmVycnkiLAogICJFbWFpbCI6ICJqZXJyeUB3ZWJnb2F0LmNvbSIsCiAgIlJvbGUiOiBbCiAgICAiQ2F0IgogIF0KfQ.CgZ27DzgVW8gzc0n6izOU638uUCi6UhiOJKYzoEZGE8}">
<div class="container-fluid">
<div id="toast"></div>
<div class="col-sm-6 col-md-4 col-lg-3 mt-4">
@ -421,7 +422,7 @@
<div class="card-footer">
<small>Last updated 12 days ago</small>
<button type="button" class="btn btn-info float-right btn-sm"
onclick="javascript:follow('Tom')">Follow
onclick="javascript:startFollowing('Tom')">Follow
</button>
<button class="btn btn-info float-right btn-sm">Delete</button>
</div>

View File

@ -26,15 +26,15 @@ jwt-refresh-alg-none=Nicely found! You solved the assignment with 'alg: none' ca
jwt-final-jerry-account=Yikes, you are removing Jerry's account, try to delete the account of Tom
jwt-final-not-tom=Username is not Tom try to pass a token for Tom
jwt-jku-hint1=Take a look at the token and specifically and the header
jwt-jku-hint2=The 'jku' (key ID) header parameter is a hint indicating which key is used to verify the JWS
jwt-jku-hint1=Take a look at the token and specifically at the headers
jwt-jku-hint2=The 'jku' header parameter hints a URL pointing to a set of keys used by the server to sign the JWT.
jwt-jku-hint3=Could you use WebWolf to host the public key as a JWKS?
jwt-jku-hint4=Create a key pair and sign the token with the private key
jwt-jku-hint5=Change the JKU header claim and point it to a URL which hosts the public key in JWKS format.
jwt-jku-hint5=Change the JKU header claim and point it to a URL that hosts the public key in JWKS format.
jwt-kid-hint1=Take a look at the token and specifically and the header
jwt-kid-hint2=The 'kid' (key ID) header parameter is a hint indicating which key was used to secure the JWS
jwt-kid-hint3=The key can be located on the filesystem in memory or even reside in the database
jwt-kid-hint1=Take a look at the token and specifically at the headers
jwt-kid-hint2=The 'kid' (key ID) header parameter hints at the key was used to secure the JWS
jwt-kid-hint3=The key resides can for example, either in the filesystem in memory or the database.
jwt-kid-hint4=The key is stored in the database and loaded while verifying a token
jwt-kid-hint5=Using a SQL injection you might be able to manipulate the key to something you know and create a new token.
jwt-kid-hint6=Use: hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS -- as the kid in the header and change the contents of the token to Tom and hit the endpoint with the new token
jwt-kid-hint5=Using an SQL injection, you might be able to manipulate the key to a known object and create a new token.
jwt-kid-hint6=Use: hacked' UNION select 'deletingTom' from INFORMATION_SCHEMA.SYSTEM_USERS -- as the kid in the header change the contents of the token to Tom and hit the endpoint with the new token

View File

@ -1,7 +1,7 @@
function follow(user) {
$.ajax({
type: 'POST',
url: 'JWT/final/follow/' + user
url: 'JWT/kid/follow/' + user
}).then(function (result) {
$("#toast").append(result);
})

View File

@ -0,0 +1,8 @@
function startFollowing(user) {
$.ajax({
type: 'POST',
url: 'JWT/kid/follow/' + user
}).then(function (result) {
$("#toast").append(result);
})
}

View File

@ -47,7 +47,7 @@
<!-- modify the action to point to the intended endpoint and set other attributes as desired -->
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="lesson-template/sample-attack">
th:action="@{/lesson-template/sample-attack}">
<table>
<tr>
<td>two random params</td>

View File

@ -16,7 +16,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="LogSpoofing/log-spoofing">
th:action="@{/LogSpoofing/log-spoofing}">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password"/>
@ -38,7 +38,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" name="task"
method="POST"
action="LogSpoofing/log-bleeding">
th:action="@{/LogSpoofing/log-bleeding}">
<input type="text" value="" name="username" placeholder="username"/>
<input type="password" value="" name="password" placeholder="password"/>

View File

@ -52,7 +52,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="access-control/hidden-menu">
th:action="@{/access-control/hidden-menu}">
<p>Hidden item 1 <input name="hiddenMenu1" value="" type="TEXT"/></p>
<p>Hidden item 2 <input name="hiddenMenu2" value="" type="TEXT"/></p>
@ -75,7 +75,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="access-control/user-hash">
th:action="@{/access-control/user-hash}">
<p>Your Hash: <input name="userHash" value="" type="TEXT"/></p>
<br/>
@ -97,7 +97,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="access-control/user-hash-fix">
th:action="@{/access-control/user-hash-fix}">
<p>Your Hash: <input name="userHash" value="" type="TEXT"/></p>
<br/>

View File

@ -3,17 +3,13 @@
When creating a password reset link you need to make sure:
- It is a unique link with a random token
- It can only be used once
- You can use it only once
- The link is only valid for a limited amount of time.
Sending a link with a random token means an attacker cannot start a simple DOS attack to your website by starting to
block users. The link should not be usable more than once which makes it impossible to change the password again.
The time out is necessary to restrict the attack window, having a link opens up a lot of possibilities for the attacker.
Sending a link with a random token means an attacker cannot start a simple DOS attack to your website by starting to block users. The link should not be usable more than once, which makes it impossible to change the password again. The time-out is necessary to restrict the attack window. Having a link opens up a lot of possibilities for the attacker.
== Assignment
Try to reset the password of Tom (tom@webgoat-cloud.org) to your own choice and login as Tom with
that password. Note: it is not possible to use OWASP ZAP for this lesson, also browsers might not work, command line
tools like `curl` and the like will be more successful for this attack.
Try to reset Tom's password (tom@webgoat-cloud.org) to your own choice and log in as Tom with that password. Note: it is impossible to use OWASP ZAP for this lesson. Also, browsers might not work; command line tools like `curl` and the like will be more successful for this attack.
Tom always resets his password immediately after receiving the email with the link.
Tom is quick to act when it comes to his password. He always resets it immediately after receiving the email with the link.

View File

@ -23,7 +23,7 @@
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
method="POST"
action="PasswordReset/simple-mail/reset">
th:action="@{/PasswordReset/simple-mail/reset}">
<div style="display: none;" id="password-reset-2">
<h4 class="">Forgot your password?</h4>
@ -47,7 +47,7 @@
</form>
<form class="attack-form" accept-charset="UNKNOWN" novalidate="novalidate"
method="POST"
action="PasswordReset/simple-mail">
th:action="@{/PasswordReset/simple-mail}">
<div style="padding: 20px;" id="password-login-2">
<h4 style="border-bottom: 1px solid #c5c5c5;"><i class="glyphicon glyphicon-user"></i>
Account

View File

@ -9,7 +9,7 @@
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 col-sm-offset-2 col-md-offset-3">
<form role="form" method="POST" action="PasswordReset/reset/change-password" th:object="${form}" novalidate="novalidate">
<form role="form" method="POST" th:action="@{/PasswordReset/reset/change-password}" th:object="${form}" novalidate="novalidate">
<h2 class="sign_up_title">Reset your password</h2>
<div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
<input type="hidden" name="resetLink" th:field="*{resetLink}" />

View File

@ -22,7 +22,7 @@
informationalCallback="profileUploadCallback"
prepareData="profileUpload"
enctype="multipart/form-data"
action="PathTraversal/profile-upload">
th:action="@{/PathTraversal/profile-upload}">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="preview"/>
@ -76,7 +76,7 @@
informationalCallback="profileUploadCallbackFix"
prepareData="profileUploadFix"
enctype="multipart/form-data"
action="PathTraversal/profile-upload-fix">
th:action="@{/PathTraversal/profile-upload-fix}">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="previewFix"/>
@ -131,7 +131,7 @@
informationalCallback="profileUploadCallbackRemoveUserInput"
prepareData="profileUploadRemoveUserInput"
enctype="multipart/form-data"
action="PathTraversal/profile-upload-remove-user-input">
th:action="@{/PathTraversal/profile-upload-remove-user-input}">
<div class="preview text-center">
<img class="preview-img" th:src="@{/images/account.png}" alt="Preview Image" width="200"
height="200" id="previewRemoveUserInput"/>

View File

@ -20,7 +20,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SecurePasswords/assignment"
th:action="@{/SecurePasswords/assignment}"
autocomplete="off">
<div class="input-group input-group">

View File

@ -1,7 +1,7 @@
<div class="row">
<div class="col-md-4">
<form class="attack-form" accept-charset="UNKNOWN" method="POST"
action="SpoofCookie/login">
th:action="@{/SpoofCookie/login}">
<div style="padding: 20px;" id="password-login">
<h4 style="border-bottom: 1px solid #c5c5c5;">Account Access</h4>
<fieldset>

View File

@ -15,7 +15,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack2"
th:action="@{/SqlInjection/attack2}"
autocomplete="off">
<table>
<tr>
@ -39,7 +39,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack3"
th:action="@{/SqlInjection/attack3}"
autocomplete="off">
<table>
<tr>
@ -63,7 +63,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack4"
th:action="@{/SqlInjection/attack4}"
autocomplete="off">
<table>
<tr>
@ -87,7 +87,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack5"
th:action="@{/SqlInjection/attack5}"
autocomplete="off">
<table>
<tr>
@ -143,7 +143,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/assignment5a">
th:action="@{/SqlInjection/assignment5a}">
<table>
<tr>
<td>SELECT * FROM user_data WHERE first_name = 'John' AND last_name = '</td>
@ -188,7 +188,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/assignment5b">
th:action="@{/SqlInjection/assignment5b}">
<table>
<tr>
<td>Login_Count:</td>
@ -216,7 +216,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack8"
th:action="@{/SqlInjection/attack8}"
autocomplete="off">
<table>
<tr>
@ -244,7 +244,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack9"
th:action="@{/SqlInjection/attack9}"
autocomplete="off">
<table>
<tr>
@ -273,7 +273,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjection/attack10"
th:action="@{/SqlInjection/attack10}"
autocomplete="off">
<table>
<tr>

View File

@ -20,7 +20,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjectionAdvanced/attack6a">
th:action="@{/SqlInjectionAdvanced/attack6a}">
<table>
<tr>
<td>Name:</td>
@ -33,7 +33,7 @@
</form>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjectionAdvanced/attack6b">
th:action="@{/SqlInjectionAdvanced/attack6b}">
<table>
<tr>
<td>Password:</td>
@ -79,7 +79,7 @@
<div class="col-lg-12">
<form id="login-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjectionAdvanced/challenge_Login"
th:action="@{/SqlInjectionAdvanced/Challenge_Login}"
role="form">
<div class="form-group">
<input type="text" name="username_login" id="username4" tabindex="1"
@ -115,7 +115,7 @@
</form>
<form id="register-form" class="attack-form" accept-charset="UNKNOWN"
method="PUT" name="form"
action="SqlInjectionAdvanced/challenge"
th:action="@{/SqlInjectionAdvanced/challenge}"
style="display: none;" role="form">
<div class="form-group">
<input type="text" name="username_reg" id="username" tabindex="1"
@ -168,7 +168,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjectionAdvanced/quiz"
th:action="@{/SqlInjectionAdvanced/quiz}"
role="form">
<div id="q_container"></div>
<br />

View File

@ -23,7 +23,7 @@
<div class="adoc-content" th:replace="~{doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_completion.adoc}"></div>
<div class="attack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="SqlInjectionMitigations/attack10a">
<form class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" th:action="@{/SqlInjectionMitigations/attack10a}">
<div>
<p>Connection conn = DriverManager.<input type="text" name="field1" id="field1" />(DBURL, DBUSER, DBPW);</p>
<p><input type="text" name="field2" id="field2" /> = conn.<input type="text" name="field3" id="field3" />("SELECT status FROM users WHERE name=<input type="text" name="field4" id="field4" /> AND mail=<input type="text" name="field5" id="field5" />");</p>
@ -42,7 +42,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/sqlinjection/documentation/SqlInjection_jdbc_newcode.adoc}"></div>
<div class="attack-container" style="border: none !important; height: 100%; min-height: 300px;">
<form id="codesubmit" style="height: 100%; min-height: 300px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="SqlInjectionMitigations/attack10b">
<form id="codesubmit" style="height: 100%; min-height: 300px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" th:action="@{/SqlInjectionMitigations/attack10b}">
<div>
<div id="editor" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 300px;" name="editor"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>
@ -72,7 +72,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlOnlyInputValidation/attack"
th:action="@{/SqlInjectionMitigations/attack}"
enctype="application/json;charset=UTF-8">
<table>
<tr>
@ -95,7 +95,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlOnlyInputValidationOnKeywords/attack"
th:action="@{/SqlInjectionMitigations/attack}"
enctype="application/json;charset=UTF-8">
<table>
<tr>
@ -124,7 +124,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SqlInjectionMitigations/attack12a">
th:action="@{/SqlInjectionMitigations/attack12a}">
<div class="container-fluid">
<div class="row">
<div class="panel panel-primary">
@ -173,7 +173,7 @@
<br/>
</div>
</form>
<form class="attack-form" method="POST" name="form" action="SqlInjectionMitigations/attack12a">
<form class="attack-form" method="POST" name="form" th:action="@{/SqlInjectionMitigations/attack12a}">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon">IP address webgoat-prd server:</div>

View File

@ -12,7 +12,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SSRF/task1">
th:action="@{/SSRF/task1}">
<table>
<tr>
<td><input type="hidden" id="url1" name="url" value="images/tom.png"/></td>
@ -34,7 +34,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="SSRF/task2">
th:action="@{/SSRF/task2}">
<table>
<tr>
<td><input type="hidden" id="url2" name="url" value="images/cat.png"/></td>

View File

@ -15,9 +15,9 @@ image::images/requests.png[caption="Figure: ", style="lesson-image"]
{nbsp}
{nbsp}
Suppose we tricked a user into clicking on a link he/she received in an email. This link will open up our crafted
password reset link page. The user does not notice any differences compared to the normal password reset page of the company.
The user enters a new password and hits enter. The new password will be sent to your host. In this case, the new
password will be sent to WebWolf. Try to locate the unique code.
Suppose we tricked a user into clicking on a link received in an email. This link will open up our crafted
password reset link page. The user notices no differences from the company's standard password reset page.
The user enters a new password and hits enter. Your host will receive the new password. In this case, the new
password ends up in WebWolf. Try to locate the unique code.
Please be aware that the user will receive an error page after resetting the password. In a real attack scenario the user would probably see a normal success page (this is due to a limit on what we can control with WebWolf)
Please be aware that the user will receive an error page after resetting the password. In an actual attack scenario, the user would probably see a standard success page (this is due to a limit on what we can control with WebWolf)

View File

@ -18,7 +18,7 @@
<form class="attack-form" accept-charset="UNKNOWN" style="position:relative;top:150px"
method="POST" name="form"
action="WebWolf/mail">
th:action="@{/WebWolf/mail}">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
@ -39,7 +39,7 @@
<!-- <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>-->
<form class="attack-form" accept-charset="UNKNOWN" style="position:relative;top:-50px"
method="POST" name="secondform"
action="WebWolf/mail/send">
th:action="@{/WebWolf/mail/send}">
<div class="container-fluid">
<div class="row">
<div class="col-md-4">

View File

@ -7,4 +7,4 @@ Why is that?
That is because no link triggers that XSS.
You can try it yourself to see what happens ... go to:
link:/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111["/WebGoat/CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111",window=_blank]
link:CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111["CrossSiteScripting/attack5a?QTY1=1&QTY2=1&QTY3=1&QTY4=1&field1=<script>alert('my%20javascript%20here')</script>4128+3214+0002+1999&field2=111",window=_blank]

View File

@ -12,7 +12,7 @@
<div id="lessonContent">
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="CrossSiteScripting/attack1">
th:action="@{/CrossSiteScripting/attack1}">
<table>
<tr>
<td><input type="checkbox" name="checkboxAttack1"> The cookies are the same on each tab </td>
@ -46,7 +46,7 @@
<div id="lessonContent">
<form class="attack-form" accept-charset="UNKNOWN"
method="GET" name="xss-5a"
action="CrossSiteScripting/attack5a">
th:action="@{/CrossSiteScripting/attack5a}">
<center>
<h4>Shopping Cart</h4>
</center>
@ -133,7 +133,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMTestRoute"
action="CrossSiteScripting/attack6a">
th:action="@{/CrossSiteScripting/attack6a}">
<input name="DOMTestRoute" value="" type="TEXT" />
<input name="SubmitTestRoute" value="Submit" type="SUBMIT"/>
</form>
@ -148,7 +148,7 @@
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="CrossSiteScripting/dom-follow-up">
th:action="@{/CrossSiteScripting/dom-follow-up}">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>
@ -168,7 +168,7 @@
<div class="container-fluid">
<form id="quiz-form" class="attack-form" accept-charset="UNKNOWN"
method="POST" name="form"
action="CrossSiteScripting/quiz" role="form">
th:action="@{/CrossSiteScripting/quiz}" role="form">
<div id="q_container"></div>
<br />
<input name="Quiz_solutions" value="Submit answers" type="SUBMIT"/>

View File

@ -21,7 +21,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/xss/documentation/CrossSiteScripting_content8b.adoc}"></div>
<div class="attack-container" style="height: 100%; border: none !important;min-height: 450px;">
<form id="codesubmit" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="CrossSiteScripting/attack3">
<form id="codesubmit" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" th:action="@{/CrossSiteScripting/attack3}">
<div>
<div id="editor" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 350px;" name="editor"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>
@ -41,7 +41,7 @@
<div class="lesson-page-wrapper">
<div class="adoc-content" th:replace="~{doc:lessons/xss/documentation/CrossSiteScripting_content8c.adoc}"></div>
<div class="attack-container" style="height: 100%; border: none !important;min-height: 450px;">
<form id="codesubmit2" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" action="CrossSiteScripting/attack4">
<form id="codesubmit2" style="height: 100%; min-height: 350px;" class="attack-form" accept-charset="UNKNOWN" method="POST" name="form" th:action="@{/CrossSiteScripting/attack4}">
<div>
<div id="editor2" style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 350px;" name="editor2"></div>
<script th:src="@{/js/libs/ace.js}" type="text/javascript" charset="utf-8"></script>

View File

@ -67,7 +67,7 @@
<form class="attack-form" accept-charset="UNKNOWN"
method="POST" name="DOMFollowUp"
action="CrossSiteScriptingStored/stored-xss-follow-up">
th:action="@{/CrossSiteScriptingStored/stored-xss-follow-up}">
<input name="successMessage" value="" type="TEXT" />
<input name="submitMessage" value="Submit" type="SUBMIT"/>
</form>

View File

@ -28,7 +28,7 @@
successCallback="simpleXXECallback"
failureCallback="simpleXXECallback"
contentType="application/xml"
action="xxe/simple">
th:action="@{/xxe/simple}">
<div class="container-fluid">
<div class="panel post">
<div class="post-heading">
@ -94,7 +94,7 @@
prepareData="contentTypeXXE"
successCallback="contentTypeXXECallback"
failureCallback="contentTypeXXECallback"
action="xxe/content-type"
th:action="@{/xxe/content-type}"
contentType="application/json">
<div class="container-fluid">
<div class="panel post">
@ -166,7 +166,7 @@
prepareData="blindXXE"
successCallback="blindXXECallback"
failureCallback="blindXXECallback"
action="xxe/blind"
th:action="@{/xxe/blind}"
contentType="application/xml">
<div class="container-fluid">
<div class="panel post">