Compare commits

...

20 Commits

Author SHA1 Message Date
6a83ddcdef refactor: remove unused code 2024-12-15 12:49:42 +01:00
67c1f622ef refactor: make AssignmentEndpoint an interface 2024-12-02 20:32:06 +01:00
a3e0fcc9b3 refactor: move plugin messages
It is now done afterward through an interceptor. No more need to burden assignments with plugin messages etc. Only return the key and the optional args.
2024-12-02 10:51:19 +01:00
d8100385b6 fix: automatically solve XSS mitigation (#1957)
This PR moves the mitigation Java class into the correct package.

The lesson was automatically solved because no assignments were found.

Closes: #1943
2024-11-14 08:42:55 +01:00
4880afa0e3 fix: remove implicit context path guessing (#1956)
Pass the context-path in the assignment overview so the frontend can easily match an assignment.
2024-11-13 21:32:28 +01:00
e60ca6ce72 chore: bump org.jruby:jruby from 9.4.8.0 to 9.4.9.0 (#1954) 2024-11-11 13:46:45 +01:00
88a763f513 chore: bump org.testcontainers:junit-jupiter from 1.20.1 to 1.20.3 (#1946)
Bumps [org.testcontainers:junit-jupiter](https://github.com/testcontainers/testcontainers-java) from 1.20.1 to 1.20.3.
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.20.1...1.20.3)

---
updated-dependencies:
- dependency-name: org.testcontainers:junit-jupiter
  dependency-type: direct:development
  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 16:13:27 +01:00
7f33d3609f chore: bump org.apache.maven.plugins:maven-surefire-plugin (#1948)
Bumps [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) from 3.5.1 to 3.5.2.
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.1...surefire-3.5.2)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  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 16:13:10 +01:00
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
201 changed files with 981 additions and 1095 deletions

View File

@ -11,8 +11,28 @@ on:
- main - main
jobs: 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: build:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
needs: [ pre-commit ]
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
@ -26,11 +46,6 @@ jobs:
distribution: 'temurin' distribution: 'temurin'
java-version: 21 java-version: 21
architecture: x64 architecture: x64
- name: Cache Maven packages cache: 'maven'
uses: actions/cache@v4.1.1
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: ${{ runner.os }}-m2-
- name: Build with Maven - name: Build with Maven
run: mvn --no-transfer-progress verify 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' distribution: 'temurin'
java-version: 21 java-version: 21
architecture: x64 architecture: x64
cache: 'maven'
- 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
- name: "Set labels for ${{ github.ref }}" - name: "Set labels for ${{ github.ref }}"
run: | run: |

View File

@ -35,13 +35,7 @@ jobs:
distribution: 'temurin' distribution: 'temurin'
java-version: 21 java-version: 21
architecture: x64 architecture: x64
#Uses an action to set up a cache using a certain key based on the hash of the dependencies cache: 'maven'
- 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-
- uses: BSFishy/pip-action@v1 - uses: BSFishy/pip-action@v1
with: with:
packages: | 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. 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 ## 4. Run from the sources
### Prerequisites: ### Prerequisites:

20
pom.xml
View File

@ -66,13 +66,13 @@
<bootstrap.version>5.3.3</bootstrap.version> <bootstrap.version>5.3.3</bootstrap.version>
<cglib.version>3.3.0</cglib.version> <cglib.version>3.3.0</cglib.version>
<!-- do not update necessary for lesson --> <!-- 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-collections.version>3.2.1</commons-collections.version>
<commons-compress.version>1.27.1</commons-compress.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-lang3.version>3.14.0</commons-lang3.version>
<commons-text.version>1.12.0</commons-text.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> <jacoco.version>0.8.11</jacoco.version>
<java.version>21</java.version> <java.version>21</java.version>
<jaxb.version>2.3.1</jaxb.version> <jaxb.version>2.3.1</jaxb.version>
@ -85,7 +85,7 @@
<maven-jar-plugin.version>3.1.2</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.2</maven-jar-plugin.version>
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version> <maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
<maven-source-plugin.version>3.1.0</maven-source-plugin.version> <maven-source-plugin.version>3.1.0</maven-source-plugin.version>
<maven-surefire-plugin.version>3.5.1</maven-surefire-plugin.version> <maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version>
<maven.compiler.source>21</maven.compiler.source> <maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target> <maven.compiler.target>21</maven.compiler.target>
<pmd.version>3.15.0</pmd.version> <pmd.version>3.15.0</pmd.version>
@ -93,13 +93,13 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version> <thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
<waittimeForServerStart>30</waittimeForServerStart> <waittimeForServerStart>60</waittimeForServerStart>
<webdriver.version>5.9.2</webdriver.version> <webdriver.version>5.9.2</webdriver.version>
<webgoat.context>/</webgoat.context> <webgoat.context>/</webgoat.context>
<webgoat.sslenabled>false</webgoat.sslenabled> <webgoat.sslenabled>false</webgoat.sslenabled>
<webjars-locator-core.version>0.59</webjars-locator-core.version> <webjars-locator-core.version>0.59</webjars-locator-core.version>
<webwolf.context>/</webwolf.context> <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> <xml-resolver.version>1.2</xml-resolver.version>
<xstream.version>1.4.5</xstream.version> <xstream.version>1.4.5</xstream.version>
<!-- do not update necessary for lesson --> <!-- do not update necessary for lesson -->
@ -213,7 +213,7 @@
<dependency> <dependency>
<groupId>org.jruby</groupId> <groupId>org.jruby</groupId>
<artifactId>jruby</artifactId> <artifactId>jruby</artifactId>
<version>9.4.8.0</version> <version>9.4.9.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -235,13 +235,13 @@
<dependency> <dependency>
<groupId>org.testcontainers</groupId> <groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId> <artifactId>testcontainers</artifactId>
<version>1.20.1</version> <version>1.20.3</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.testcontainers</groupId> <groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>1.20.1</version> <version>1.20.3</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -374,7 +374,7 @@
<dependency> <dependency>
<groupId>com.github.terma</groupId> <groupId>com.github.terma</groupId>
<artifactId>javaniotcpproxy</artifactId> <artifactId>javaniotcpproxy</artifactId>
<version>1.5</version> <version>1.6</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>

View File

@ -55,8 +55,8 @@ import org.thymeleaf.templateresource.StringTemplateResource;
public class LessonTemplateResolver extends FileTemplateResolver { public class LessonTemplateResolver extends FileTemplateResolver {
private static final String PREFIX = "lesson:"; private static final String PREFIX = "lesson:";
private ResourceLoader resourceLoader; private final ResourceLoader resourceLoader;
private Map<String, byte[]> resources = new HashMap<>(); private final Map<String, byte[]> resources = new HashMap<>();
public LessonTemplateResolver(ResourceLoader resourceLoader) { public LessonTemplateResolver(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader; this.resourceLoader = resourceLoader;

View File

@ -40,7 +40,6 @@ import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.container.i18n.Language; import org.owasp.webgoat.container.i18n.Language;
import org.owasp.webgoat.container.i18n.Messages; import org.owasp.webgoat.container.i18n.Messages;
import org.owasp.webgoat.container.i18n.PluginMessages; import org.owasp.webgoat.container.i18n.PluginMessages;
import org.owasp.webgoat.container.lessons.LessonScanner;
import org.owasp.webgoat.container.session.LabelDebugger; import org.owasp.webgoat.container.session.LabelDebugger;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -74,8 +73,6 @@ public class MvcConfiguration implements WebMvcConfigurer {
private static final String UTF8 = "UTF-8"; private static final String UTF8 = "UTF-8";
private final LessonScanner lessonScanner;
@Override @Override
public void addViewControllers(ViewControllerRegistry registry) { public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login"); registry.addViewController("/login").setViewName("login");
@ -187,28 +184,6 @@ public class MvcConfiguration implements WebMvcConfigurer {
registry registry
.addResourceHandler("/fonts/**") .addResourceHandler("/fonts/**")
.addResourceLocations("classpath:/webgoat/static/fonts/"); .addResourceLocations("classpath:/webgoat/static/fonts/");
// WebGoat lessons
registry
.addResourceHandler("/images/**")
.addResourceLocations(
lessonScanner.applyPattern("classpath:/lessons/%s/images/").toArray(String[]::new));
registry
.addResourceHandler("/lesson_js/**")
.addResourceLocations(
lessonScanner.applyPattern("classpath:/lessons/%s/js/").toArray(String[]::new));
registry
.addResourceHandler("/lesson_css/**")
.addResourceLocations(
lessonScanner.applyPattern("classpath:/lessons/%s/css/").toArray(String[]::new));
registry
.addResourceHandler("/lesson_templates/**")
.addResourceLocations(
lessonScanner.applyPattern("classpath:/lessons/%s/templates/").toArray(String[]::new));
registry
.addResourceHandler("/video/**")
.addResourceLocations(
lessonScanner.applyPattern("classpath:/lessons/%s/video/").toArray(String[]::new));
} }
@Bean @Bean

View File

@ -33,7 +33,6 @@ package org.owasp.webgoat.container;
import java.io.File; import java.io.File;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.owasp.webgoat.container.users.UserRepository;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.autoconfigure.domain.EntityScan;
@ -54,12 +53,6 @@ import org.springframework.web.client.RestTemplate;
@EntityScan(basePackages = "org.owasp.webgoat.container") @EntityScan(basePackages = "org.owasp.webgoat.container")
public class WebGoat { public class WebGoat {
private final UserRepository userRepository;
public WebGoat(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Bean(name = "pluginTargetDirectory") @Bean(name = "pluginTargetDirectory")
public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) { public File pluginTargetDirectory(@Value("${webgoat.user.directory}") final String webgoatHome) {
return new File(webgoatHome); return new File(webgoatHome);

View File

@ -25,51 +25,4 @@
package org.owasp.webgoat.container.assignments; package org.owasp.webgoat.container.assignments;
import org.owasp.webgoat.container.i18n.PluginMessages; public interface AssignmentEndpoint {}
import org.springframework.beans.factory.annotation.Autowired;
public abstract class AssignmentEndpoint {
// TODO: move this to different bean.
@Autowired private PluginMessages messages;
/**
* Convenience method for create a successful result:
*
* <p>- Assignment is set to solved - Feedback message is set to 'assignment.solved'
*
* <p>Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
protected AttackResult.AttackResultBuilder success(AssignmentEndpoint assignment) {
return AttackResult.builder(messages)
.lessonCompleted(true)
.attemptWasMade()
.feedback("assignment.solved")
.assignment(assignment);
}
/**
* Convenience method for create a failed result:
*
* <p>- Assignment is set to not solved - Feedback message is set to 'assignment.not.solved'
*
* <p>Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
protected AttackResult.AttackResultBuilder failed(AssignmentEndpoint assignment) {
return AttackResult.builder(messages)
.lessonCompleted(false)
.attemptWasMade()
.feedback("assignment.not.solved")
.assignment(assignment);
}
protected AttackResult.AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(false).assignment(assignment);
}
}

View File

@ -1,19 +0,0 @@
package org.owasp.webgoat.container.assignments;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.web.bind.annotation.RequestMethod;
/** Created by nbaars on 1/14/17. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AssignmentPath {
String[] path() default {};
RequestMethod[] method() default {};
String value() default "";
}

View File

@ -30,82 +30,18 @@ import static org.apache.commons.text.StringEscapeUtils.escapeJson;
import lombok.Getter; import lombok.Getter;
import org.owasp.webgoat.container.i18n.PluginMessages; import org.owasp.webgoat.container.i18n.PluginMessages;
@Getter
public class AttackResult { public class AttackResult {
public static class AttackResultBuilder {
private boolean lessonCompleted; private boolean lessonCompleted;
private PluginMessages messages; private String feedback;
private Object[] feedbackArgs; private Object[] feedbackArgs;
private String feedbackResourceBundleKey;
private String output; private String output;
private Object[] outputArgs; private Object[] outputArgs;
private AssignmentEndpoint assignment; private final String assignment;
private boolean attemptWasMade = false; private boolean attemptWasMade;
public AttackResultBuilder(PluginMessages messages) { private AttackResult(
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 AttackResultBuilder attemptWasMade() {
this.attemptWasMade = true;
return this;
}
public AttackResult build() {
return new AttackResult(
lessonCompleted,
messages.getMessage(feedbackResourceBundleKey, feedbackArgs),
messages.getMessage(output, output, outputArgs),
assignment.getClass().getSimpleName(),
attemptWasMade);
}
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
this.assignment = assignment;
return this;
}
}
@Getter private boolean lessonCompleted;
@Getter private String feedback;
@Getter private String output;
@Getter private final String assignment;
@Getter private boolean attemptWasMade;
public AttackResult(
boolean lessonCompleted, boolean lessonCompleted,
String feedback, String feedback,
String output, String output,
@ -118,11 +54,33 @@ public class AttackResult {
this.attemptWasMade = attemptWasMade; this.attemptWasMade = attemptWasMade;
} }
public static AttackResultBuilder builder(PluginMessages messages) { public AttackResult(
return new AttackResultBuilder(messages); boolean lessonCompleted,
String feedback,
Object[] feedbackArgs,
String output,
Object[] outputArgs,
String assignment,
boolean attemptWasMade) {
this.lessonCompleted = lessonCompleted;
this.feedback = feedback;
this.feedbackArgs = feedbackArgs;
this.output = output;
this.outputArgs = outputArgs;
this.assignment = assignment;
this.attemptWasMade = attemptWasMade;
} }
public boolean assignmentSolved() { public boolean assignmentSolved() {
return lessonCompleted; return lessonCompleted;
} }
public AttackResult apply(PluginMessages pluginMessages) {
return new AttackResult(
lessonCompleted,
pluginMessages.getMessage(feedback, feedback, feedbackArgs),
pluginMessages.getMessage(output, output, outputArgs),
assignment,
attemptWasMade);
}
} }

View File

@ -0,0 +1,130 @@
package org.owasp.webgoat.container.assignments;
import org.owasp.webgoat.container.i18n.PluginMessages;
public class AttackResultBuilder {
private PluginMessages messages;
private boolean lessonCompleted;
private Object[] feedbackArgs;
private String feedbackResourceBundleKey;
private String output;
private Object[] outputArgs;
private AssignmentEndpoint assignment;
private boolean attemptWasMade = false;
private boolean assignmentCompleted;
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
}
public AttackResultBuilder() {}
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 assignmentCompleted(boolean assignmentCompleted) {
this.assignmentCompleted = assignmentCompleted;
this.feedbackResourceBundleKey = "assignment.completed";
return this;
}
public AttackResultBuilder assignmentCompleted(
boolean assignmentCompleted, String resourceBundleKey) {
this.assignmentCompleted = assignmentCompleted;
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 AttackResultBuilder attemptWasMade() {
this.attemptWasMade = true;
return this;
}
public AttackResult build() {
return new AttackResult(
lessonCompleted,
feedbackResourceBundleKey,
feedbackArgs,
output,
outputArgs,
assignment.getClass().getSimpleName(),
attemptWasMade);
}
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
this.assignment = assignment;
return this;
}
/**
* Convenience method for create a successful result:
*
* <p>- Assignment is set to solved - Feedback message is set to 'assignment.solved'
*
* <p>Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
public static AttackResultBuilder success(AssignmentEndpoint assignment) {
return new AttackResultBuilder()
.lessonCompleted(true)
.assignmentCompleted(true)
.attemptWasMade()
.feedback("assignment.solved")
.assignment(assignment);
}
/**
* Convenience method for create a failed result:
*
* <p>- Assignment is set to not solved - Feedback message is set to 'assignment.not.solved'
*
* <p>Of course you can overwrite these values in a specific lesson
*
* @return a builder for creating a result from a lesson
* @param assignment
*/
public static AttackResultBuilder failed(AssignmentEndpoint assignment) {
return new AttackResultBuilder()
.lessonCompleted(false)
.assignmentCompleted(true)
.attemptWasMade()
.feedback("assignment.not.solved")
.assignment(assignment);
}
public static AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {
return new AttackResultBuilder().lessonCompleted(false).assignment(assignment);
}
}

View File

@ -0,0 +1,41 @@
package org.owasp.webgoat.container.assignments;
import org.owasp.webgoat.container.i18n.PluginMessages;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/** This class intercepts the response body and applies the plugin messages to the attack result. */
@RestControllerAdvice
public class AttackResultMessageResponseBodyAdvice implements ResponseBodyAdvice<Object> {
private final PluginMessages pluginMessages;
public AttackResultMessageResponseBodyAdvice(PluginMessages pluginMessages) {
this.pluginMessages = pluginMessages;
}
@Override
public boolean supports(
MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(
Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response) {
if (body instanceof AttackResult a) {
return a.apply(pluginMessages);
}
return body;
}
}

View File

@ -30,6 +30,7 @@ import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.Course; import org.owasp.webgoat.container.session.Course;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -42,10 +43,15 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class CourseConfiguration { public class CourseConfiguration {
private final List<Lesson> lessons; private final List<Lesson> lessons;
private final List<AssignmentEndpoint> assignments; private final List<AssignmentEndpoint> assignments;
private final String contextPath;
public CourseConfiguration(List<Lesson> lessons, List<AssignmentEndpoint> assignments) { public CourseConfiguration(
List<Lesson> lessons,
List<AssignmentEndpoint> assignments,
@Value("${server.servlet.context-path}") String contextPath) {
this.lessons = lessons; this.lessons = lessons;
this.assignments = assignments; this.assignments = assignments;
this.contextPath = contextPath.equals("/") ? "" : contextPath;
} }
private void attachToLessonInParentPackage( private void attachToLessonInParentPackage(
@ -124,7 +130,7 @@ public class CourseConfiguration {
if (methodReturnTypeIsOfTypeAttackResult(m)) { if (methodReturnTypeIsOfTypeAttackResult(m)) {
var mapping = getMapping(m); var mapping = getMapping(m);
if (mapping != null) { if (mapping != null) {
return mapping; return contextPath + mapping;
} }
} }
} }

View File

@ -35,6 +35,5 @@ package org.owasp.webgoat.container.lessons;
*/ */
public enum LessonMenuItemType { public enum LessonMenuItemType {
CATEGORY, CATEGORY,
LESSON, LESSON
STAGE
} }

View File

@ -1,42 +0,0 @@
package org.owasp.webgoat.container.lessons;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class LessonScanner {
private static final Pattern lessonPattern = Pattern.compile("^.*/lessons/([^/]*)/.*$");
@Getter private final Set<String> lessons = new HashSet<>();
public LessonScanner(ResourcePatternResolver resourcePatternResolver) {
try {
var resources = resourcePatternResolver.getResources("classpath:/lessons/*/*");
for (var resource : resources) {
// WG can run as a fat jar or as directly from file system we need to support both so use
// the URL
var url = resource.getURL();
var matcher = lessonPattern.matcher(url.toString());
if (matcher.matches()) {
lessons.add(matcher.group(1));
}
}
log.debug("Found {} lessons", lessons.size());
} catch (IOException e) {
log.warn("No lessons found...");
}
}
public List<String> applyPattern(String pattern) {
return lessons.stream().map(lesson -> String.format(pattern, lesson)).toList();
}
}

View File

@ -30,10 +30,8 @@ package org.owasp.webgoat.container.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.owasp.webgoat.container.CurrentUsername; import org.owasp.webgoat.container.CurrentUsername;
import org.owasp.webgoat.container.lessons.Assignment;
import org.owasp.webgoat.container.lessons.Category; import org.owasp.webgoat.container.lessons.Category;
import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.lessons.Lesson;
import org.owasp.webgoat.container.lessons.LessonMenuItem; import org.owasp.webgoat.container.lessons.LessonMenuItem;
@ -100,7 +98,7 @@ public class LessonMenuService {
lessonItem.setLink(lesson.getLink()); lessonItem.setLink(lesson.getLink());
lessonItem.setType(LessonMenuItemType.LESSON); lessonItem.setType(LessonMenuItemType.LESSON);
LessonProgress lessonTracker = userTracker.getLessonProgress(lesson); LessonProgress lessonTracker = userTracker.getLessonProgress(lesson);
boolean lessonSolved = lessonCompleted(lessonTracker.getLessonOverview(), lesson); boolean lessonSolved = lessonTracker.isLessonSolved();
lessonItem.setComplete(lessonSolved); lessonItem.setComplete(lessonSolved);
categoryItem.addChild(lessonItem); categoryItem.addChild(lessonItem);
} }
@ -109,18 +107,4 @@ public class LessonMenuService {
} }
return menu; return menu;
} }
private boolean lessonCompleted(Map<Assignment, Boolean> map, Lesson currentLesson) {
boolean result = true;
for (Map.Entry<Assignment, Boolean> entry : map.entrySet()) {
Assignment storedAssignment = entry.getKey();
for (Assignment lessonAssignment : currentLesson.getAssignments()) {
if (lessonAssignment.getName().equals(storedAssignment.getName())) {
result = result && entry.getValue();
break;
}
}
}
return result;
}
} }

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.authbypass; package org.owasp.webgoat.lessons.authbypass;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.ServletException; import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
@ -46,7 +49,7 @@ import org.springframework.web.bind.annotation.RestController;
"auth-bypass.hints.verify.3", "auth-bypass.hints.verify.3",
"auth-bypass.hints.verify.4" "auth-bypass.hints.verify.4"
}) })
public class VerifyAccount extends AssignmentEndpoint { public class VerifyAccount implements AssignmentEndpoint {
private final LessonSession userSessionData; private final LessonSession userSessionData;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.bypassrestrictions; package org.owasp.webgoat.lessons.bypassrestrictions;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -30,7 +33,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class BypassRestrictionsFieldRestrictions extends AssignmentEndpoint { public class BypassRestrictionsFieldRestrictions implements AssignmentEndpoint {
@PostMapping("/BypassRestrictions/FieldRestrictions") @PostMapping("/BypassRestrictions/FieldRestrictions")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.bypassrestrictions; package org.owasp.webgoat.lessons.bypassrestrictions;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -30,7 +33,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class BypassRestrictionsFrontendValidation extends AssignmentEndpoint { public class BypassRestrictionsFrontendValidation implements AssignmentEndpoint {
@PostMapping("/BypassRestrictions/frontendValidation") @PostMapping("/BypassRestrictions/frontendValidation")
@ResponseBody @ResponseBody

View File

@ -22,7 +22,9 @@
package org.owasp.webgoat.lessons.challenges; package org.owasp.webgoat.lessons.challenges;
import lombok.AllArgsConstructor; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@ -32,11 +34,14 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AllArgsConstructor public class FlagController implements AssignmentEndpoint {
public class FlagController extends AssignmentEndpoint {
private final Flags flags; private final Flags flags;
public FlagController(Flags flags) {
this.flags = flags;
}
@PostMapping(path = "/challenge/flag/{flagNumber}") @PostMapping(path = "/challenge/flag/{flagNumber}")
@ResponseBody @ResponseBody
public AttackResult postFlag(@PathVariable int flagNumber, @RequestParam String flag) { public AttackResult postFlag(@PathVariable int flagNumber, @RequestParam String flag) {

View File

@ -1,8 +1,9 @@
package org.owasp.webgoat.lessons.challenges.challenge1; package org.owasp.webgoat.lessons.challenges.challenge1;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.owasp.webgoat.lessons.challenges.SolutionConstants.PASSWORD; import static org.owasp.webgoat.lessons.challenges.SolutionConstants.PASSWORD;
import lombok.RequiredArgsConstructor;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.lessons.challenges.Flags; import org.owasp.webgoat.lessons.challenges.Flags;
@ -42,11 +43,14 @@ import org.springframework.web.bind.annotation.RestController;
* @since August 11, 2016 * @since August 11, 2016
*/ */
@RestController @RestController
@RequiredArgsConstructor public class Assignment1 implements AssignmentEndpoint {
public class Assignment1 extends AssignmentEndpoint {
private final Flags flags; private final Flags flags;
public Assignment1(Flags flags) {
this.flags = flags;
}
@PostMapping("/challenge/1") @PostMapping("/challenge/1")
@ResponseBody @ResponseBody
public AttackResult completed(@RequestParam String username, @RequestParam String password) { public AttackResult completed(@RequestParam String username, @RequestParam String password) {

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.challenges.challenge5; package org.owasp.webgoat.lessons.challenges.challenge5;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -39,7 +42,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class Assignment5 extends AssignmentEndpoint { public class Assignment5 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
private final Flags flags; private final Flags flags;

View File

@ -1,5 +1,7 @@
package org.owasp.webgoat.lessons.challenges.challenge7; package org.owasp.webgoat.lessons.challenges.challenge7;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -29,7 +31,7 @@ import org.springframework.web.client.RestTemplate;
*/ */
@RestController @RestController
@Slf4j @Slf4j
public class Assignment7 extends AssignmentEndpoint { public class Assignment7 implements AssignmentEndpoint {
public static final String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2"; public static final String ADMIN_PASSWORD_LINK = "375afe1104f4a487a73823c50a9292a2";

View File

@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
public class Assignment8 extends AssignmentEndpoint { public class Assignment8 implements AssignmentEndpoint {
private static final Map<Integer, Integer> votes = new HashMap<>(); private static final Map<Integer, Integer> votes = new HashMap<>();

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.chromedevtools; package org.owasp.webgoat.lessons.chromedevtools;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
* @since 30.11.18 * @since 30.11.18
*/ */
@RestController @RestController
public class NetworkDummy extends AssignmentEndpoint { public class NetworkDummy implements AssignmentEndpoint {
private final LessonSession lessonSession; private final LessonSession lessonSession;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.chromedevtools; package org.owasp.webgoat.lessons.chromedevtools;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -40,7 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
*/ */
@RestController @RestController
@AssignmentHints({"networkHint1", "networkHint2"}) @AssignmentHints({"networkHint1", "networkHint2"})
public class NetworkLesson extends AssignmentEndpoint { public class NetworkLesson implements AssignmentEndpoint {
@PostMapping( @PostMapping(
value = "/ChromeDevTools/network", value = "/ChromeDevTools/network",

View File

@ -1,5 +1,8 @@
package org.owasp.webgoat.lessons.cia; package org.owasp.webgoat.lessons.cia;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -9,9 +12,9 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class CIAQuiz extends AssignmentEndpoint { public class CIAQuiz implements AssignmentEndpoint {
String[] solutions = {"Solution 3", "Solution 1", "Solution 4", "Solution 2"}; private final String[] solutions = {"Solution 3", "Solution 1", "Solution 4", "Solution 2"};
boolean[] guesses = new boolean[solutions.length]; boolean[] guesses = new boolean[solutions.length];
@PostMapping("/cia/quiz") @PostMapping("/cia/quiz")

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.clientsidefiltering; package org.owasp.webgoat.lessons.clientsidefiltering;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
"ClientSideFilteringHint3", "ClientSideFilteringHint3",
"ClientSideFilteringHint4" "ClientSideFilteringHint4"
}) })
public class ClientSideFilteringAssignment extends AssignmentEndpoint { public class ClientSideFilteringAssignment implements AssignmentEndpoint {
@PostMapping("/clientSideFiltering/attack1") @PostMapping("/clientSideFiltering/attack1")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.clientsidefiltering; package org.owasp.webgoat.lessons.clientsidefiltering;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -40,8 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
"client.side.filtering.free.hint2", "client.side.filtering.free.hint2",
"client.side.filtering.free.hint3" "client.side.filtering.free.hint3"
}) })
public class ClientSideFilteringFreeAssignment extends AssignmentEndpoint { public class ClientSideFilteringFreeAssignment implements AssignmentEndpoint {
public static final String SUPER_COUPON_CODE = "get_it_for_free"; public static final String SUPER_COUPON_CODE = "get_it_for_free";
@PostMapping("/clientSideFiltering/getItForFree") @PostMapping("/clientSideFiltering/getItForFree")

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.cryptography; package org.owasp.webgoat.lessons.cryptography;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.Base64; import java.util.Base64;
import java.util.Random; import java.util.Random;
@ -35,7 +38,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class EncodingAssignment extends AssignmentEndpoint { public class EncodingAssignment implements AssignmentEndpoint {
public static String getBasicAuth(String username, String password) { public static String getBasicAuth(String username, String password) {
return Base64.getEncoder().encodeToString(username.concat(":").concat(password).getBytes()); return Base64.getEncoder().encodeToString(username.concat(":").concat(password).getBytes());

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.cryptography; package org.owasp.webgoat.lessons.cryptography;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -39,8 +42,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"crypto-hashing.hints.1", "crypto-hashing.hints.2"}) @AssignmentHints({"crypto-hashing.hints.1", "crypto-hashing.hints.2"})
public class HashingAssignment extends AssignmentEndpoint { public class HashingAssignment implements AssignmentEndpoint {
public static final String[] SECRETS = {"secret", "admin", "password", "123456", "passw0rd"}; public static final String[] SECRETS = {"secret", "admin", "password", "123456", "passw0rd"};
@RequestMapping(path = "/crypto/hashing/md5", produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(path = "/crypto/hashing/md5", produces = MediaType.TEXT_HTML_VALUE)

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.cryptography; package org.owasp.webgoat.lessons.cryptography;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
"crypto-secure-defaults.hints.2", "crypto-secure-defaults.hints.2",
"crypto-secure-defaults.hints.3" "crypto-secure-defaults.hints.3"
}) })
public class SecureDefaultsAssignment extends AssignmentEndpoint { public class SecureDefaultsAssignment implements AssignmentEndpoint {
@PostMapping("/crypto/secure/defaults") @PostMapping("/crypto/secure/defaults")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.cryptography; package org.owasp.webgoat.lessons.cryptography;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.security.InvalidAlgorithmParameterException; import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair; import java.security.KeyPair;
@ -47,7 +50,7 @@ import org.springframework.web.bind.annotation.RestController;
"crypto-signing.hints.4" "crypto-signing.hints.4"
}) })
@Slf4j @Slf4j
public class SigningAssignment extends AssignmentEndpoint { public class SigningAssignment implements AssignmentEndpoint {
@RequestMapping(path = "/crypto/signing/getprivate", produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(path = "/crypto/signing/getprivate", produces = MediaType.TEXT_HTML_VALUE)
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.cryptography; package org.owasp.webgoat.lessons.cryptography;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -32,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"crypto-encoding-xor.hints.1"}) @AssignmentHints({"crypto-encoding-xor.hints.1"})
public class XOREncodingAssignment extends AssignmentEndpoint { public class XOREncodingAssignment implements AssignmentEndpoint {
@PostMapping("/crypto/encoding/xor") @PostMapping("/crypto/encoding/xor")
@ResponseBody @ResponseBody

View File

@ -22,11 +22,13 @@
package org.owasp.webgoat.lessons.csrf; package org.owasp.webgoat.lessons.csrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -34,9 +36,13 @@ import org.springframework.web.bind.annotation.RestController;
/** Created by jason on 9/29/17. */ /** Created by jason on 9/29/17. */
@RestController @RestController
@AssignmentHints({"csrf-get.hint1", "csrf-get.hint2", "csrf-get.hint3", "csrf-get.hint4"}) @AssignmentHints({"csrf-get.hint1", "csrf-get.hint2", "csrf-get.hint3", "csrf-get.hint4"})
public class CSRFConfirmFlag1 extends AssignmentEndpoint { public class CSRFConfirmFlag1 implements AssignmentEndpoint {
@Autowired LessonSession userSessionData; private final LessonSession userSessionData;
public CSRFConfirmFlag1(LessonSession userSessionData) {
this.userSessionData = userSessionData;
}
@PostMapping( @PostMapping(
path = "/csrf/confirm-flag-1", path = "/csrf/confirm-flag-1",

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.csrf; package org.owasp.webgoat.lessons.csrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
@ -34,7 +37,6 @@ import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -44,10 +46,15 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"csrf-feedback-hint1", "csrf-feedback-hint2", "csrf-feedback-hint3"}) @AssignmentHints({"csrf-feedback-hint1", "csrf-feedback-hint2", "csrf-feedback-hint3"})
public class CSRFFeedback extends AssignmentEndpoint { public class CSRFFeedback implements AssignmentEndpoint {
@Autowired private LessonSession userSessionData; private final LessonSession userSessionData;
@Autowired private ObjectMapper objectMapper; private final ObjectMapper objectMapper;
public CSRFFeedback(LessonSession userSessionData, ObjectMapper objectMapper) {
this.userSessionData = userSessionData;
this.objectMapper = objectMapper;
}
@PostMapping( @PostMapping(
value = "/csrf/feedback/message", value = "/csrf/feedback/message",

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.csrf; package org.owasp.webgoat.lessons.csrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.CurrentUsername; import org.owasp.webgoat.container.CurrentUsername;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
@ -32,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"csrf-login-hint1", "csrf-login-hint2", "csrf-login-hint3"}) @AssignmentHints({"csrf-login-hint1", "csrf-login-hint2", "csrf-login-hint3"})
public class CSRFLogin extends AssignmentEndpoint { public class CSRFLogin implements AssignmentEndpoint {
@PostMapping( @PostMapping(
path = "/csrf/login", path = "/csrf/login",

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.csrf; package org.owasp.webgoat.lessons.csrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.springframework.http.MediaType.ALL_VALUE; import static org.springframework.http.MediaType.ALL_VALUE;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -45,7 +47,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"csrf-review-hint1", "csrf-review-hint2", "csrf-review-hint3"}) @AssignmentHints({"csrf-review-hint1", "csrf-review-hint2", "csrf-review-hint3"})
public class ForgedReviews extends AssignmentEndpoint { public class ForgedReviews implements AssignmentEndpoint {
private static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd, HH:mm:ss"); private static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd, HH:mm:ss");

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.deserialization; package org.owasp.webgoat.lessons.deserialization;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InvalidClassException; import java.io.InvalidClassException;
@ -42,7 +45,7 @@ import org.springframework.web.bind.annotation.RestController;
"insecure-deserialization.hints.2", "insecure-deserialization.hints.2",
"insecure-deserialization.hints.3" "insecure-deserialization.hints.3"
}) })
public class InsecureDeserializationTask extends AssignmentEndpoint { public class InsecureDeserializationTask implements AssignmentEndpoint {
@PostMapping("/InsecureDeserialization/task") @PostMapping("/InsecureDeserialization/task")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.hijacksession; package org.owasp.webgoat.lessons.hijacksession;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -30,7 +33,6 @@ import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.lessons.hijacksession.cas.Authentication; import org.owasp.webgoat.lessons.hijacksession.cas.Authentication;
import org.owasp.webgoat.lessons.hijacksession.cas.HijackSessionAuthenticationProvider; import org.owasp.webgoat.lessons.hijacksession.cas.HijackSessionAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -51,11 +53,14 @@ import org.springframework.web.bind.annotation.RestController;
"hijacksession.hints.4", "hijacksession.hints.4",
"hijacksession.hints.5" "hijacksession.hints.5"
}) })
public class HijackSessionAssignment extends AssignmentEndpoint { public class HijackSessionAssignment implements AssignmentEndpoint {
private static final String COOKIE_NAME = "hijack_cookie"; private static final String COOKIE_NAME = "hijack_cookie";
@Autowired HijackSessionAuthenticationProvider provider; private final HijackSessionAuthenticationProvider provider;
public HijackSessionAssignment(HijackSessionAuthenticationProvider provider) {
this.provider = provider;
}
@PostMapping(path = "/HijackSession/login") @PostMapping(path = "/HijackSession/login")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.htmltampering; package org.owasp.webgoat.lessons.htmltampering;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -32,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"hint1", "hint2", "hint3"}) @AssignmentHints({"hint1", "hint2", "hint3"})
public class HtmlTamperingTask extends AssignmentEndpoint { public class HtmlTamperingTask implements AssignmentEndpoint {
@PostMapping("/HtmlTampering/task") @PostMapping("/HtmlTampering/task")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.httpbasics; package org.owasp.webgoat.lessons.httpbasics;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -32,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"http-basics.hints.http_basics_lesson.1"}) @AssignmentHints({"http-basics.hints.http_basics_lesson.1"})
public class HttpBasicsLesson extends AssignmentEndpoint { public class HttpBasicsLesson implements AssignmentEndpoint {
@PostMapping("/HttpBasics/attack1") @PostMapping("/HttpBasics/attack1")
@ResponseBody @ResponseBody

View File

@ -22,9 +22,11 @@
package org.owasp.webgoat.lessons.httpbasics; package org.owasp.webgoat.lessons.httpbasics;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AssignmentPath;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -33,8 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"http-basics.hints.http_basic_quiz.1", "http-basics.hints.http_basic_quiz.2"}) @AssignmentHints({"http-basics.hints.http_basic_quiz.1", "http-basics.hints.http_basic_quiz.2"})
@AssignmentPath("HttpBasics/attack2") public class HttpBasicsQuiz implements AssignmentEndpoint {
public class HttpBasicsQuiz extends AssignmentEndpoint {
@PostMapping("/HttpBasics/attack2") @PostMapping("/HttpBasics/attack2")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.httpproxies; package org.owasp.webgoat.lessons.httpproxies;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -34,7 +37,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class HttpBasicsInterceptRequest extends AssignmentEndpoint { public class HttpBasicsInterceptRequest implements AssignmentEndpoint {
@RequestMapping( @RequestMapping(
path = "/HttpProxies/intercept-request", path = "/HttpProxies/intercept-request",

View File

@ -23,6 +23,9 @@
package org.owasp.webgoat.lessons.idor; package org.owasp.webgoat.lessons.idor;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
"idor.hints.idorDiffAttributes2", "idor.hints.idorDiffAttributes2",
"idor.hints.idorDiffAttributes3" "idor.hints.idorDiffAttributes3"
}) })
public class IDORDiffAttributes extends AssignmentEndpoint { public class IDORDiffAttributes implements AssignmentEndpoint {
@PostMapping("/IDOR/diff-attributes") @PostMapping("/IDOR/diff-attributes")
@ResponseBody @ResponseBody

View File

@ -23,11 +23,13 @@
package org.owasp.webgoat.lessons.idor; package org.owasp.webgoat.lessons.idor;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -46,9 +48,13 @@ import org.springframework.web.bind.annotation.RestController;
"idor.hints.otherProfile8", "idor.hints.otherProfile8",
"idor.hints.otherProfile9" "idor.hints.otherProfile9"
}) })
public class IDOREditOtherProfile extends AssignmentEndpoint { public class IDOREditOtherProfile implements AssignmentEndpoint {
@Autowired private LessonSession userSessionData; private final LessonSession userSessionData;
public IDOREditOtherProfile(LessonSession lessonSession) {
this.userSessionData = lessonSession;
}
@PutMapping(path = "/IDOR/profile/{userId}", consumes = "application/json") @PutMapping(path = "/IDOR/profile/{userId}", consumes = "application/json")
@ResponseBody @ResponseBody

View File

@ -23,6 +23,9 @@
package org.owasp.webgoat.lessons.idor; package org.owasp.webgoat.lessons.idor;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -36,15 +39,14 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"idor.hints.idor_login"}) @AssignmentHints({"idor.hints.idor_login"})
public class IDORLogin extends AssignmentEndpoint { public class IDORLogin implements AssignmentEndpoint {
private final LessonSession lessonSession; private final LessonSession lessonSession;
public IDORLogin(LessonSession lessonSession) { public IDORLogin(LessonSession lessonSession) {
this.lessonSession = lessonSession; this.lessonSession = lessonSession;
} }
private Map<String, Map<String, String>> idorUserInfo = new HashMap<>(); private final Map<String, Map<String, String>> idorUserInfo = new HashMap<>();
public void initIDORInfo() { public void initIDORInfo() {

View File

@ -23,12 +23,13 @@
package org.owasp.webgoat.lessons.idor; package org.owasp.webgoat.lessons.idor;
import jakarta.servlet.http.HttpServletResponse; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -46,15 +47,19 @@ import org.springframework.web.bind.annotation.RestController;
"idor.hints.otherProfile8", "idor.hints.otherProfile8",
"idor.hints.otherProfile9" "idor.hints.otherProfile9"
}) })
public class IDORViewOtherProfile extends AssignmentEndpoint { public class IDORViewOtherProfile implements AssignmentEndpoint {
@Autowired LessonSession userSessionData; private final LessonSession userSessionData;
public IDORViewOtherProfile(LessonSession userSessionData) {
this.userSessionData = userSessionData;
}
@GetMapping( @GetMapping(
path = "/IDOR/profile/{userId}", path = "/IDOR/profile/{userId}",
produces = {"application/json"}) produces = {"application/json"})
@ResponseBody @ResponseBody
public AttackResult completed(@PathVariable("userId") String userId, HttpServletResponse resp) { public AttackResult completed(@PathVariable("userId") String userId) {
Object obj = userSessionData.getValue("idor-authenticated-as"); Object obj = userSessionData.getValue("idor-authenticated-as");
if (obj != null && obj.equals("tom")) { if (obj != null && obj.equals("tom")) {

View File

@ -27,7 +27,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -36,7 +35,11 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
public class IDORViewOwnProfile { public class IDORViewOwnProfile {
@Autowired LessonSession userSessionData; private final LessonSession userSessionData;
public IDORViewOwnProfile(LessonSession userSessionData) {
this.userSessionData = userSessionData;
}
@GetMapping( @GetMapping(
path = {"/IDOR/own", "/IDOR/profile"}, path = {"/IDOR/own", "/IDOR/profile"},
@ -60,7 +63,7 @@ public class IDORViewOwnProfile {
"You do not have privileges to view the profile. Authenticate as tom first please."); "You do not have privileges to view the profile. Authenticate as tom first please.");
} }
} catch (Exception ex) { } catch (Exception ex) {
log.error("something went wrong", ex.getMessage()); log.error("something went wrong: {}", ex.getMessage());
} }
return details; return details;
} }

View File

@ -23,11 +23,13 @@
package org.owasp.webgoat.lessons.idor; package org.owasp.webgoat.lessons.idor;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -39,9 +41,12 @@ import org.springframework.web.bind.annotation.RestController;
"idor.hints.ownProfileAltUrl2", "idor.hints.ownProfileAltUrl2",
"idor.hints.ownProfileAltUrl3" "idor.hints.ownProfileAltUrl3"
}) })
public class IDORViewOwnProfileAltUrl extends AssignmentEndpoint { public class IDORViewOwnProfileAltUrl implements AssignmentEndpoint {
private final LessonSession userSessionData;
@Autowired LessonSession userSessionData; public IDORViewOwnProfileAltUrl(LessonSession userSessionData) {
this.userSessionData = userSessionData;
}
@PostMapping("/IDOR/profile/alt-path") @PostMapping("/IDOR/profile/alt-path")
@ResponseBody @ResponseBody

View File

@ -22,13 +22,16 @@
package org.owasp.webgoat.lessons.insecurelogin; package org.owasp.webgoat.lessons.insecurelogin;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@RestController @RestController
public class InsecureLoginTask extends AssignmentEndpoint { public class InsecureLoginTask implements AssignmentEndpoint {
@PostMapping("/InsecureLogin/task") @PostMapping("/InsecureLogin/task")
@ResponseBody @ResponseBody

View File

@ -1,5 +1,8 @@
package org.owasp.webgoat.lessons.jwt; package org.owasp.webgoat.lessons.jwt;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -8,7 +11,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class JWTDecodeEndpoint extends AssignmentEndpoint { public class JWTDecodeEndpoint implements AssignmentEndpoint {
@PostMapping("/JWT/decode") @PostMapping("/JWT/decode")
@ResponseBody @ResponseBody

View File

@ -1,5 +1,8 @@
package org.owasp.webgoat.lessons.jwt; package org.owasp.webgoat.lessons.jwt;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -9,7 +12,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class JWTQuiz extends AssignmentEndpoint { public class JWTQuiz implements AssignmentEndpoint {
private final String[] solutions = {"Solution 1", "Solution 2"}; private final String[] solutions = {"Solution 1", "Solution 2"};
private final boolean[] guesses = new boolean[solutions.length]; private final boolean[] guesses = new boolean[solutions.length];

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.jwt; package org.owasp.webgoat.lessons.jwt;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.springframework.http.ResponseEntity.ok; import static org.springframework.http.ResponseEntity.ok;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
@ -56,7 +58,7 @@ import org.springframework.web.bind.annotation.RestController;
"jwt-refresh-hint3", "jwt-refresh-hint3",
"jwt-refresh-hint4" "jwt-refresh-hint4"
}) })
public class JWTRefreshEndpoint extends AssignmentEndpoint { public class JWTRefreshEndpoint implements AssignmentEndpoint {
public static final String PASSWORD = "bm5nhSkxCXZkKRy4"; public static final String PASSWORD = "bm5nhSkxCXZkKRy4";
private static final String JWT_PASSWORD = "bm5n3SkxCX4kKRy4"; private static final String JWT_PASSWORD = "bm5n3SkxCX4kKRy4";

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.jwt; package org.owasp.webgoat.lessons.jwt;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
@ -44,7 +47,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"}) @AssignmentHints({"jwt-secret-hint1", "jwt-secret-hint2", "jwt-secret-hint3"})
public class JWTSecretKeyEndpoint extends AssignmentEndpoint { public class JWTSecretKeyEndpoint implements AssignmentEndpoint {
public static final String[] SECRETS = { public static final String[] SECRETS = {
"victory", "business", "available", "shipping", "washington" "victory", "business", "available", "shipping", "washington"

View File

@ -25,6 +25,8 @@ package org.owasp.webgoat.lessons.jwt;
import static java.util.Comparator.comparingLong; import static java.util.Comparator.comparingLong;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwt;
@ -66,13 +68,13 @@ import org.springframework.web.bind.annotation.RestController;
"jwt-change-token-hint4", "jwt-change-token-hint4",
"jwt-change-token-hint5" "jwt-change-token-hint5"
}) })
public class JWTVotesEndpoint extends AssignmentEndpoint { public class JWTVotesEndpoint implements AssignmentEndpoint {
public static final String JWT_PASSWORD = TextCodec.BASE64.encode("victory"); public static final String JWT_PASSWORD = TextCodec.BASE64.encode("victory");
private static String validUsers = "TomJerrySylvester"; private static String validUsers = "TomJerrySylvester";
private static int totalVotes = 38929; private static int totalVotes = 38929;
private Map<String, Vote> votes = new HashMap<>(); private final Map<String, Vote> votes = new HashMap<>();
@PostConstruct @PostConstruct
public void initVotes() { public void initVotes() {

View File

@ -1,5 +1,8 @@
package org.owasp.webgoat.lessons.jwt.claimmisuse; package org.owasp.webgoat.lessons.jwt.claimmisuse;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import com.auth0.jwk.JwkException; import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProviderBuilder; import com.auth0.jwk.JwkProviderBuilder;
import com.auth0.jwt.JWT; import com.auth0.jwt.JWT;
@ -19,7 +22,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/JWT/jku") @RequestMapping("/JWT/")
@RestController @RestController
@AssignmentHints({ @AssignmentHints({
"jwt-jku-hint1", "jwt-jku-hint1",
@ -28,9 +31,9 @@ import org.springframework.web.bind.annotation.RestController;
"jwt-jku-hint4", "jwt-jku-hint4",
"jwt-jku-hint5" "jwt-jku-hint5"
}) })
public class JWTHeaderJKUEndpoint extends AssignmentEndpoint { public class JWTHeaderJKUEndpoint implements AssignmentEndpoint {
@PostMapping("/follow/{user}") @PostMapping("jku/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) { public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) { if ("Jerry".equals(user)) {
return "Following yourself seems redundant"; return "Following yourself seems redundant";
@ -39,7 +42,7 @@ public class JWTHeaderJKUEndpoint extends AssignmentEndpoint {
} }
} }
@PostMapping("/delete") @PostMapping("jku/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) { public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build(); return failed(this).feedback("jwt-invalid-token").build();

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.jwt.claimmisuse; package org.owasp.webgoat.lessons.jwt.claimmisuse;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwt;
@ -52,16 +55,15 @@ import org.springframework.web.bind.annotation.RestController;
"jwt-kid-hint5", "jwt-kid-hint5",
"jwt-kid-hint6" "jwt-kid-hint6"
}) })
@RequestMapping("/JWT/kid") @RequestMapping("/JWT/")
public class JWTHeaderKIDEndpoint extends AssignmentEndpoint { public class JWTHeaderKIDEndpoint implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
private JWTHeaderKIDEndpoint(LessonDataSource dataSource) { private JWTHeaderKIDEndpoint(LessonDataSource dataSource) {
this.dataSource = dataSource; this.dataSource = dataSource;
} }
@PostMapping("/follow/{user}") @PostMapping("kid/follow/{user}")
public @ResponseBody String follow(@PathVariable("user") String user) { public @ResponseBody String follow(@PathVariable("user") String user) {
if ("Jerry".equals(user)) { if ("Jerry".equals(user)) {
return "Following yourself seems redundant"; return "Following yourself seems redundant";
@ -70,7 +72,7 @@ public class JWTHeaderKIDEndpoint extends AssignmentEndpoint {
} }
} }
@PostMapping("/delete") @PostMapping("kid/delete")
public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) { public @ResponseBody AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) { if (StringUtils.isEmpty(token)) {
return failed(this).feedback("jwt-invalid-token").build(); return failed(this).feedback("jwt-invalid-token").build();

View File

@ -22,13 +22,15 @@
package org.owasp.webgoat.lessons.lessontemplate; package org.owasp.webgoat.lessons.lessontemplate;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.owasp.webgoat.container.session.LessonSession; import org.owasp.webgoat.container.session.LessonSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -39,12 +41,14 @@ import org.springframework.web.bind.annotation.RestController;
/** Created by jason on 1/5/17. */ /** Created by jason on 1/5/17. */
@RestController @RestController
@AssignmentHints({"lesson-template.hints.1", "lesson-template.hints.2", "lesson-template.hints.3"}) @AssignmentHints({"lesson-template.hints.1", "lesson-template.hints.2", "lesson-template.hints.3"})
public class SampleAttack extends AssignmentEndpoint { public class SampleAttack implements AssignmentEndpoint {
private static final String secretValue = "secr37Value";
String secretValue = "secr37Value"; private final LessonSession userSessionData;
// UserSessionData is bound to session and can be used to persist data across multiple assignments public SampleAttack(LessonSession userSessionData) {
@Autowired LessonSession userSessionData; this.userSessionData = userSessionData;
}
@PostMapping("/lesson-template/sample-attack") @PostMapping("/lesson-template/sample-attack")
@ResponseBody @ResponseBody

View File

@ -22,7 +22,9 @@
package org.owasp.webgoat.lessons.logging; package org.owasp.webgoat.lessons.logging;
import jakarta.annotation.PostConstruct; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
import java.util.UUID; import java.util.UUID;
@ -37,14 +39,13 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class LogBleedingTask extends AssignmentEndpoint { public class LogBleedingTask implements AssignmentEndpoint {
Logger log = LoggerFactory.getLogger(this.getClass().getName()); private static final Logger log = LoggerFactory.getLogger(LogBleedingTask.class);
private String password; private final String password;
@PostConstruct public LogBleedingTask() {
public void generatePassword() { this.password = UUID.randomUUID().toString();
password = UUID.randomUUID().toString();
log.info( log.info(
"Password for admin: {}", "Password for admin: {}",
Base64.getEncoder().encodeToString(password.getBytes(StandardCharsets.UTF_8))); Base64.getEncoder().encodeToString(password.getBytes(StandardCharsets.UTF_8)));

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.logging; package org.owasp.webgoat.lessons.logging;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.apache.logging.log4j.util.Strings; import org.apache.logging.log4j.util.Strings;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -31,7 +34,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class LogSpoofingTask extends AssignmentEndpoint { public class LogSpoofingTask implements AssignmentEndpoint {
@PostMapping("/LogSpoofing/log-spoofing") @PostMapping("/LogSpoofing/log-spoofing")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.missingac; package org.owasp.webgoat.lessons.missingac;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -36,7 +39,7 @@ import org.springframework.web.bind.annotation.RestController;
"access-control.hidden-menus.hint2", "access-control.hidden-menus.hint2",
"access-control.hidden-menus.hint3" "access-control.hidden-menus.hint3"
}) })
public class MissingFunctionACHiddenMenus extends AssignmentEndpoint { public class MissingFunctionACHiddenMenus implements AssignmentEndpoint {
@PostMapping( @PostMapping(
path = "/access-control/hidden-menu", path = "/access-control/hidden-menu",

View File

@ -22,9 +22,10 @@
package org.owasp.webgoat.lessons.missingac; package org.owasp.webgoat.lessons.missingac;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.owasp.webgoat.lessons.missingac.MissingFunctionAC.PASSWORD_SALT_SIMPLE; import static org.owasp.webgoat.lessons.missingac.MissingFunctionAC.PASSWORD_SALT_SIMPLE;
import lombok.RequiredArgsConstructor;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -40,11 +41,14 @@ import org.springframework.web.bind.annotation.RestController;
"access-control.hash.hint4", "access-control.hash.hint4",
"access-control.hash.hint5" "access-control.hash.hint5"
}) })
@RequiredArgsConstructor public class MissingFunctionACYourHash implements AssignmentEndpoint {
public class MissingFunctionACYourHash extends AssignmentEndpoint {
private final MissingAccessControlUserRepository userRepository; private final MissingAccessControlUserRepository userRepository;
public MissingFunctionACYourHash(MissingAccessControlUserRepository userRepository) {
this.userRepository = userRepository;
}
@PostMapping( @PostMapping(
path = "/access-control/user-hash", path = "/access-control/user-hash",
produces = {"application/json"}) produces = {"application/json"})

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.missingac; package org.owasp.webgoat.lessons.missingac;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.owasp.webgoat.lessons.missingac.MissingFunctionAC.PASSWORD_SALT_ADMIN; import static org.owasp.webgoat.lessons.missingac.MissingFunctionAC.PASSWORD_SALT_ADMIN;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -42,7 +44,7 @@ import org.springframework.web.bind.annotation.RestController;
"access-control.hash.hint12", "access-control.hash.hint12",
"access-control.hash.hint13" "access-control.hash.hint13"
}) })
public class MissingFunctionACYourHashAdmin extends AssignmentEndpoint { public class MissingFunctionACYourHashAdmin implements AssignmentEndpoint {
private final MissingAccessControlUserRepository userRepository; private final MissingAccessControlUserRepository userRepository;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.passwordreset; package org.owasp.webgoat.lessons.passwordreset;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
* @since 8/20/17. * @since 8/20/17.
*/ */
@RestController @RestController
public class QuestionsAssignment extends AssignmentEndpoint { public class QuestionsAssignment implements AssignmentEndpoint {
private static final Map<String, String> COLORS = new HashMap<>(); private static final Map<String, String> COLORS = new HashMap<>();

View File

@ -22,6 +22,10 @@
package org.owasp.webgoat.lessons.passwordreset; package org.owasp.webgoat.lessons.passwordreset;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.springframework.util.StringUtils.hasText;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -56,7 +60,7 @@ import org.springframework.web.servlet.ModelAndView;
"password-reset-hint5", "password-reset-hint5",
"password-reset-hint6" "password-reset-hint6"
}) })
public class ResetLinkAssignment extends AssignmentEndpoint { public class ResetLinkAssignment implements AssignmentEndpoint {
private static final String VIEW_FORMATTER = "lessons/passwordreset/templates/%s.html"; private static final String VIEW_FORMATTER = "lessons/passwordreset/templates/%s.html";
static final String PASSWORD_TOM_9 = static final String PASSWORD_TOM_9 =
@ -117,7 +121,7 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
BindingResult bindingResult, BindingResult bindingResult,
@CurrentUsername String username) { @CurrentUsername String username) {
ModelAndView modelAndView = new ModelAndView(); ModelAndView modelAndView = new ModelAndView();
if (!org.springframework.util.StringUtils.hasText(form.getPassword())) { if (!hasText(form.getPassword())) {
bindingResult.rejectValue("password", "not.empty"); bindingResult.rejectValue("password", "not.empty");
} }
if (bindingResult.hasErrors()) { if (bindingResult.hasErrors()) {

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.passwordreset; package org.owasp.webgoat.lessons.passwordreset;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.util.UUID; import java.util.UUID;
import org.owasp.webgoat.container.CurrentUsername; import org.owasp.webgoat.container.CurrentUsername;
@ -44,12 +47,12 @@ import org.springframework.web.client.RestTemplate;
* @since 8/20/17. * @since 8/20/17.
*/ */
@RestController @RestController
public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint { public class ResetLinkAssignmentForgotPassword implements AssignmentEndpoint {
private final RestTemplate restTemplate; private final RestTemplate restTemplate;
private String webWolfHost; private final String webWolfHost;
private String webWolfPort; private final String webWolfPort;
private String webWolfURL; private final String webWolfURL;
private final String webWolfMailURL; private final String webWolfMailURL;
public ResetLinkAssignmentForgotPassword( public ResetLinkAssignmentForgotPassword(

View File

@ -23,12 +23,13 @@
package org.owasp.webgoat.lessons.passwordreset; package org.owasp.webgoat.lessons.passwordreset;
import static java.util.Optional.of; import static java.util.Optional.of;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.informationMessage;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
@ -41,9 +42,9 @@ import org.springframework.web.bind.annotation.RestController;
* @since 11.12.18 * @since 11.12.18
*/ */
@RestController @RestController
public class SecurityQuestionAssignment extends AssignmentEndpoint { public class SecurityQuestionAssignment implements AssignmentEndpoint {
@Autowired private TriedQuestions triedQuestions; private final TriedQuestions triedQuestions;
private static Map<String, String> questions; private static Map<String, String> questions;
@ -90,6 +91,10 @@ public class SecurityQuestionAssignment extends AssignmentEndpoint {
questions.put("What is your favorite color?", "Can easily be guessed."); questions.put("What is your favorite color?", "Can easily be guessed.");
} }
public SecurityQuestionAssignment(TriedQuestions triedQuestions) {
this.triedQuestions = triedQuestions;
}
@PostMapping("/PasswordReset/SecurityQuestions") @PostMapping("/PasswordReset/SecurityQuestions")
@ResponseBody @ResponseBody
public AttackResult completed(@RequestParam String question) { public AttackResult completed(@RequestParam String question) {

View File

@ -23,6 +23,9 @@
package org.owasp.webgoat.lessons.passwordreset; package org.owasp.webgoat.lessons.passwordreset;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.informationMessage;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -43,8 +46,7 @@ import org.springframework.web.client.RestTemplate;
* @since 8/20/17. * @since 8/20/17.
*/ */
@RestController @RestController
public class SimpleMailAssignment extends AssignmentEndpoint { public class SimpleMailAssignment implements AssignmentEndpoint {
private final String webWolfURL; private final String webWolfURL;
private RestTemplate restTemplate; private RestTemplate restTemplate;

View File

@ -1,5 +1,9 @@
package org.owasp.webgoat.lessons.pathtraversal; package org.owasp.webgoat.lessons.pathtraversal;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.informationMessage;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
@ -7,7 +11,6 @@ import java.nio.file.Files;
import java.util.Arrays; import java.util.Arrays;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
@ -21,11 +24,14 @@ import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@AllArgsConstructor
@Getter @Getter
public class ProfileUploadBase extends AssignmentEndpoint { public class ProfileUploadBase implements AssignmentEndpoint {
private String webGoatHomeDirectory; private final String webGoatHomeDirectory;
public ProfileUploadBase(String webGoatHomeDirectory) {
this.webGoatHomeDirectory = webGoatHomeDirectory;
}
protected AttackResult execute(MultipartFile file, String fullName, String username) { protected AttackResult execute(MultipartFile file, String fullName, String username) {
if (file.isEmpty()) { if (file.isEmpty()) {

View File

@ -1,5 +1,8 @@
package org.owasp.webgoat.lessons.pathtraversal; package org.owasp.webgoat.lessons.pathtraversal;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import java.io.File; import java.io.File;
@ -40,8 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
"path-traversal-profile-retrieve.hint6" "path-traversal-profile-retrieve.hint6"
}) })
@Slf4j @Slf4j
public class ProfileUploadRetrieval extends AssignmentEndpoint { public class ProfileUploadRetrieval implements AssignmentEndpoint {
private final File catPicturesDirectory; private final File catPicturesDirectory;
public ProfileUploadRetrieval(@Value("${webgoat.server.directory}") String webGoatHomeDirectory) { public ProfileUploadRetrieval(@Value("${webgoat.server.directory}") String webGoatHomeDirectory) {

View File

@ -1,5 +1,7 @@
package org.owasp.webgoat.lessons.pathtraversal; package org.owasp.webgoat.lessons.pathtraversal;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import static org.springframework.http.MediaType.ALL_VALUE; import static org.springframework.http.MediaType.ALL_VALUE;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.securepasswords; package org.owasp.webgoat.lessons.securepasswords;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import com.nulabinc.zxcvbn.Strength; import com.nulabinc.zxcvbn.Strength;
import com.nulabinc.zxcvbn.Zxcvbn; import com.nulabinc.zxcvbn.Zxcvbn;
import java.text.DecimalFormat; import java.text.DecimalFormat;
@ -35,7 +38,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class SecurePasswordsAssignment extends AssignmentEndpoint { public class SecurePasswordsAssignment implements AssignmentEndpoint {
@PostMapping("SecurePasswords/assignment") @PostMapping("SecurePasswords/assignment")
@ResponseBody @ResponseBody

View File

@ -23,6 +23,10 @@
package org.owasp.webgoat.lessons.spoofcookie; package org.owasp.webgoat.lessons.spoofcookie;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.informationMessage;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.servlet.http.Cookie; import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.util.Map; import java.util.Map;
@ -48,7 +52,7 @@ import org.springframework.web.bind.annotation.RestController;
@AssignmentHints({"spoofcookie.hint1", "spoofcookie.hint2", "spoofcookie.hint3"}) @AssignmentHints({"spoofcookie.hint1", "spoofcookie.hint2", "spoofcookie.hint3"})
@RestController @RestController
public class SpoofCookieAssignment extends AssignmentEndpoint { public class SpoofCookieAssignment implements AssignmentEndpoint {
private static final String COOKIE_NAME = "spoof_auth"; private static final String COOKIE_NAME = "spoof_auth";
private static final String COOKIE_INFO = private static final String COOKIE_INFO =

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.advanced; package org.owasp.webgoat.lessons.sqlinjection.advanced;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.*; import java.sql.*;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.container.LessonDataSource; import org.owasp.webgoat.container.LessonDataSource;
@ -42,7 +45,7 @@ import org.springframework.web.bind.annotation.RestController;
@AssignmentHints( @AssignmentHints(
value = {"SqlInjectionChallenge1", "SqlInjectionChallenge2", "SqlInjectionChallenge3"}) value = {"SqlInjectionChallenge1", "SqlInjectionChallenge2", "SqlInjectionChallenge3"})
@Slf4j @Slf4j
public class SqlInjectionChallenge extends AssignmentEndpoint { public class SqlInjectionChallenge implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.advanced; package org.owasp.webgoat.lessons.sqlinjection.advanced;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.LessonDataSource; import org.owasp.webgoat.container.LessonDataSource;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
@ -39,8 +42,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlInjectionChallengeHint3", "SqlInjectionChallengeHint3",
"SqlInjectionChallengeHint4" "SqlInjectionChallengeHint4"
}) })
public class SqlInjectionChallengeLogin extends AssignmentEndpoint { public class SqlInjectionChallengeLogin implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
public SqlInjectionChallengeLogin(LessonDataSource dataSource) { public SqlInjectionChallengeLogin(LessonDataSource dataSource) {

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.advanced; package org.owasp.webgoat.lessons.sqlinjection.advanced;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
@ -46,8 +49,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint-advanced-6a-4", "SqlStringInjectionHint-advanced-6a-4",
"SqlStringInjectionHint-advanced-6a-5" "SqlStringInjectionHint-advanced-6a-5"
}) })
public class SqlInjectionLesson6a extends AssignmentEndpoint { public class SqlInjectionLesson6a implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
private static final String YOUR_QUERY_WAS = "<br> Your query was: "; private static final String YOUR_QUERY_WAS = "<br> Your query was: ";

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.advanced; package org.owasp.webgoat.lessons.sqlinjection.advanced;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -36,8 +39,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class SqlInjectionLesson6b extends AssignmentEndpoint { public class SqlInjectionLesson6b implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
public SqlInjectionLesson6b(LessonDataSource dataSource) { public SqlInjectionLesson6b(LessonDataSource dataSource) {

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.advanced; package org.owasp.webgoat.lessons.sqlinjection.advanced;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.IOException; import java.io.IOException;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
* implement the quiz go to the quiz.js file in webgoat-container -> js * implement the quiz go to the quiz.js file in webgoat-container -> js
*/ */
@RestController @RestController
public class SqlInjectionQuiz extends AssignmentEndpoint { public class SqlInjectionQuiz implements AssignmentEndpoint {
String[] solutions = {"Solution 4", "Solution 3", "Solution 2", "Solution 3", "Solution 4"}; String[] solutions = {"Solution 4", "Solution 3", "Solution 2", "Solution 3", "Solution 4"};
boolean[] guesses = new boolean[solutions.length]; boolean[] guesses = new boolean[solutions.length];

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.introduction; package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
@ -45,7 +48,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint.10.5", "SqlStringInjectionHint.10.5",
"SqlStringInjectionHint.10.6" "SqlStringInjectionHint.10.6"
}) })
public class SqlInjectionLesson10 extends AssignmentEndpoint { public class SqlInjectionLesson10 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
@ -120,8 +123,7 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
if (errorMsg.contains("object not found: ACCESS_LOG")) { if (errorMsg.contains("object not found: ACCESS_LOG")) {
return false; return false;
} else { } else {
System.err.println(e.getMessage()); return true;
return false;
} }
} }
} }

View File

@ -24,6 +24,8 @@ package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
@ -45,7 +47,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint2-3", "SqlStringInjectionHint2-3",
"SqlStringInjectionHint2-4" "SqlStringInjectionHint2-4"
}) })
public class SqlInjectionLesson2 extends AssignmentEndpoint { public class SqlInjectionLesson2 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -24,6 +24,8 @@ package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -40,7 +42,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints(value = {"SqlStringInjectionHint3-1", "SqlStringInjectionHint3-2"}) @AssignmentHints(value = {"SqlStringInjectionHint3-1", "SqlStringInjectionHint3-2"})
public class SqlInjectionLesson3 extends AssignmentEndpoint { public class SqlInjectionLesson3 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -24,6 +24,8 @@ package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static java.sql.ResultSet.CONCUR_READ_ONLY; import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE; import static java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -41,7 +43,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints( @AssignmentHints(
value = {"SqlStringInjectionHint4-1", "SqlStringInjectionHint4-2", "SqlStringInjectionHint4-3"}) value = {"SqlStringInjectionHint4-1", "SqlStringInjectionHint4-2", "SqlStringInjectionHint4-3"})
public class SqlInjectionLesson4 extends AssignmentEndpoint { public class SqlInjectionLesson4 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.introduction; package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -43,7 +46,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint5-3", "SqlStringInjectionHint5-3",
"SqlStringInjectionHint5-4" "SqlStringInjectionHint5-4"
}) })
public class SqlInjectionLesson5 extends AssignmentEndpoint { public class SqlInjectionLesson5 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.introduction; package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.*; import java.sql.*;
import org.owasp.webgoat.container.LessonDataSource; import org.owasp.webgoat.container.LessonDataSource;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -34,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints(value = {"SqlStringInjectionHint5a1"}) @AssignmentHints(value = {"SqlStringInjectionHint5a1"})
public class SqlInjectionLesson5a extends AssignmentEndpoint { public class SqlInjectionLesson5a implements AssignmentEndpoint {
private static final String EXPLANATION = private static final String EXPLANATION =
"<br> Explanation: This injection works, because <span style=\"font-style: italic\">or '1' =" "<br> Explanation: This injection works, because <span style=\"font-style: italic\">or '1' ="

View File

@ -22,7 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.introduction; package org.owasp.webgoat.lessons.sqlinjection.introduction;
import jakarta.servlet.http.HttpServletRequest; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.IOException; import java.io.IOException;
import java.sql.*; import java.sql.*;
import org.owasp.webgoat.container.LessonDataSource; import org.owasp.webgoat.container.LessonDataSource;
@ -42,7 +44,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint5b3", "SqlStringInjectionHint5b3",
"SqlStringInjectionHint5b4" "SqlStringInjectionHint5b4"
}) })
public class SqlInjectionLesson5b extends AssignmentEndpoint { public class SqlInjectionLesson5b implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
@ -52,8 +54,7 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint {
@PostMapping("/SqlInjection/assignment5b") @PostMapping("/SqlInjection/assignment5b")
@ResponseBody @ResponseBody
public AttackResult completed( public AttackResult completed(@RequestParam String userid, @RequestParam String login_count)
@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request)
throws IOException { throws IOException {
return injectableQuery(login_count, userid); return injectableQuery(login_count, userid);
} }

View File

@ -24,6 +24,8 @@ package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static java.sql.ResultSet.CONCUR_UPDATABLE; import static java.sql.ResultSet.CONCUR_UPDATABLE;
import static java.sql.ResultSet.TYPE_SCROLL_SENSITIVE; import static java.sql.ResultSet.TYPE_SCROLL_SENSITIVE;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.*; import java.sql.*;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -46,7 +48,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint.8.4", "SqlStringInjectionHint.8.4",
"SqlStringInjectionHint.8.5" "SqlStringInjectionHint.8.5"
}) })
public class SqlInjectionLesson8 extends AssignmentEndpoint { public class SqlInjectionLesson8 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;

View File

@ -24,6 +24,8 @@ package org.owasp.webgoat.lessons.sqlinjection.introduction;
import static org.hsqldb.jdbc.JDBCResultSet.CONCUR_UPDATABLE; import static org.hsqldb.jdbc.JDBCResultSet.CONCUR_UPDATABLE;
import static org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_SENSITIVE; import static org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_SENSITIVE;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -47,7 +49,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint.9.4", "SqlStringInjectionHint.9.4",
"SqlStringInjectionHint.9.5" "SqlStringInjectionHint.9.5"
}) })
public class SqlInjectionLesson9 extends AssignmentEndpoint { public class SqlInjectionLesson9 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
@ -99,7 +101,6 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
SqlInjectionLesson8.generateTable(this.getEmployeesDataOrderBySalaryDesc(connection))) SqlInjectionLesson8.generateTable(this.getEmployeesDataOrderBySalaryDesc(connection)))
.build(); .build();
} catch (SQLException e) { } catch (SQLException e) {
System.err.println(e.getMessage());
return failed(this) return failed(this)
.output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>") .output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>")
.build(); .build();

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.mitigation; package org.owasp.webgoat.lessons.sqlinjection.mitigation;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
@ -35,9 +38,9 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j @Slf4j
@AssignmentHints( @AssignmentHints(
value = {"SqlStringInjectionHint-mitigation-10a-1", "SqlStringInjectionHint-mitigation-10a-2"}) value = {"SqlStringInjectionHint-mitigation-10a-1", "SqlStringInjectionHint-mitigation-10a-2"})
public class SqlInjectionLesson10a extends AssignmentEndpoint { public class SqlInjectionLesson10a implements AssignmentEndpoint {
private String[] results = { private static final String[] results = {
"getConnection", "PreparedStatement", "prepareStatement", "?", "?", "setString", "setString" "getConnection", "PreparedStatement", "prepareStatement", "?", "?", "setString", "setString"
}; };

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.mitigation; package org.owasp.webgoat.lessons.sqlinjection.mitigation;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
@ -52,7 +55,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint-mitigation-10b-4", "SqlStringInjectionHint-mitigation-10b-4",
"SqlStringInjectionHint-mitigation-10b-5" "SqlStringInjectionHint-mitigation-10b-5"
}) })
public class SqlInjectionLesson10b extends AssignmentEndpoint { public class SqlInjectionLesson10b implements AssignmentEndpoint {
@PostMapping("/SqlInjectionMitigations/attack10b") @PostMapping("/SqlInjectionMitigations/attack10b")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.sqlinjection.mitigation; package org.owasp.webgoat.lessons.sqlinjection.mitigation;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -45,7 +48,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlStringInjectionHint-mitigation-13-4" "SqlStringInjectionHint-mitigation-13-4"
}) })
@Slf4j @Slf4j
public class SqlInjectionLesson13 extends AssignmentEndpoint { public class SqlInjectionLesson13 implements AssignmentEndpoint {
private final LessonDataSource dataSource; private final LessonDataSource dataSource;
@ -68,7 +71,7 @@ public class SqlInjectionLesson13 extends AssignmentEndpoint {
return failed(this).build(); return failed(this).build();
} catch (SQLException e) { } catch (SQLException e) {
log.error("Failed", e); log.error("Failed", e);
return (failed(this).build()); return failed(this).build();
} }
} }
} }

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.sqlinjection.mitigation; package org.owasp.webgoat.lessons.sqlinjection.mitigation;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -34,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints( @AssignmentHints(
value = {"SqlOnlyInputValidation-1", "SqlOnlyInputValidation-2", "SqlOnlyInputValidation-3"}) value = {"SqlOnlyInputValidation-1", "SqlOnlyInputValidation-2", "SqlOnlyInputValidation-3"})
public class SqlOnlyInputValidation extends AssignmentEndpoint { public class SqlOnlyInputValidation implements AssignmentEndpoint {
private final SqlInjectionLesson6a lesson6a; private final SqlInjectionLesson6a lesson6a;
@ -52,7 +54,9 @@ public class SqlOnlyInputValidation extends AssignmentEndpoint {
return new AttackResult( return new AttackResult(
attackResult.isLessonCompleted(), attackResult.isLessonCompleted(),
attackResult.getFeedback(), attackResult.getFeedback(),
attackResult.getFeedbackArgs(),
attackResult.getOutput(), attackResult.getOutput(),
attackResult.getOutputArgs(),
getClass().getSimpleName(), getClass().getSimpleName(),
true); true);
} }

View File

@ -22,6 +22,8 @@
package org.owasp.webgoat.lessons.sqlinjection.mitigation; package org.owasp.webgoat.lessons.sqlinjection.mitigation;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -38,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
"SqlOnlyInputValidationOnKeywords-2", "SqlOnlyInputValidationOnKeywords-2",
"SqlOnlyInputValidationOnKeywords-3" "SqlOnlyInputValidationOnKeywords-3"
}) })
public class SqlOnlyInputValidationOnKeywords extends AssignmentEndpoint { public class SqlOnlyInputValidationOnKeywords implements AssignmentEndpoint {
private final SqlInjectionLesson6a lesson6a; private final SqlInjectionLesson6a lesson6a;
@ -58,7 +60,9 @@ public class SqlOnlyInputValidationOnKeywords extends AssignmentEndpoint {
return new AttackResult( return new AttackResult(
attackResult.isLessonCompleted(), attackResult.isLessonCompleted(),
attackResult.getFeedback(), attackResult.getFeedback(),
attackResult.getFeedbackArgs(),
attackResult.getOutput(), attackResult.getOutput(),
attackResult.getOutputArgs(),
getClass().getSimpleName(), getClass().getSimpleName(),
true); true);
} }

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.ssrf; package org.owasp.webgoat.lessons.ssrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AssignmentHints;
import org.owasp.webgoat.container.assignments.AttackResult; import org.owasp.webgoat.container.assignments.AttackResult;
@ -32,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"ssrf.hint1", "ssrf.hint2"}) @AssignmentHints({"ssrf.hint1", "ssrf.hint2"})
public class SSRFTask1 extends AssignmentEndpoint { public class SSRFTask1 implements AssignmentEndpoint {
@PostMapping("/SSRF/task1") @PostMapping("/SSRF/task1")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.ssrf; package org.owasp.webgoat.lessons.ssrf;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException; import java.net.MalformedURLException;
@ -37,7 +40,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"ssrf.hint3"}) @AssignmentHints({"ssrf.hint3"})
public class SSRFTask2 extends AssignmentEndpoint { public class SSRFTask2 implements AssignmentEndpoint {
@PostMapping("/SSRF/task2") @PostMapping("/SSRF/task2")
@ResponseBody @ResponseBody

View File

@ -22,6 +22,9 @@
package org.owasp.webgoat.lessons.vulnerablecomponents; package org.owasp.webgoat.lessons.vulnerablecomponents;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -34,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@AssignmentHints({"vulnerable.hint"}) @AssignmentHints({"vulnerable.hint"})
public class VulnerableComponentsLesson extends AssignmentEndpoint { public class VulnerableComponentsLesson implements AssignmentEndpoint {
@PostMapping("/VulnerableComponents/attack1") @PostMapping("/VulnerableComponents/attack1")
public @ResponseBody AttackResult completed(@RequestParam String payload) { public @ResponseBody AttackResult completed(@RequestParam String payload) {

View File

@ -22,9 +22,9 @@
package org.owasp.webgoat.lessons.webwolfintroduction; package org.owasp.webgoat.lessons.webwolfintroduction;
import jakarta.servlet.http.HttpServletRequest; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import java.net.URI; import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import java.net.URISyntaxException;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.container.CurrentUsername; import org.owasp.webgoat.container.CurrentUsername;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -41,10 +41,12 @@ import org.springframework.web.servlet.ModelAndView;
* @since 8/20/17. * @since 8/20/17.
*/ */
@RestController @RestController
public class LandingAssignment extends AssignmentEndpoint { public class LandingAssignment implements AssignmentEndpoint {
private final String landingPageUrl;
@Value("${webwolf.landingpage.url}") public LandingAssignment(@Value("${webwolf.landingpage.url}") String landingPageUrl) {
private String landingPageUrl; this.landingPageUrl = landingPageUrl;
}
@PostMapping("/WebWolf/landing") @PostMapping("/WebWolf/landing")
@ResponseBody @ResponseBody
@ -56,9 +58,7 @@ public class LandingAssignment extends AssignmentEndpoint {
} }
@GetMapping("/WebWolf/landing/password-reset") @GetMapping("/WebWolf/landing/password-reset")
public ModelAndView openPasswordReset( public ModelAndView openPasswordReset(@CurrentUsername String username) {
HttpServletRequest request, @CurrentUsername String username) throws URISyntaxException {
URI uri = new URI(request.getRequestURL().toString());
ModelAndView modelAndView = new ModelAndView(); ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject( modelAndView.addObject(
"webwolfLandingPageUrl", landingPageUrl.replace("//landing", "/landing")); "webwolfLandingPageUrl", landingPageUrl.replace("//landing", "/landing"));

View File

@ -22,6 +22,10 @@
package org.owasp.webgoat.lessons.webwolfintroduction; package org.owasp.webgoat.lessons.webwolfintroduction;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.failed;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.informationMessage;
import static org.owasp.webgoat.container.assignments.AttackResultBuilder.success;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.owasp.webgoat.container.CurrentUsername; import org.owasp.webgoat.container.CurrentUsername;
import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentEndpoint;
@ -39,7 +43,7 @@ import org.springframework.web.client.RestTemplate;
* @since 8/20/17. * @since 8/20/17.
*/ */
@RestController @RestController
public class MailAssignment extends AssignmentEndpoint { public class MailAssignment implements AssignmentEndpoint {
private final String webWolfURL; private final String webWolfURL;
private RestTemplate restTemplate; private RestTemplate restTemplate;

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