Renamed to lessontemplate
This commit is contained in:
@ -0,0 +1,111 @@
|
||||
=== Step 4: Add an assignment to your lesson
|
||||
|
||||
With an assignment, a user can practice within a lesson. A lesson can consist of multiple assignments, each assignment
|
||||
needs to extend the class `AssignmentEndpoint`, let's look at an example:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@RestController // <1>
|
||||
@AssignmentHints({"lesson-template.hints.1", "lesson-template.hints.2", "lesson-template.hints.3"}) // <2>
|
||||
public class SampleAttack extends AssignmentEndpoint { // <3>
|
||||
|
||||
private final String secretValue = "secr37Value";
|
||||
|
||||
@Autowired
|
||||
private UserSessionData userSessionData; // <4>
|
||||
|
||||
@PostMapping("/lesson-template/sample-attack") <5>
|
||||
@ResponseBody
|
||||
public AttackResult completed(@RequestParam("param1") String param1, @RequestParam("param2") String param2) { <6>
|
||||
if (userSessionData.getValue("some-value") != null) {
|
||||
// do any session updating you want here ... or not, just comment/example here
|
||||
//return failed(this).feedback("lesson-template.sample-attack.failure-2").build();
|
||||
}
|
||||
|
||||
//overly simple example for success. See other existing lesssons for ways to detect 'success' or 'failure'
|
||||
if (secretValue.equals(param1)) {
|
||||
return success(this) // <7>
|
||||
.output("Custom Output ...if you want, for success")
|
||||
.feedback("lesson-template.sample-attack.success")
|
||||
.build();
|
||||
//lesson-template.sample-attack.success is defined in src/main/resources/i18n/WebGoatLabels.properties
|
||||
}
|
||||
|
||||
// else
|
||||
return failed(this) // <8>
|
||||
.feedback("lesson-template.sample-attack.failure-2")
|
||||
.output("Custom output for this failure scenario, usually html that will get rendered directly ... yes, you can self-xss if you want")
|
||||
.build();
|
||||
}
|
||||
----
|
||||
<1> Every assignment is just a Spring RestController
|
||||
<2> Each assignment can have a list of hints. The actual text needs to be placed in `WebGoatLabels.properties` in the folder `src/main/resources/{lessonName}/i18n`
|
||||
<3> Each assignment needs to extend the class `AssignmentEndpoint`, giving you some helpful methods you need when you want to mark an assignment as complete
|
||||
<4> As the assignment is a Spring-based class, you can auto wire every component managed by Spring necessary for the assignment
|
||||
<5> Each assignment should at least have one mapping with the method signature (see 6)
|
||||
<6> When the user tries to solve an assignment, you need return an `AttackResult`
|
||||
<7> Returning a successful attack result when user solved the lesson
|
||||
<8> Returning a failed attack user did not solve the lesson
|
||||
|
||||
{nbsp} +
|
||||
|
||||
As you can see, an assignment is a REST controller which needs to at least have one method with the following signature:
|
||||
|
||||
[source]
|
||||
----
|
||||
@RequestMapping(method = "...", path = "/lesson-template/solution")
|
||||
@ResponseBody
|
||||
public AttackResult solve(String param) {
|
||||
...
|
||||
}
|
||||
----
|
||||
|
||||
=== Extra endpoints
|
||||
|
||||
Other endpoints can be added in the assignment to support different cases for the assignment, for example:
|
||||
|
||||
[source]
|
||||
----
|
||||
@GetMapping("lesson-template/shop/{user}")
|
||||
@ResponseBody
|
||||
public List<Item> getItemsInBasket(@PathVariable("user") String user) {
|
||||
return List.of(new Item("WG-1", "WebGoat promo", 12.0), new Item("WG-2", "WebGoat sticker", 0.00));
|
||||
}
|
||||
----
|
||||
|
||||
=== Adding an assignment to the HTML page
|
||||
|
||||
We mentioned a lesson could consist of multiple assignments, WebGoat picks them up automatically, and the UI displays
|
||||
a navigation bar on top of every lesson. A page with an assignment will be red initially and will become
|
||||
green when the user solves the assignment. To make this work we need to add to the HTML file:
|
||||
|
||||
[source]
|
||||
----
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lesson-template-attack.adoc"></div>
|
||||
<div class="attack-container">
|
||||
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
|
||||
<form class="attack-form" accept-charset="UNKNOWN"
|
||||
method="POST" name="form"
|
||||
action="/WebGoat/lesson-template/sample-attack">
|
||||
<table>
|
||||
<tr>
|
||||
<td>two random params</td>
|
||||
<td>parameter 1:<input name="param1" value="" type="TEXT" /></td>
|
||||
<td>parameter 2:<input name="param2" value="" type="TEXT" /></td>
|
||||
<td>
|
||||
<input name="submit" value="Submit" type="SUBMIT"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div class="attack-feedback"></div>
|
||||
<div class="attack-output"></div>
|
||||
</div>
|
||||
</div>
|
||||
----
|
||||
|
||||
So the `action` of the form should match the method which defines the check if the lesson has been solved or not
|
||||
see `public AttackResult solved()`
|
||||
|
||||
That's it. You have now successfully created your first WebGoat lesson, including an assignment!
|
@ -0,0 +1,36 @@
|
||||
== Step 1: writing content
|
||||
|
||||
Each lesson can consist of multiple pages with content (text) to explain the vulnerability at hand. The content
|
||||
is written in AsciiDoc[https://asciidoctor.org/docs/asciidoc-writers-guide/] which makes it very easy to write content (if you know Markdown, you know AsciiDoc).
|
||||
|
||||
You can find excellent tutorials online for the AsciiDoc syntax. We are just showing a basic overview below.
|
||||
Below we will describe some constructs often used within WebGoat.
|
||||
|
||||
=== Sub-heading
|
||||
|
||||
Check AsciiDoc for syntax, but more = means smaller headings. You can *bold* text and other things.
|
||||
|
||||
=== Structuring files
|
||||
|
||||
You should set up all content to these *.adoc files. The AsciiDoc files reside in the
|
||||
directory `/src/main/resources/{lesson}/documentation/`.
|
||||
|
||||
=== Images
|
||||
|
||||
Images can be referenced below, including setting style (recommended to use lesson-image as the style). The root is `/src/main/resources/{lesson}/images`
|
||||
|
||||
image::images/firefox-proxy-config.png[Firefox Proxy Config,510,634,style="lesson-image"]
|
||||
|
||||
=== Code block
|
||||
|
||||
Write code blocks as follows:
|
||||
|
||||
```
|
||||
[source]
|
||||
----
|
||||
public class A {
|
||||
|
||||
private String test;
|
||||
}
|
||||
----
|
||||
```
|
@ -0,0 +1,25 @@
|
||||
=== Database
|
||||
|
||||
If the new lesson needs to store or uses a database, you can add a create script in the directory `/src/main/resources/{lesson}/db/migration` folder.
|
||||
The file name needs to follow a specific convention: `V2019_11_10_1__new-lesson.sql`, so the first part is just the current date.
|
||||
In this file, you can for example, create tables and insert some data, for example:
|
||||
|
||||
[source]
|
||||
----
|
||||
CREATE TABLE servers(
|
||||
id varchar(10),
|
||||
hostname varchar(20),
|
||||
ip varchar(20),
|
||||
mac varchar(20),
|
||||
status varchar(20),
|
||||
description varchar(40)
|
||||
);
|
||||
|
||||
INSERT INTO servers VALUES ('1', 'webgoat-dev', '192.168.4.0', 'AA:BB:11:22:CC:DD', 'online', 'Development server');
|
||||
INSERT INTO servers VALUES ('2', 'webgoat-tst', '192.168.2.1', 'EE:FF:33:44:AB:CD', 'online', 'Test server');
|
||||
INSERT INTO servers VALUES ('3', 'webgoat-acc', '192.168.3.3', 'EF:12:FE:34:AA:CC', 'offline', 'Acceptance server');
|
||||
INSERT INTO servers VALUES ('4', 'webgoat-pre-prod', '192.168.6.4', 'EF:12:FE:34:AA:CC', 'offline', 'Pre-production server');
|
||||
INSERT INTO servers VALUES ('4', 'webgoat-prd', '104.130.219.202', 'FA:91:EB:82:DC:73', 'out of order', 'Production server');
|
||||
----
|
||||
|
||||
Creating a database will automatically allow WebGoat to reset the database to its original state.
|
@ -0,0 +1,34 @@
|
||||
=== Step 3: Write glue html page
|
||||
|
||||
We mentioned a lesson could consist of multiple assignments, WebGoat picks them up automatically, and the UI displays
|
||||
a navigation bar on top of every lesson. A page with an assignment will be red initially and will become
|
||||
green when the user solves the assignment. To make this work we need to add:
|
||||
|
||||
[source]
|
||||
----
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
|
||||
lesson-template-intro.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
|
||||
lesson-template-content.adoc"></div>
|
||||
</div>
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lessons/lessontemplate/documentation/
|
||||
lesson-template-lesson-class.adoc"></div>
|
||||
</div>
|
||||
</html>
|
||||
----
|
||||
|
||||
This file needs to be places in: `/src/main/resources/{lesson}/html/`. The name of the file should be the same as
|
||||
the Java class we created in step 2.
|
||||
|
||||
The snippet above will create three separate pages (navigation bar) with the adoc pages we created to create this lesson.
|
||||
|
||||
That's it we create a basic lesson with only content. To make it all work, you need to make the lesson available in
|
||||
WebGoat.
|
||||
|
||||
That's it. Start WebGoat, and your lesson will appear in the menu.
|
@ -0,0 +1,9 @@
|
||||
This lesson describes the steps needed to add a new lesson to WebGoat. In general, there are four steps:
|
||||
|
||||
- Write the content. In WebGoat, we use AsciiDoc as a format.
|
||||
- Create a lesson class
|
||||
- Write HTML glue page, so WebGoat knows how to display the content
|
||||
- Add one or more assignments within the lesson
|
||||
|
||||
Let's see how to create a new lesson.
|
||||
|
@ -0,0 +1,21 @@
|
||||
=== Step 2: adding a new lesson class
|
||||
|
||||
Each lesson can contain multiple assignments, first. Let's define a lesson class in Java:
|
||||
|
||||
[source]
|
||||
----
|
||||
@Component
|
||||
public class LessonTemplate extends Lesson {
|
||||
@Override
|
||||
public Category getDefaultCategory() {
|
||||
return Category.GENERAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "lesson-template.title";
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Add the new lesson to a new package under `org.owasp.webgoat.lessons`.
|
@ -0,0 +1,11 @@
|
||||
=== Even more content
|
||||
|
||||
You can include multiple adoc files in one page, by including them in the same `<div>`:
|
||||
|
||||
[source]
|
||||
----
|
||||
<div class="lesson-page-wrapper">
|
||||
<div class="adoc-content" th:replace="doc:lesson-template-video.adoc"></div>
|
||||
<div class="adoc-content" th:replace="doc:lesson-template-video-more.adoc"></div>
|
||||
</div>
|
||||
----
|
@ -0,0 +1,7 @@
|
||||
=== More Content, Video too ...
|
||||
|
||||
You can structure and format the content however you like. You can even include video if you like (but may be subject to browser support). You may want to make it more pertinent to web application security than this, though.
|
||||
|
||||
video::video/sample-video.m4v[width=480,start=5]
|
||||
|
||||
see http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#videos for more detail on video syntax
|
Reference in New Issue
Block a user