refactor: small updates and improvements in HTTP Basic lesson (#2024)
* refactor: cleanup attack result and builder * refactor: solve compiler warnings * feature: improve HTTP basics lesson Closes: #494
This commit is contained in:
parent
00f3538be2
commit
c3c520f487
@ -12,13 +12,13 @@ import org.owasp.webgoat.container.i18n.PluginMessages;
|
|||||||
@Getter
|
@Getter
|
||||||
public class AttackResult {
|
public class AttackResult {
|
||||||
|
|
||||||
private boolean lessonCompleted;
|
private final boolean lessonCompleted;
|
||||||
private String feedback;
|
private final String feedback;
|
||||||
private Object[] feedbackArgs;
|
private Object[] feedbackArgs;
|
||||||
private String output;
|
private final String output;
|
||||||
private Object[] outputArgs;
|
private Object[] outputArgs;
|
||||||
private final String assignment;
|
private final String assignment;
|
||||||
private boolean attemptWasMade;
|
private final boolean attemptWasMade;
|
||||||
|
|
||||||
private AttackResult(
|
private AttackResult(
|
||||||
boolean lessonCompleted,
|
boolean lessonCompleted,
|
||||||
|
@ -8,7 +8,6 @@ import org.owasp.webgoat.container.i18n.PluginMessages;
|
|||||||
|
|
||||||
public class AttackResultBuilder {
|
public class AttackResultBuilder {
|
||||||
|
|
||||||
private PluginMessages messages;
|
|
||||||
private boolean lessonCompleted;
|
private boolean lessonCompleted;
|
||||||
private Object[] feedbackArgs;
|
private Object[] feedbackArgs;
|
||||||
private String feedbackResourceBundleKey;
|
private String feedbackResourceBundleKey;
|
||||||
@ -16,13 +15,6 @@ public class AttackResultBuilder {
|
|||||||
private Object[] outputArgs;
|
private Object[] outputArgs;
|
||||||
private AssignmentEndpoint assignment;
|
private AssignmentEndpoint assignment;
|
||||||
private boolean attemptWasMade = false;
|
private boolean attemptWasMade = false;
|
||||||
private boolean assignmentCompleted;
|
|
||||||
|
|
||||||
public AttackResultBuilder(PluginMessages messages) {
|
|
||||||
this.messages = messages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AttackResultBuilder() {}
|
|
||||||
|
|
||||||
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
|
public AttackResultBuilder lessonCompleted(boolean lessonCompleted) {
|
||||||
this.lessonCompleted = lessonCompleted;
|
this.lessonCompleted = lessonCompleted;
|
||||||
@ -36,19 +28,6 @@ public class AttackResultBuilder {
|
|||||||
return this;
|
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) {
|
public AttackResultBuilder feedbackArgs(Object... args) {
|
||||||
this.feedbackArgs = args;
|
this.feedbackArgs = args;
|
||||||
return this;
|
return this;
|
||||||
@ -95,15 +74,14 @@ public class AttackResultBuilder {
|
|||||||
*
|
*
|
||||||
* <p>- Assignment is set to solved - Feedback message is set to 'assignment.solved'
|
* <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
|
* <p>Of course, you can overwrite these values in a specific lesson
|
||||||
*
|
*
|
||||||
|
* @param assignment the assignment that was solved
|
||||||
* @return a builder for creating a result from a lesson
|
* @return a builder for creating a result from a lesson
|
||||||
* @param assignment
|
|
||||||
*/
|
*/
|
||||||
public static AttackResultBuilder success(AssignmentEndpoint assignment) {
|
public static AttackResultBuilder success(AssignmentEndpoint assignment) {
|
||||||
return new AttackResultBuilder()
|
return new AttackResultBuilder()
|
||||||
.lessonCompleted(true)
|
.lessonCompleted(true)
|
||||||
.assignmentCompleted(true)
|
|
||||||
.attemptWasMade()
|
.attemptWasMade()
|
||||||
.feedback("assignment.solved")
|
.feedback("assignment.solved")
|
||||||
.assignment(assignment);
|
.assignment(assignment);
|
||||||
@ -114,15 +92,14 @@ public class AttackResultBuilder {
|
|||||||
*
|
*
|
||||||
* <p>- Assignment is set to not solved - Feedback message is set to 'assignment.not.solved'
|
* <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
|
* <p>Of course, you can overwrite these values in a specific lesson
|
||||||
*
|
*
|
||||||
|
* @param assignment the assignment that was not solved
|
||||||
* @return a builder for creating a result from a lesson
|
* @return a builder for creating a result from a lesson
|
||||||
* @param assignment
|
|
||||||
*/
|
*/
|
||||||
public static AttackResultBuilder failed(AssignmentEndpoint assignment) {
|
public static AttackResultBuilder failed(AssignmentEndpoint assignment) {
|
||||||
return new AttackResultBuilder()
|
return new AttackResultBuilder()
|
||||||
.lessonCompleted(false)
|
.lessonCompleted(false)
|
||||||
.assignmentCompleted(true)
|
|
||||||
.attemptWasMade()
|
.attemptWasMade()
|
||||||
.feedback("assignment.not.solved")
|
.feedback("assignment.not.solved")
|
||||||
.assignment(assignment);
|
.assignment(assignment);
|
||||||
|
@ -13,9 +13,6 @@ import org.springframework.web.servlet.LocaleResolver;
|
|||||||
/**
|
/**
|
||||||
* Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the
|
* Wrapper around the LocaleResolver from Spring so we do not need to bother with passing the
|
||||||
* HttpRequest object when asking for a Locale.
|
* HttpRequest object when asking for a Locale.
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @date 2/7/17
|
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Language {
|
public class Language {
|
||||||
|
@ -11,9 +11,6 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Message resource bundle for plugins.
|
* Message resource bundle for plugins.
|
||||||
*
|
|
||||||
* @author nbaars
|
|
||||||
* @date 2/4/17
|
|
||||||
*/
|
*/
|
||||||
public class PluginMessages extends ReloadableResourceBundleMessageSource {
|
public class PluginMessages extends ReloadableResourceBundleMessageSource {
|
||||||
private static final String PROPERTIES_SUFFIX = ".properties";
|
private static final String PROPERTIES_SUFFIX = ".properties";
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: Copyright © 2024 WebGoat authors
|
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
*/
|
|
||||||
package org.owasp.webgoat.container.report;
|
|
||||||
|
|
||||||
record LessonStatistics(String name, boolean solved, int numberOfAttempts) {}
|
|
@ -54,12 +54,12 @@ public class ReportCardController {
|
|||||||
lessonStatistics);
|
lessonStatistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ReportCard(
|
public record ReportCard(
|
||||||
int totalNumberOfLessons,
|
int totalNumberOfLessons,
|
||||||
int totalNumberOfAssignments,
|
int totalNumberOfAssignments,
|
||||||
long numberOfAssignmentsSolved,
|
long numberOfAssignmentsSolved,
|
||||||
long numberOfLessonsSolved,
|
long numberOfLessonsSolved,
|
||||||
List<LessonStatistics> lessonStatistics) {}
|
List<LessonStatistics> lessonStatistics) {}
|
||||||
|
|
||||||
private record LessonStatistics(String name, boolean solved, int numberOfAttempts) {}
|
public record LessonStatistics(String name, boolean solved, int numberOfAttempts) {}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
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",
|
||||||
|
"http-basics.hints.http_basic_quiz.3"
|
||||||
|
})
|
||||||
public class HttpBasicsQuiz implements AssignmentEndpoint {
|
public class HttpBasicsQuiz implements AssignmentEndpoint {
|
||||||
|
|
||||||
@PostMapping("/HttpBasics/attack2")
|
@PostMapping("/HttpBasics/attack2")
|
||||||
|
@ -4,5 +4,5 @@ input and display it back to the user, illustrating the basics of handling an HT
|
|||||||
|
|
||||||
== Try It!
|
== Try It!
|
||||||
|
|
||||||
Enter your name in the input field below and press "Go!" to submit. The server will accept the request, reverse the input
|
Enter your name in the input field below and press "Go!" to submit. Use the Developer Tools to view the HTTP request and response.
|
||||||
and display it back to the user, illustrating the basics of handling an HTTP request.
|
Can you see the response with the reversed username?
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
== The Quiz
|
== The Quiz
|
||||||
|
|
||||||
What type of HTTP verb does WebGoat use when submitting the form in this lesson? A POST or a GET?
|
What type of HTTP verb does WebGoat use when submitting the form in this assignment? A POST or a GET?
|
||||||
|
And can you find the magic number?
|
||||||
|
@ -7,8 +7,7 @@ This lesson presents the basics for understanding the transfer of data between t
|
|||||||
== Goals
|
== Goals
|
||||||
|
|
||||||
The user should become familiar with the features of WebGoat by manipulating the above
|
The user should become familiar with the features of WebGoat by manipulating the above
|
||||||
buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You may also try using
|
buttons to view hints, show the HTTP request parameters, the HTTP request cookies, and the Java source code. You can use the default Developer Tools in your browser to view the HTTP request and response.
|
||||||
link:https://www.zaproxy.org/[OWASP Zed Attack Proxy] for the first time.
|
|
||||||
|
|
||||||
=== How HTTP works:
|
=== How HTTP works:
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
<div id="lessonContent">
|
<div id="lessonContent">
|
||||||
<form accept-charset="UNKNOWN" method="POST" name="form"
|
<form accept-charset="UNKNOWN" method="POST" name="form"
|
||||||
th:action="@{/#attack/307/100}">
|
th:action="@{/#attack/307/100}">
|
||||||
Enter Your Name: <input name="person" value="" type="TEXT"/><input
|
Enter your name: <input name="person" value="" type="TEXT"/><input
|
||||||
name="SUBMIT" value="Go!" type="SUBMIT"/>
|
name="SUBMIT" value="Go!" type="SUBMIT" class="spacing"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -71,7 +71,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>What is the magic number:</td>
|
<td>What is the magic number:</td>
|
||||||
<td><input name="magic_answer" value="" type="TEXT" /><input
|
<td><input name="magic_answer" value="" type="TEXT" /><input
|
||||||
name="SUBMIT" value="Go!" type="SUBMIT" /></td>
|
name="SUBMIT" value="Go!" type="SUBMIT" class="spacing" /></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -3,10 +3,10 @@ http-basics.Go!=Go!
|
|||||||
1.http-basics.title=HTTP Basics
|
1.http-basics.title=HTTP Basics
|
||||||
|
|
||||||
|
|
||||||
http-basics.hints.http_basics_lesson.1=Type in your name and press 'go'
|
http-basics.hints.http_basics_lesson.1=Type in your name and press 'Go'
|
||||||
http-basics.hints.http_basic_quiz.1=Turn on Show Parameters or other features
|
http-basics.hints.http_basic_quiz.1=You can use developer tools in your browser to inspect the HTML source
|
||||||
http-basics.hints.http_basic_quiz.2=Try to intercept the request with <a href='https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project' title='Link to ZAP'>OWASP ZAP</a>
|
http-basics.hints.http_basic_quiz.2=Search for the form tag in the HTML source
|
||||||
|
http-basics.hints.http_basic_quiz.3=You can submit the form and examine the request payload in the developer tools.
|
||||||
|
|
||||||
http-basics.empty=Try again, name cannot be empty.
|
http-basics.empty=Try again, name cannot be empty.
|
||||||
http-basics.reversed=The server has reversed your name: {0}
|
http-basics.reversed=The server has reversed your name: {0}
|
||||||
|
@ -1436,3 +1436,7 @@ pre .conum {
|
|||||||
b.conum * {
|
b.conum * {
|
||||||
color: inherit !important
|
color: inherit !important
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spacing {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user