Adjust lesson template (#704)

* Remove method `getId()` from all lessons as it defaults to the class name

* remove clean up endpoint

* remove unused class `RequestParameter`

* remove unused class `PluginLoadingFailure`

* Move `CourseConfiguration` to lesson package

* Add more content around the lesson template lesson and make it visible as a lesson in WebGoat

* Remove explicit invocation `trackProgress()` inside WebGoat framework so assignments only need to return an `AttackResult`

* Put original solution back as well for SQL string injection

* review comments

* Add
This commit is contained in:
Nanne Baars
2019-11-17 13:39:56 +01:00
committed by René Zubcevic
parent f40b6ffd31
commit 5dd6b31905
139 changed files with 769 additions and 870 deletions

View File

@ -38,10 +38,4 @@ public class AuthBypass extends Lesson {
public String getTitle() {
return "auth-bypass.title";
}
@Override
public String getId() {
return "AuthBypass";
}
}

View File

@ -24,7 +24,6 @@ package org.owasp.webgoat.auth_bypass;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.owasp.webgoat.session.WebSession;
@ -61,22 +60,22 @@ public class VerifyAccount extends AssignmentEndpoint {
AccountVerificationHelper verificationHelper = new AccountVerificationHelper();
Map<String, String> submittedAnswers = parseSecQuestions(req);
if (verificationHelper.didUserLikelylCheat((HashMap) submittedAnswers)) {
return trackProgress(failed()
return failed(this)
.feedback("verify-account.cheated")
.output("Yes, you guessed correctly, but see the feedback message")
.build());
.build();
}
// else
if (verificationHelper.verifyAccount(Integer.valueOf(userId), (HashMap) submittedAnswers)) {
userSessionData.setValue("account-verified-id", userId);
return trackProgress(success()
return success(this)
.feedback("verify-account.success")
.build());
.build();
} else {
return trackProgress(failed()
return failed(this)
.feedback("verify-account.failed")
.build());
.build();
}
}

View File

@ -37,9 +37,4 @@ public class BypassRestrictions extends Lesson {
public String getTitle() {
return "bypass-restrictions.title";
}
@Override
public String getId() {
return "BypassRestrictions";
}
}

View File

@ -36,17 +36,17 @@ public class BypassRestrictionsFieldRestrictions extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String select, @RequestParam String radio, @RequestParam String checkbox, @RequestParam String shortInput) {
if (select.equals("option1") || select.equals("option2")) {
return trackProgress(failed().build());
return failed(this).build();
}
if (radio.equals("option1") || radio.equals("option2")) {
return trackProgress(failed().build());
return failed(this).build();
}
if (checkbox.equals("on") || checkbox.equals("off")) {
return trackProgress(failed().build());
return failed(this).build();
}
if (shortInput.length() <= 5) {
return trackProgress(failed().build());
return failed(this).build();
}
return trackProgress(success().build());
return success(this).build();
}
}

View File

@ -23,13 +23,9 @@
package org.owasp.webgoat.bypass_restrictions;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RestController
public class BypassRestrictionsFrontendValidation extends AssignmentEndpoint {
@ -44,29 +40,29 @@ public class BypassRestrictionsFrontendValidation extends AssignmentEndpoint {
final String regex6 = "^\\d{5}(-\\d{4})?$";
final String regex7 = "^[2-9]\\d{2}-?\\d{3}-?\\d{4}$";
if (error > 0) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field1.matches(regex1)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field2.matches(regex2)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field3.matches(regex3)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field4.matches(regex4)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field5.matches(regex5)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field6.matches(regex6)) {
return trackProgress(failed().build());
return failed(this).build();
}
if (field7.matches(regex7)) {
return trackProgress(failed().build());
return failed(this).build();
}
return trackProgress(success().build());
return success(this).build();
}
}

View File

@ -18,9 +18,4 @@ public class ChallengeIntro extends Lesson {
public String getTitle() {
return "challenge0.title";
}
@Override
public String getId() {
return "Challenge";
}
}

View File

@ -48,11 +48,11 @@ public class Assignment1 extends AssignmentEndpoint {
boolean ipAddressKnown = true;
boolean passwordCorrect = "admin".equals(username) && PASSWORD.equals(password);
if (passwordCorrect && ipAddressKnown) {
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(1)).build();
return success(this).feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(1)).build();
} else if (passwordCorrect) {
return failed().feedback("ip.address.unknown").build();
return failed(this).feedback("ip.address.unknown").build();
}
return failed().build();
return failed(this).build();
}
public static boolean containsHeader(HttpServletRequest request) {

View File

@ -20,9 +20,4 @@ public class Challenge1 extends Lesson {
public String getTitle() {
return "challenge1.title";
}
@Override
public String getId() {
return "Challenge1";
}
}

View File

@ -50,19 +50,19 @@ public class Assignment5 extends AssignmentEndpoint {
@ResponseBody
public AttackResult login(@RequestParam String username_login, @RequestParam String password_login) throws Exception {
if (!StringUtils.hasText(username_login) || !StringUtils.hasText(password_login)) {
return failed().feedback("required4").build();
return failed(this).feedback("required4").build();
}
if (!"Larry".equals(username_login)) {
return failed().feedback("user.not.larry").feedbackArgs(username_login).build();
return failed(this).feedback("user.not.larry").feedbackArgs(username_login).build();
}
try (var connection = dataSource.getConnection()) {
PreparedStatement statement = connection.prepareStatement("select password from challenge_users where userid = '" + username_login + "' and password = '" + password_login + "'");
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
return success().feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
return success(this).feedback("challenge.solved").feedbackArgs(Flag.FLAGS.get(5)).build();
} else {
return failed().feedback("challenge.close").build();
return failed(this).feedback("challenge.close").build();
}
}
}

View File

@ -42,9 +42,4 @@ public class Challenge5 extends Lesson {
public String getTitle() {
return "challenge5.title";
}
@Override
public String getId() {
return "Challenge5";
}
}

View File

@ -1,6 +1,5 @@
package org.owasp.webgoat.challenges.challenge7;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AttackResult;
@ -71,7 +70,7 @@ public class Assignment7 extends AssignmentEndpoint {
restTemplate.postForEntity(webWolfMailURL, mail, Object.class);
}
}
return success().feedback("email.send").feedbackArgs(email).build();
return success(this).feedback("email.send").feedbackArgs(email).build();
}
@GetMapping(value = "/challenge/7/.git", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)

View File

@ -20,9 +20,4 @@ public class Challenge7 extends Lesson {
public String getTitle() {
return "challenge7.title";
}
@Override
public String getId() {
return "Challenge7";
}
}

View File

@ -20,9 +20,4 @@ public class Challenge8 extends Lesson {
public String getTitle() {
return "challenge8.title";
}
@Override
public String getId() {
return "Challenge8";
}
}

View File

@ -35,16 +35,11 @@ public class ChromeDevTools extends Lesson {
@Override
public Category getDefaultCategory() {
return Category.GENERAL;
return Category.GENERAL;
}
@Override
public String getTitle() {
return "3.chrome-dev-tools.title";//3rd lesson in General
return "3.chrome-dev-tools.title";//3rd lesson in General
}
@Override
public String getId() {
return "ChromeDevTools";
}
}
}

View File

@ -23,13 +23,10 @@
package org.owasp.webgoat.chrome_dev_tools;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* This is just a class used to make the the HTTP request.
*
@ -46,9 +43,9 @@ public class NetworkDummy extends AssignmentEndpoint {
String answer = (String) userSessionData.getValue("randValue");
if (successMessage != null && successMessage.equals(answer)) {
return trackProgress(success().feedback("xss-dom-message-success").build());
return success(this).feedback("xss-dom-message-success").build();
} else {
return trackProgress(failed().feedback("xss-dom-message-failure").build());
return failed(this).feedback("xss-dom-message-failure").build();
}
}
}

View File

@ -24,13 +24,10 @@ package org.owasp.webgoat.chrome_dev_tools;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* Assignment where the user has to look through an HTTP Request
* using the Developer Tools and find a specific number.
@ -46,9 +43,9 @@ public class NetworkLesson extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String network_num, @RequestParam String number) {
if (network_num.equals(number)) {
return trackProgress(success().feedback("network.success").output("").build());
return success(this).feedback("network.success").output("").build();
} else {
return trackProgress(failed().feedback("network.failed").build());
return failed(this).feedback("network.failed").build();
}
}

View File

@ -20,9 +20,4 @@ public class CIA extends Lesson {
public String getTitle() {
return "4.cia.title";//4th lesson in general
}
@Override
public String getId() {
return "CIA";
}
}

View File

@ -29,9 +29,9 @@ public class CIAQuiz extends AssignmentEndpoint {
}
if (correctAnswers == solutions.length) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -45,9 +45,4 @@ public class ClientSideFiltering extends Lesson {
public String getTitle() {
return "client.side.filtering.title";
}
@Override
public String getId() {
return "ClientSideFiltering";
}
}

View File

@ -24,12 +24,9 @@ package org.owasp.webgoat.client_side_filtering;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@AssignmentHints({"ClientSideFilteringHint1", "ClientSideFilteringHint2", "ClientSideFilteringHint3", "ClientSideFilteringHint4"})
public class ClientSideFilteringAssignment extends AssignmentEndpoint {
@ -37,8 +34,8 @@ public class ClientSideFilteringAssignment extends AssignmentEndpoint {
@PostMapping("/clientSideFiltering/attack1")
@ResponseBody
public AttackResult completed(@RequestParam String answer) {
return trackProgress("450000".equals(answer)
? success().feedback("assignment.solved").build() :
failed().feedback("ClientSideFiltering.incorrect").build());
return "450000".equals(answer)
? success(this).feedback("assignment.solved").build() :
failed(this).feedback("ClientSideFiltering.incorrect").build();
}
}

View File

@ -24,12 +24,9 @@ package org.owasp.webgoat.client_side_filtering;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
/**
* @author nbaars
* @since 4/6/17.
@ -44,8 +41,8 @@ public class ClientSideFilteringFreeAssignment extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String checkoutCode) {
if (SUPER_COUPON_CODE.equals(checkoutCode)) {
return trackProgress(success().build());
return success(this).build();
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -37,9 +37,4 @@ public class CrossSiteScripting extends Lesson {
public String getTitle() {
return "xss.title";
}
@Override
public String getId() {
return "CrossSiteScripting";
}
}

View File

@ -38,9 +38,9 @@ public class CrossSiteScriptingLesson1 extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String answer_xss_1) {
if (answer_xss_1.toString().toLowerCase().equals("yes")) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().feedback("xss.lesson1.failure").build());
return failed(this).feedback("xss.lesson1.failure").build();
}
}
}

View File

@ -44,7 +44,7 @@ public class CrossSiteScriptingLesson3 extends AssignmentEndpoint {
public AttackResult completed(@RequestParam String editor) {
String unescapedString = org.jsoup.parser.Parser.unescapeEntities(editor, true);
try {
if (editor.isEmpty()) return trackProgress(failed().feedback("xss-mitigation-3-no-code").build());
if (editor.isEmpty()) return failed(this).feedback("xss-mitigation-3-no-code").build();
Document doc = Jsoup.parse(unescapedString);
String[] lines = unescapedString.split("<html>");
@ -68,12 +68,12 @@ public class CrossSiteScriptingLesson3 extends AssignmentEndpoint {
if (includeCorrect && firstNameCorrect && lastNameCorrect) {
System.out.println("true");
return trackProgress(success().feedback("xss-mitigation-3-success").build());
return success(this).feedback("xss-mitigation-3-success").build();
} else {
return trackProgress(failed().feedback("xss-mitigation-3-failure").build());
return failed(this).feedback("xss-mitigation-3-failure").build();
}
} catch (Exception e) {
return trackProgress(failed().output(e.getMessage()).build());
return failed(this).output(e.getMessage()).build();
}
}
}

View File

@ -52,10 +52,10 @@ public class CrossSiteScriptingLesson4 extends AssignmentEndpoint {
editor.contains("MyCommentDAO.addComment(threadID, userID") &&
editor.contains(".getCleanHTML());")) {
log.debug("true");
return trackProgress(success().feedback("xss-mitigation-4-success").build());
return success(this).feedback("xss-mitigation-4-success").build();
} else {
log.debug("false");
return trackProgress(failed().feedback("xss-mitigation-4-failed").build());
return failed(this).feedback("xss-mitigation-4-failed").build();
}
}
}

View File

@ -46,7 +46,7 @@ public class CrossSiteScriptingLesson5a extends AssignmentEndpoint {
@RequestParam String field2) {
if (field2.toLowerCase().matches("<script>.*(console\\.log\\(.*\\)|alert\\(.*\\))<\\/script>")) {
return trackProgress(failed().feedback("xss-reflected-5a-failed-wrong-field").build());
return failed(this).feedback("xss-reflected-5a-failed-wrong-field").build();
}
double totalSale = QTY1.intValue() * 69.99 + QTY2.intValue() * 27.99 + QTY3.intValue() * 1599.99 + QTY4.intValue() * 299.99;
@ -64,19 +64,19 @@ public class CrossSiteScriptingLesson5a extends AssignmentEndpoint {
}
if (field1.toLowerCase().matches("<script>.*(console\\.log\\(.*\\)|alert\\(.*\\))<\\/script>")) {
//return trackProgress()
//return )
userSessionData.setValue("xss-reflected-5a-complete", "true");
if (field1.toLowerCase().contains("console.log")) {
return trackProgress(success().feedback("xss-reflected-5a-success-console").output(cart.toString()).build());
return success(this).feedback("xss-reflected-5a-success-console").output(cart.toString()).build();
} else {
return trackProgress(success().feedback("xss-reflected-5a-success-alert").output(cart.toString()).build());
return success(this).feedback("xss-reflected-5a-success-alert").output(cart.toString()).build();
}
} else {
userSessionData.setValue("xss-reflected1-complete", "false");
return trackProgress(success()
return success(this)
.feedback("xss-reflected-5a-failure")
.output(cart.toString())
.build());
.build();
}
}
}

View File

@ -42,10 +42,10 @@ public class CrossSiteScriptingLesson6a extends AssignmentEndpoint {
public AttackResult completed(@RequestParam String DOMTestRoute) {
if (DOMTestRoute.matches("start\\.mvc#test(\\/|)")) {
//return trackProgress()
return trackProgress(success().feedback("xss-reflected-6a-success").build());
//return )
return success(this).feedback("xss-reflected-6a-success").build();
} else {
return trackProgress(failed().feedback("xss-reflected-6a-failure").build());
return failed(this).feedback("xss-reflected-6a-failure").build();
}
}

View File

@ -53,9 +53,9 @@ public class CrossSiteScriptingQuiz extends AssignmentEndpoint {
}
if (correctAnswers == solutions.length) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -42,9 +42,9 @@ public class DOMCrossSiteScripting extends AssignmentEndpoint {
userSessionData.setValue("randValue", String.valueOf(number.nextInt()));
if (param1 == 42 && param2 == 24 && request.getHeader("webgoat-requested-by").equals("dom-xss-vuln")) {
return trackProgress(success().output("phoneHome Response is " + userSessionData.getValue("randValue").toString()).build());
return success(this).output("phoneHome Response is " + userSessionData.getValue("randValue").toString()).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}
}

View File

@ -42,9 +42,9 @@ public class DOMCrossSiteScriptingVerifier extends AssignmentEndpoint {
String answer = (String) userSessionData.getValue("randValue");
if (successMessage.equals(answer)) {
return trackProgress(success().feedback("xss-dom-message-success").build());
return success(this).feedback("xss-dom-message-success").build();
} else {
return trackProgress(failed().feedback("xss-dom-message-failure").build());
return failed(this).feedback("xss-dom-message-failure").build();
}
}
}

View File

@ -35,9 +35,4 @@ public class CrossSiteScriptingMitigation extends Lesson {
public String getTitle() {
return "xss-mitigation.title";
}
@Override
public String getId() {
return "CrossSiteScriptingMitigation";
}
}

View File

@ -35,9 +35,4 @@ public class CrossSiteScriptingStored extends Lesson {
public String getTitle() {
return "xss-stored.title";
}
@Override
public String getId() {
return "CrossSiteScriptingStored";
}
}

View File

@ -43,9 +43,9 @@ public class StoredCrossSiteScriptingVerifier extends AssignmentEndpoint {
UserSessionData userSessionData = getUserSessionData();
if (successMessage.equals(userSessionData.getValue("randValue").toString())) {
return trackProgress(success().feedback("xss-stored-callback-success").build());
return success(this).feedback("xss-stored-callback-success").build();
} else {
return trackProgress(failed().feedback("xss-stored-callback-failure").build());
return failed(this).feedback("xss-stored-callback-failure").build();
}
}
}

View File

@ -88,9 +88,9 @@ public class StoredXssComments extends AssignmentEndpoint {
userComments.put(webSession.getUserName(), comments);
if (comment.getText().contains(phoneHomeString)) {
return (success().feedback("xss-stored-comment-success").build());
return (success(this).feedback("xss-stored-comment-success").build());
} else {
return (failed().feedback("xss-stored-comment-failure").build());
return (failed(this).feedback("xss-stored-comment-failure").build());
}
}

View File

@ -52,7 +52,6 @@ public class DOMCrossSiteScriptingTest extends AssignmentEndpointTest {
init(domXss);
this.mockMvc = standaloneSetup(domXss).build();
CrossSiteScripting xss = new CrossSiteScripting();
when(webSession.getCurrentLesson()).thenReturn(xss);
when(userSessionData.getValue("randValue")).thenReturn(randVal);
}

View File

@ -41,10 +41,4 @@ public class CSRF extends Lesson {
@Override
public String getTitle() { return "csrf.title"; }
@Override
public String getId() {
return "CSRF";
}
}

View File

@ -47,11 +47,12 @@ public class CSRFConfirmFlag1 extends AssignmentEndpoint {
public AttackResult completed(String confirmFlagVal) {
Object userSessionDataStr = userSessionData.getValue("csrf-get-success");
if (userSessionDataStr != null && confirmFlagVal.equals(userSessionDataStr.toString())) {
return trackProgress(
success().feedback("csrf-get-null-referer.success").output("Correct, the flag was " + userSessionData.getValue("csrf-get-success")).build()
);
return success(this)
.feedback("csrf-get-null-referer.success")
.output("Correct, the flag was " + userSessionData.getValue("csrf-get-success"))
.build();
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -24,11 +24,9 @@ package org.owasp.webgoat.csrf;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
import org.springframework.beans.factory.annotation.Autowired;
@ -66,25 +64,25 @@ public class CSRFFeedback extends AssignmentEndpoint {
objectMapper.enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS);
objectMapper.readValue(feedback.getBytes(), Map.class);
} catch (IOException e) {
return failed().feedback(ExceptionUtils.getStackTrace(e)).build();
return failed(this).feedback(ExceptionUtils.getStackTrace(e)).build();
}
boolean correctCSRF = requestContainsWebGoatCookie(request.getCookies()) && request.getContentType().contains(MediaType.TEXT_PLAIN_VALUE);
correctCSRF &= hostOrRefererDifferentHost(request);
if (correctCSRF) {
String flag = UUID.randomUUID().toString();
userSessionData.setValue("csrf-feedback", flag);
return success().feedback("csrf-feedback-success").feedbackArgs(flag).build();
return success(this).feedback("csrf-feedback-success").feedbackArgs(flag).build();
}
return failed().build();
return failed(this).build();
}
@PostMapping(path = "/csrf/feedback", produces = "application/json")
@ResponseBody
public AttackResult flag(@RequestParam("confirmFlagVal") String flag) {
if (flag.equals(userSessionData.getValue("csrf-feedback"))) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -51,9 +51,9 @@ public class CSRFLogin extends AssignmentEndpoint {
String userName = request.getUserPrincipal().getName();
if (userName.startsWith("csrf")) {
markAssignmentSolvedWithRealUser(userName.substring("csrf-".length()));
return trackProgress(success().feedback("csrf-login-success").build());
return success(this).feedback("csrf-login-success").build();
}
return trackProgress(failed().feedback("csrf-login-failed").feedbackArgs(userName).build());
return failed(this).feedback("csrf-login-failed").feedbackArgs(userName).build();
}
private void markAssignmentSolvedWithRealUser(String username) {

View File

@ -90,13 +90,13 @@ public class ForgedReviews extends AssignmentEndpoint {
userReviews.put(webSession.getUserName(), reviews);
//short-circuit
if (validateReq == null || !validateReq.equals(weakAntiCSRF)) {
return trackProgress(failed().feedback("csrf-you-forgot-something").build());
return failed(this).feedback("csrf-you-forgot-something").build();
}
//we have the spoofed files
if (referer != "NULL" && refererArr[2].equals(host)) {
return trackProgress(failed().feedback("csrf-same-host").build());
return failed(this).feedback("csrf-same-host").build();
} else {
return trackProgress(success().feedback("csrf-review.success").build()); //feedback("xss-stored-comment-failure")
return success(this).feedback("csrf-review.success").build(); //feedback("xss-stored-comment-failure")
}
}
}

View File

@ -44,9 +44,4 @@ public class HtmlTampering extends Lesson {
public String getTitle() {
return "html-tampering.title";
}
@Override
public String getId() {
return "HtmlTampering";
}
}

View File

@ -24,12 +24,9 @@ package org.owasp.webgoat.html_tampering;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@AssignmentHints({"hint1", "hint2", "hint3"})
public class HtmlTamperingTask extends AssignmentEndpoint {
@ -38,8 +35,8 @@ public class HtmlTamperingTask extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String QTY, @RequestParam String Total) {
if (Float.parseFloat(QTY) * 2999.99 > Float.parseFloat(Total) + 1) {
return trackProgress(success().feedback("html-tampering.tamper.success").build());
return success(this).feedback("html-tampering.tamper.success").build();
}
return trackProgress(failed().feedback("html-tampering.tamper.failure").build());
return failed(this).feedback("html-tampering.tamper.failure").build();
}
}

View File

@ -37,9 +37,4 @@ public class HttpBasics extends Lesson {
public String getTitle() {
return "1.http-basics.title";//first lesson in general
}
@Override
public String getId() {
return "HttpBasics";
}
}

View File

@ -24,12 +24,9 @@ package org.owasp.webgoat.http_basics;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
@RestController
@AssignmentHints({"http-basics.hints.http_basics_lesson.1"})
public class HttpBasicsLesson extends AssignmentEndpoint {
@ -38,12 +35,12 @@ public class HttpBasicsLesson extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String person) {
if (!person.equals("")) {
return trackProgress(success()
return success(this)
.feedback("http-basics.reversed")
.feedbackArgs(new StringBuffer(person).reverse().toString())
.build());
.build();
} else {
return trackProgress(failed().feedback("http-basics.empty").build());
return failed(this).feedback("http-basics.empty").build();
}
}
}

View File

@ -40,15 +40,15 @@ public class HttpBasicsQuiz extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String answer, @RequestParam String magic_answer, @RequestParam String magic_num, HttpServletRequest request) throws IOException {
if ("POST".equals(answer.toUpperCase()) && magic_answer.equals(magic_num)) {
return trackProgress(success().build());
return success(this).build();
} else {
if (!"POST".equals(answer.toUpperCase())) {
return trackProgress(failed().feedback("http-basics.incorrect").build());
return failed(this).feedback("http-basics.incorrect").build();
}
if (!magic_answer.equals(magic_num)) {
return trackProgress(failed().feedback("http-basics.magic").build());
return failed(this).feedback("http-basics.magic").build();
}
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -23,10 +23,8 @@
package org.owasp.webgoat.http_proxies;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@ -39,12 +37,12 @@ public class HttpBasicsInterceptRequest extends AssignmentEndpoint {
public AttackResult completed(@RequestHeader(value = "x-request-intercepted", required = false) Boolean headerValue,
@RequestParam(value = "changeMe", required = false) String paramValue, HttpServletRequest request) {
if (HttpMethod.POST.matches(request.getMethod())) {
return trackProgress(failed().feedback("http-proxies.intercept.failure").build());
return failed(this).feedback("http-proxies.intercept.failure").build();
}
if (headerValue != null && paramValue != null && headerValue && "Requests are tampered easily".equalsIgnoreCase(paramValue)) {
return trackProgress(success().feedback("http-proxies.intercept.success").build());
return success(this).feedback("http-proxies.intercept.success").build();
} else {
return trackProgress(failed().feedback("http-proxies.intercept.failure").build());
return failed(this).feedback("http-proxies.intercept.failure").build();
}
}
}

View File

@ -44,9 +44,4 @@ public class HttpProxies extends Lesson {
public String getTitle() {
return "2.http-proxies.title";//second lesson in GENERAL
}
@Override
public String getId() {
return "HttpProxies";
}
}

View File

@ -47,7 +47,6 @@ public class HttpBasicsInterceptRequestTest extends AssignmentEndpointTest {
HttpBasicsInterceptRequest httpBasicsInterceptRequest = new HttpBasicsInterceptRequest();
init(httpBasicsInterceptRequest);
this.mockMvc = standaloneSetup(httpBasicsInterceptRequest).build();
when(webSession.getCurrentLesson()).thenReturn(new HttpProxies());
}
@Test

View File

@ -45,10 +45,4 @@ public class IDOR extends Lesson {
public String getTitle() {
return "idor.title";
}
@Override
public String getId() {
return "IDOR";
}
}

View File

@ -24,13 +24,9 @@ package org.owasp.webgoat.idor;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RestController
@AssignmentHints({"idor.hints.idorDiffAttributes1", "idor.hints.idorDiffAttributes2", "idor.hints.idorDiffAttributes3"})
public class IDORDiffAttributes extends AssignmentEndpoint {
@ -41,13 +37,13 @@ public class IDORDiffAttributes extends AssignmentEndpoint {
attributes = attributes.trim();
String[] diffAttribs = attributes.split(",");
if (diffAttribs.length < 2) {
return trackProgress(failed().feedback("idor.diff.attributes.missing").build());
return failed(this).feedback("idor.diff.attributes.missing").build();
}
if (diffAttribs[0].toLowerCase().trim().equals("userid") && diffAttribs[1].toLowerCase().trim().equals("role")
|| diffAttribs[1].toLowerCase().trim().equals("userid") && diffAttribs[0].toLowerCase().trim().equals("role")) {
return trackProgress(success().feedback("idor.diff.success").build());
return success(this).feedback("idor.diff.success").build();
} else {
return trackProgress(failed().feedback("idor.diff.failure").build());
return failed(this).feedback("idor.diff.failure").build();
}
}
}

View File

@ -52,42 +52,42 @@ public class IDOREditOtherProfiile extends AssignmentEndpoint {
// we will persist in the session object for now in case we want to refer back or use it later
userSessionData.setValue("idor-updated-other-profile", currentUserProfile);
if (currentUserProfile.getRole() <= 1 && currentUserProfile.getColor().toLowerCase().equals("red")) {
return trackProgress(success()
return success(this)
.feedback("idor.edit.profile.success1")
.output(currentUserProfile.profileToMap().toString())
.build());
.build();
}
if (currentUserProfile.getRole() > 1 && currentUserProfile.getColor().toLowerCase().equals("red")) {
return trackProgress(success()
return success(this)
.feedback("idor.edit.profile.failure1")
.output(currentUserProfile.profileToMap().toString())
.build());
.build();
}
if (currentUserProfile.getRole() <= 1 && !currentUserProfile.getColor().toLowerCase().equals("red")) {
return trackProgress(success()
return success(this)
.feedback("idor.edit.profile.failure2")
.output(currentUserProfile.profileToMap().toString())
.build());
.build();
}
// else
return trackProgress(failed()
return failed(this)
.feedback("idor.edit.profile.failure3")
.output(currentUserProfile.profileToMap().toString())
.build());
.build();
} else if (userSubmittedProfile.getUserId().equals(authUserId)) {
return failed().feedback("idor.edit.profile.failure4").build();
return failed(this).feedback("idor.edit.profile.failure4").build();
}
if (currentUserProfile.getColor().equals("black") && currentUserProfile.getRole() <= 1) {
return trackProgress(success()
return success(this)
.feedback("idor.edit.profile.success2")
.output(userSessionData.getValue("idor-updated-own-profile").toString())
.build());
.build();
} else {
return trackProgress(failed().feedback("idor.edit.profile.failure3").build());
return failed(this).feedback("idor.edit.profile.failure3").build();
}
}

View File

@ -24,7 +24,6 @@ package org.owasp.webgoat.idor;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.session.UserSessionData;
@ -65,12 +64,12 @@ public class IDORLogin extends AssignmentEndpoint {
if ("tom".equals(username) && idorUserInfo.get("tom").get("password").equals(password)) {
userSessionData.setValue("idor-authenticated-as", username);
userSessionData.setValue("idor-authenticated-user-id", idorUserInfo.get(username).get("id"));
return trackProgress(success().feedback("idor.login.success").feedbackArgs(username).build());
return success(this).feedback("idor.login.success").feedbackArgs(username).build();
} else {
return trackProgress(failed().feedback("idor.login.failure").build());
return failed(this).feedback("idor.login.failure").build();
}
} else {
return trackProgress(failed().feedback("idor.login.failure").build());
return failed(this).feedback("idor.login.failure").build();
}
}
}

View File

@ -56,14 +56,14 @@ public class IDORViewOtherProfile extends AssignmentEndpoint {
UserProfile requestedProfile = new UserProfile(userId);
// secure code would ensure there was a horizontal access control check prior to dishing up the requested profile
if (requestedProfile.getUserId().equals("2342388")) {
return trackProgress(success().feedback("idor.view.profile.success").output(requestedProfile.profileToMap().toString()).build());
return success(this).feedback("idor.view.profile.success").output(requestedProfile.profileToMap().toString()).build();
} else {
return trackProgress(failed().feedback("idor.view.profile.close1").build());
return failed(this).feedback("idor.view.profile.close1").build();
}
} else {
return trackProgress(failed().feedback("idor.view.profile.close2").build());
return failed(this).feedback("idor.view.profile.close2").build();
}
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -48,16 +48,16 @@ public class IDORViewOwnProfileAltUrl extends AssignmentEndpoint {
String[] urlParts = url.split("/");
if (urlParts[0].equals("WebGoat") && urlParts[1].equals("IDOR") && urlParts[2].equals("profile") && urlParts[3].equals(authUserId)) {
UserProfile userProfile = new UserProfile(authUserId);
return trackProgress(success().feedback("idor.view.own.profile.success").output(userProfile.profileToMap().toString()).build());
return success(this).feedback("idor.view.own.profile.success").output(userProfile.profileToMap().toString()).build();
} else {
return trackProgress(failed().feedback("idor.view.own.profile.failure1").build());
return failed(this).feedback("idor.view.own.profile.failure1").build();
}
} else {
return trackProgress(failed().feedback("idor.view.own.profile.failure2").build());
return failed(this).feedback("idor.view.own.profile.failure2").build();
}
} catch (Exception ex) {
return failed().feedback("an error occurred with your request").build();
return failed(this).feedback("an error occurred with your request").build();
}
}
}

View File

@ -44,9 +44,4 @@ public class InsecureDeserialization extends Lesson {
public String getTitle() {
return "insecure-deserialization.title";
}
@Override
public String getId() {
return "InsecureDeserialization";
}
}

View File

@ -56,26 +56,26 @@ public class InsecureDeserializationTask extends AssignmentEndpoint {
Object o = ois.readObject();
if (!(o instanceof VulnerableTaskHolder)) {
if (o instanceof String) {
return trackProgress(failed().feedback("insecure-deserialization.stringobject").build());
return failed(this).feedback("insecure-deserialization.stringobject").build();
}
return trackProgress(failed().feedback("insecure-deserialization.wrongobject").build());
return failed(this).feedback("insecure-deserialization.wrongobject").build();
}
after = System.currentTimeMillis();
} catch (InvalidClassException e) {
return trackProgress(failed().feedback("insecure-deserialization.invalidversion").build());
return failed(this).feedback("insecure-deserialization.invalidversion").build();
} catch (IllegalArgumentException e) {
return trackProgress(failed().feedback("insecure-deserialization.expired").build());
return failed(this).feedback("insecure-deserialization.expired").build();
} catch (Exception e) {
return trackProgress(failed().feedback("insecure-deserialization.invalidversion").build());
return failed(this).feedback("insecure-deserialization.invalidversion").build();
}
delay = (int) (after - before);
if (delay > 7000) {
return trackProgress(failed().build());
return failed(this).build();
}
if (delay < 3000) {
return trackProgress(failed().build());
return failed(this).build();
}
return trackProgress(success().build());
return success(this).build();
}
}

View File

@ -28,7 +28,6 @@ public class DeserializeTest extends AssignmentEndpointTest {
InsecureDeserializationTask insecureTask = new InsecureDeserializationTask();
init(insecureTask);
this.mockMvc = standaloneSetup(insecureTask).build();
when(webSession.getCurrentLesson()).thenReturn(new InsecureDeserialization());
}
@Test

View File

@ -44,9 +44,4 @@ public class InsecureLogin extends Lesson {
public String getTitle() {
return "insecure-login.title";
}
@Override
public String getId() {
return "InsecureLogin";
}
}

View File

@ -23,13 +23,9 @@
package org.owasp.webgoat.insecure_login;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@RestController
public class InsecureLoginTask extends AssignmentEndpoint {
@ -37,8 +33,8 @@ public class InsecureLoginTask extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String username, @RequestParam String password) {
if (username.toString().equals("CaptainJack") && password.toString().equals("BlackPearl")) {
return trackProgress(success().build());
return success(this).build();
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -42,9 +42,4 @@ public class JWT extends Lesson {
public String getTitle() {
return "jwt.title";
}
@Override
public String getId() {
return "JWT";
}
}

View File

@ -82,7 +82,7 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
public @ResponseBody
AttackResult resetVotes(@RequestParam("token") String token) {
if (StringUtils.isEmpty(token)) {
return trackProgress(failed().feedback("jwt-invalid-token").build());
return failed(this).feedback("jwt-invalid-token").build();
} else {
try {
final String[] errorMessage = {null};
@ -102,20 +102,20 @@ public class JWTFinalEndpoint extends AssignmentEndpoint {
}
}).parseClaimsJws(token);
if (errorMessage[0] != null) {
return trackProgress(failed().output(errorMessage[0]).build());
return failed(this).output(errorMessage[0]).build();
}
Claims claims = (Claims) jwt.getBody();
String username = (String) claims.get("username");
if ("Jerry".equals(username)) {
return trackProgress(failed().feedback("jwt-final-jerry-account").build());
return failed(this).feedback("jwt-final-jerry-account").build();
}
if ("Tom".equals(username)) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().feedback("jwt-final-not-tom").build());
return failed(this).feedback("jwt-final-not-tom").build();
}
} catch (JwtException e) {
return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build());
return failed(this).feedback("jwt-invalid-token").output(e.toString()).build();
}
}
}

View File

@ -26,7 +26,6 @@ import io.jsonwebtoken.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
@ -92,13 +91,13 @@ public class JWTRefreshEndpoint extends AssignmentEndpoint {
Claims claims = (Claims) jwt.getBody();
String user = (String) claims.get("user");
if ("Tom".equals(user)) {
return ok(trackProgress(success().build()));
return ok(success(this).build());
}
return ok(trackProgress(failed().feedback("jwt-refresh-not-tom").feedbackArgs(user).build()));
return ok(failed(this).feedback("jwt-refresh-not-tom").feedbackArgs(user).build());
} catch (ExpiredJwtException e) {
return ok(trackProgress(failed().output(e.getMessage()).build()));
return ok(failed(this).output(e.getMessage()).build());
} catch (JwtException e) {
return ok(trackProgress(failed().feedback("jwt-invalid-token").build()));
return ok(failed(this).feedback("jwt-invalid-token").build());
}
}

View File

@ -74,19 +74,19 @@ public class JWTSecretKeyEndpoint extends AssignmentEndpoint {
Jwt jwt = Jwts.parser().setSigningKey(JWT_SECRET).parse(token);
Claims claims = (Claims) jwt.getBody();
if (!claims.keySet().containsAll(expectedClaims)) {
return trackProgress(failed().feedback("jwt-secret-claims-missing").build());
return failed(this).feedback("jwt-secret-claims-missing").build();
} else {
String user = (String) claims.get("username");
if (WEBGOAT_USER.equalsIgnoreCase(user)) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().feedback("jwt-secret-incorrect-user").feedbackArgs(user).build());
return failed(this).feedback("jwt-secret-incorrect-user").feedbackArgs(user).build();
}
}
} catch (Exception e) {
e.printStackTrace();
return trackProgress(failed().feedback("jwt-invalid-token").output(e.getMessage()).build());
return failed(this).feedback("jwt-invalid-token").output(e.getMessage()).build();
}
}
}

View File

@ -157,20 +157,20 @@ public class JWTVotesEndpoint extends AssignmentEndpoint {
@ResponseBody
public AttackResult resetVotes(@CookieValue(value = "access_token", required = false) String accessToken) {
if (StringUtils.isEmpty(accessToken)) {
return trackProgress(failed().feedback("jwt-invalid-token").build());
return failed(this).feedback("jwt-invalid-token").build();
} else {
try {
Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parse(accessToken);
Claims claims = (Claims) jwt.getBody();
boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
if (!isAdmin) {
return trackProgress(failed().feedback("jwt-only-admin").build());
return failed(this).feedback("jwt-only-admin").build();
} else {
votes.values().forEach(vote -> vote.reset());
return trackProgress(success().build());
return success(this).build();
}
} catch (JwtException e) {
return trackProgress(failed().feedback("jwt-invalid-token").output(e.toString()).build());
return failed(this).feedback("jwt-invalid-token").output(e.toString()).build();
}
}
}

View File

@ -38,10 +38,4 @@ public class MissingFunctionAC extends Lesson {
public String getTitle() {
return "missing-function-access-control.title";
}
@Override
public String getId() {
return "MissingFunctionAC";
}
}

View File

@ -47,22 +47,22 @@ public class MissingFunctionACHiddenMenus extends AssignmentEndpoint {
public AttackResult completed(String hiddenMenu1, String hiddenMenu2) {
//overly simple example for success. See other existing lesssons for ways to detect 'success' or 'failure'
if (hiddenMenu1.equals("Users") && hiddenMenu2.equals("Config")) {
return trackProgress(success()
return success(this)
.output("")
.feedback("access-control.hidden-menus.success")
.build());
.build();
}
if (hiddenMenu1.equals("Config") && hiddenMenu2.equals("Users")) {
return trackProgress(failed()
return failed(this)
.output("")
.feedback("access-control.hidden-menus.close")
.build());
.build();
}
return trackProgress(failed()
return failed(this)
.feedback("access-control.hidden-menus.failure")
.output("")
.build());
.build();
}
}

View File

@ -24,7 +24,6 @@ package org.owasp.webgoat.missing_ac;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.owasp.webgoat.users.UserService;
import org.owasp.webgoat.users.WebGoatUser;
@ -49,9 +48,9 @@ public class MissingFunctionACYourHash extends AssignmentEndpoint {
WebGoatUser user = userService.loadUserByUsername(currentUser);
DisplayUser displayUser = new DisplayUser(user);
if (userHash.equals(displayUser.getUserHash())) {
return trackProgress(success().feedback("access-control.hash.success").build());
return success(this).feedback("access-control.hash.success").build();
} else {
return trackProgress(failed().feedback("access-control.hash.close").build());
return failed(this).feedback("access-control.hash.close").build();
}
}
}

View File

@ -44,7 +44,6 @@ public class MissingFunctionACHiddenMenusTest extends AssignmentEndpointTest {
public void setup() {
MissingFunctionACHiddenMenus hiddenMenus = new MissingFunctionACHiddenMenus();
init(hiddenMenus);
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
this.mockMvc = standaloneSetup(hiddenMenus).build();
}

View File

@ -57,7 +57,6 @@ public class MissingFunctionYourHashTest extends AssignmentEndpointTest {
this.mockDisplayUser = new DisplayUser(new WebGoatUser("user", "userPass"));
ReflectionTestUtils.setField(yourHashTest, "userService", userService);
when(userService.loadUserByUsername(any())).thenReturn(new WebGoatUser("user", "userPass"));
when(webSession.getCurrentLesson()).thenReturn(new MissingFunctionAC());
}
@Test

View File

@ -37,9 +37,4 @@ public class PasswordReset extends Lesson {
public String getTitle() {
return "password-reset.title";
}
@Override
public String getId() {
return "PasswordReset";
}
}

View File

@ -57,15 +57,15 @@ public class QuestionsAssignment extends AssignmentEndpoint {
String username = (String) json.getOrDefault("username", "");
if ("webgoat".equalsIgnoreCase(username.toLowerCase())) {
return trackProgress(failed().feedback("password-questions-wrong-user").build());
return failed(this).feedback("password-questions-wrong-user").build();
}
String validAnswer = COLORS.get(username.toLowerCase());
if (validAnswer == null) {
return trackProgress(failed().feedback("password-questions-unknown-user").feedbackArgs(username).build());
return failed(this).feedback("password-questions-unknown-user").feedbackArgs(username).build();
} else if (validAnswer.equals(securityQuestion)) {
return trackProgress(success().build());
return success(this).build();
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -67,12 +67,12 @@ public class ResetLinkAssignment extends AssignmentEndpoint {
if (TOM_EMAIL.equals(email)) {
String passwordTom = usersToTomPassword.getOrDefault(getWebSession().getUserName(), PASSWORD_TOM_9);
if (passwordTom.equals(PASSWORD_TOM_9)) {
return trackProgress(failed().feedback("login_failed").build());
return failed(this).feedback("login_failed").build();
} else if (passwordTom.equals(password)) {
return trackProgress(success().build());
return success(this).build();
}
}
return trackProgress(failed().feedback("login_failed.tom").build());
return failed(this).feedback("login_failed.tom").build();
}
@GetMapping("/PasswordReset/reset/reset-password/{link}")

View File

@ -68,11 +68,11 @@ public class ResetLinkAssignmentForgotPassword extends AssignmentEndpoint {
try {
sendMailToUser(email, host, resetLink);
} catch (Exception e) {
return failed().output("E-mail can't be send. please try again.").build();
return failed(this).output("E-mail can't be send. please try again.").build();
}
}
}
return success().feedback("email.send").feedbackArgs(email).build();
return success(this).feedback("email.send").feedbackArgs(email).build();
}
private void sendMailToUser(String email, String host, String resetLink) {

View File

@ -71,10 +71,10 @@ public class SecurityQuestionAssignment extends AssignmentEndpoint {
if (answer.isPresent()) {
triedQuestions.incr(question);
if (triedQuestions.isComplete()) {
return trackProgress(success().output("<b>" + answer + "</b>").build());
return success(this).output("<b>" + answer + "</b>").build();
}
}
return informationMessage()
return informationMessage(this)
.feedback("password-questions-one-successful")
.output(answer.orElse("Unknown question, please try again..."))
.build();

View File

@ -60,9 +60,9 @@ public class SimpleMailAssignment extends AssignmentEndpoint {
String username = extractUsername(emailAddress);
if (username.equals(getWebSession().getUserName()) && StringUtils.reverse(username).equals(password)) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().feedbackArgs("password-reset-simple.password_incorrect").build());
return failed(this).feedbackArgs("password-reset-simple.password_incorrect").build();
}
}
@ -90,11 +90,11 @@ public class SimpleMailAssignment extends AssignmentEndpoint {
try {
restTemplate.postForEntity(webWolfURL, mailEvent, Object.class);
} catch (RestClientException e) {
return informationMessage().feedback("password-reset-simple.email_failed").output(e.getMessage()).build();
return informationMessage(this).feedback("password-reset-simple.email_failed").output(e.getMessage()).build();
}
return informationMessage().feedback("password-reset-simple.email_send").feedbackArgs(email).build();
return informationMessage(this).feedback("password-reset-simple.email_send").feedbackArgs(email).build();
} else {
return informationMessage().feedback("password-reset-simple.email_mismatch").feedbackArgs(username).build();
return informationMessage(this).feedback("password-reset-simple.email_mismatch").feedbackArgs(username).build();
}
}
}

View File

@ -38,8 +38,7 @@
<module>password-reset</module>
<module>ssrf</module>
<module>secure-passwords</module>
<!-- uncomment below to include lesson template in build, also uncomment the dependency in webgoat-server/pom.xml to have it run in the project fully -->
<!--<module>webgoat-lesson-template</module>-->
<module>webgoat-lesson-template</module>
</modules>
<dependencies>

View File

@ -42,9 +42,4 @@ public class SecurePasswords extends Lesson {
public String getTitle() {
return "secure-passwords.title";
}
@Override
public String getId() {
return "SecurePasswords";
}
}

View File

@ -69,9 +69,9 @@ public class SecurePasswordsAssignment extends AssignmentEndpoint {
output.append("<b>Estimated cracking time in seconds: </b>" + calculateTime((long) strength.getCrackTimeSeconds().getOnlineNoThrottling10perSecond()));
if (strength.getScore() >= 4)
return trackProgress(success().feedback("securepassword-success").output(output.toString()).build());
return success(this).feedback("securepassword-success").output(output.toString()).build();
else
return trackProgress(failed().feedback("securepassword-failed").output(output.toString()).build());
return failed(this).feedback("securepassword-failed").output(output.toString()).build();
}
public static String calculateTime(long seconds) {

View File

@ -37,9 +37,4 @@ public class SqlInjectionAdvanced extends Lesson {
public String getTitle() {
return "2.sql.advanced.title";
}
@Override
public String getId() {
return "SqlInjectionAdvanced";
}
}

View File

@ -66,9 +66,9 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
if (resultSet.next()) {
if (username_reg.contains("tom'")) {
attackResult = trackProgress(success().feedback("user.exists").build());
attackResult = success(this).feedback("user.exists").build();
} else {
attackResult = failed().feedback("user.exists").feedbackArgs(username_reg).build();
attackResult = failed(this).feedback("user.exists").feedbackArgs(username_reg).build();
}
} else {
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO sql_challenge_users VALUES (?, ?, ?)");
@ -76,10 +76,10 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
preparedStatement.setString(2, email_reg);
preparedStatement.setString(3, password_reg);
preparedStatement.execute();
attackResult = success().feedback("user.created").feedbackArgs(username_reg).build();
attackResult = success(this).feedback("user.created").feedbackArgs(username_reg).build();
}
} catch (SQLException e) {
attackResult = failed().output("Something went wrong").build();
attackResult = failed(this).output("Something went wrong").build();
}
}
return attackResult;
@ -87,10 +87,10 @@ public class SqlInjectionChallenge extends AssignmentEndpoint {
private AttackResult checkArguments(String username_reg, String email_reg, String password_reg) {
if (StringUtils.isEmpty(username_reg) || StringUtils.isEmpty(email_reg) || StringUtils.isEmpty(password_reg)) {
return failed().feedback("input.invalid").build();
return failed(this).feedback("input.invalid").build();
}
if (username_reg.length() > 250 || email_reg.length() > 30 || password_reg.length() > 30) {
return failed().feedback("input.invalid").build();
return failed(this).feedback("input.invalid").build();
}
return null;
}

View File

@ -54,10 +54,10 @@ public class SqlInjectionChallengeLogin extends AssignmentEndpoint {
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
return ("tom".equals(username_login)) ? trackProgress(success().build())
: success().feedback("ResultsButNotTom").build();
return ("tom".equals(username_login)) ? success(this).build()
: success(this).feedback("ResultsButNotTom").build();
} else {
return failed().feedback("NoResultsMatched").build();
return failed(this).feedback("NoResultsMatched").build();
}
}
}

View File

@ -81,19 +81,19 @@ public class SqlInjectionLesson6a extends AssignmentEndpoint {
if (output.toString().contains("dave") && output.toString().contains("passW0rD")) {
output.append(appendingWhenSucceded);
return trackProgress(success().feedback("sql-injection.advanced.6a.success").feedbackArgs(output.toString()).output(" Your query was: " + query).build());
return success(this).feedback("sql-injection.advanced.6a.success").feedbackArgs(output.toString()).output(" Your query was: " + query).build();
} else {
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + query).build());
return failed(this).output(output.toString() + "<br> Your query was: " + query).build();
}
} else {
return trackProgress(failed().feedback("sql-injection.advanced.6a.no.results").output(" Your query was: " + query).build());
return failed(this).feedback("sql-injection.advanced.6a.no.results").output(" Your query was: " + query).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + query).build());
return failed(this).output(sqle.getMessage() + "<br> Your query was: " + query).build();
}
} catch (Exception e) {
e.printStackTrace();
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build();
}
}
}

View File

@ -51,9 +51,9 @@ public class SqlInjectionLesson6b extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String userid_6b) throws IOException {
if (userid_6b.equals(getPassword())) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -59,9 +59,9 @@ public class SqlInjectionQuiz extends AssignmentEndpoint {
}
if (correctAnswers == solutions.length) {
return trackProgress(success().build());
return success(this).build();
} else {
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -37,9 +37,4 @@ public class SqlInjection extends Lesson {
public String getTitle() {
return "1.sql.injection.title";
}
@Override
public String getId() {
return "SqlInjection";
}
}

View File

@ -65,24 +65,24 @@ public class SqlInjectionLesson10 extends AssignmentEndpoint {
if (results.getStatement() != null) {
results.first();
output.append(SqlInjectionLesson8.generateTable(results));
return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build());
return failed(this).feedback("sql-injection.10.entries").output(output.toString()).build();
} else {
if (tableExists(connection)) {
return trackProgress(failed().feedback("sql-injection.10.entries").output(output.toString()).build());
return failed(this).feedback("sql-injection.10.entries").output(output.toString()).build();
} else {
return trackProgress(success().feedback("sql-injection.10.success").build());
return success(this).feedback("sql-injection.10.success").build();
}
}
} catch (SQLException e) {
if (tableExists(connection)) {
return trackProgress(failed().feedback("sql-injection.error").output("<span class='feedback-negative'>" + e.getMessage() + "</span><br>" + output.toString()).build());
return failed(this).feedback("sql-injection.error").output("<span class='feedback-negative'>" + e.getMessage() + "</span><br>" + output.toString()).build();
} else {
return trackProgress(success().feedback("sql-injection.10.success").build());
return success(this).feedback("sql-injection.10.success").build();
}
}
} catch (Exception e) {
return trackProgress(failed().output("<span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).output("<span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
}

View File

@ -67,12 +67,12 @@ public class SqlInjectionLesson2 extends AssignmentEndpoint {
if (results.getString("department").equals("Marketing")) {
output.append("<span class='feedback-positive'>" + query + "</span>");
output.append(SqlInjectionLesson8.generateTable(results));
return trackProgress(success().feedback("sql-injection.2.success").output(output.toString()).build());
return success(this).feedback("sql-injection.2.success").output(output.toString()).build();
} else {
return trackProgress(failed().feedback("sql-injection.2.failed").output(output.toString()).build());
return failed(this).feedback("sql-injection.2.failed").output(output.toString()).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().feedback("sql-injection.2.failed").output(sqle.getMessage()).build());
return failed(this).feedback("sql-injection.2.failed").output(sqle.getMessage()).build();
}
}
}

View File

@ -70,16 +70,16 @@ public class SqlInjectionLesson3 extends AssignmentEndpoint {
if (results.getString("department").equals("Sales")) {
output.append("<span class='feedback-positive'>" + query + "</span>");
output.append(SqlInjectionLesson8.generateTable(results));
return trackProgress(success().output(output.toString()).build());
return success(this).output(output.toString()).build();
} else {
return trackProgress(failed().output(output.toString()).build());
return failed(this).output(output.toString()).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage()).build());
return failed(this).output(sqle.getMessage()).build();
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage()).build();
}
}
}

View File

@ -63,15 +63,15 @@ public class SqlInjectionLesson4 extends AssignmentEndpoint {
// user completes lesson if column phone exists
if (results.first()) {
output.append("<span class='feedback-positive'>" + query + "</span>");
return trackProgress(success().output(output.toString()).build());
return success(this).output(output.toString()).build();
} else {
return trackProgress(failed().output(output.toString()).build());
return failed(this).output(output.toString()).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage()).build());
return failed(this).output(sqle.getMessage()).build();
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage()).build();
}
}
}

View File

@ -27,7 +27,6 @@ import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@ -50,12 +49,12 @@ public class SqlInjectionLesson5 extends AssignmentEndpoint {
// user completes lesson if the query is correct
if (query.matches(regex)) {
output.append("<span class='feedback-positive'>" + query + "</span>");
return trackProgress(success().output(output.toString()).build());
return success(this).output(output.toString()).build();
} else {
return trackProgress(failed().output(output.toString()).build());
return failed(this).output(output.toString()).build();
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage()).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage()).build();
}
}
}

View File

@ -70,18 +70,18 @@ public class SqlInjectionLesson5a extends AssignmentEndpoint {
// If they get back more than one user they succeeded
if (results.getRow() >= 6) {
return trackProgress(success().feedback("sql-injection.5a.success").output("Your query was: " + query + EXPLANATION).feedbackArgs(output.toString()).build());
return success(this).feedback("sql-injection.5a.success").output("Your query was: " + query + EXPLANATION).feedbackArgs(output.toString()).build();
} else {
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + query).build());
return failed(this).output(output.toString() + "<br> Your query was: " + query).build();
}
} else {
return trackProgress(failed().feedback("sql-injection.5a.no.results").output("Your query was: " + query).build());
return failed(this).feedback("sql-injection.5a.no.results").output("Your query was: " + query).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + query).build());
return failed(this).output(sqle.getMessage() + "<br> Your query was: " + query).build();
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + query).build();
}
}

View File

@ -61,8 +61,8 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint {
try {
count = Integer.parseInt(login_count);
} catch (Exception e) {
return trackProgress(failed().output("Could not parse: " + login_count + " to a number"
+ "<br> Your query was: " + queryString.replace("?", login_count)).build());
return failed(this).output("Could not parse: " + login_count + " to a number"
+ "<br> Your query was: " + queryString.replace("?", login_count)).build();
}
query.setInt(1, count);
@ -79,20 +79,20 @@ public class SqlInjectionLesson5b extends AssignmentEndpoint {
// If they get back more than one user they succeeded
if (results.getRow() >= 6) {
return trackProgress(success().feedback("sql-injection.5b.success").output("Your query was: " + queryString.replace("?", login_count)).feedbackArgs(output.toString()).build());
return success(this).feedback("sql-injection.5b.success").output("Your query was: " + queryString.replace("?", login_count)).feedbackArgs(output.toString()).build();
} else {
return trackProgress(failed().output(output.toString() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
return failed(this).output(output.toString() + "<br> Your query was: " + queryString.replace("?", login_count)).build();
}
} else {
return trackProgress(failed().feedback("sql-injection.5b.no.results").output("Your query was: " + queryString.replace("?", login_count)).build());
return failed(this).feedback("sql-injection.5b.no.results").output("Your query was: " + queryString.replace("?", login_count)).build();
}
} catch (SQLException sqle) {
return trackProgress(failed().output(sqle.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
return failed(this).output(sqle.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build();
}
} catch (Exception e) {
return trackProgress(failed().output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build());
return failed(this).output(this.getClass().getName() + " : " + e.getMessage() + "<br> Your query was: " + queryString.replace("?", login_count)).build();
}
}
}

View File

@ -71,25 +71,25 @@ public class SqlInjectionLesson8 extends AssignmentEndpoint {
if (results.getRow() > 1) {
// more than one record, the user succeeded
return trackProgress(success().feedback("sql-injection.8.success").output(output.toString()).build());
return success(this).feedback("sql-injection.8.success").output(output.toString()).build();
} else {
// only one record
return trackProgress(failed().feedback("sql-injection.8.one").output(output.toString()).build());
return failed(this).feedback("sql-injection.8.one").output(output.toString()).build();
}
} else {
// no results
return trackProgress(failed().feedback("sql-injection.8.no.results").build());
return failed(this).feedback("sql-injection.8.no.results").build();
}
} else {
return trackProgress(failed().feedback("sql-injection.error").build());
return failed(this).feedback("sql-injection.error").build();
}
} catch (SQLException e) {
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
} catch (Exception e) {
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
}

View File

@ -37,8 +37,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import static java.sql.ResultSet.CONCUR_READ_ONLY;
import static org.hsqldb.jdbc.JDBCResultSet.*;
import static org.hsqldb.jdbc.JDBCResultSet.CONCUR_UPDATABLE;
import static org.hsqldb.jdbc.JDBCResultSet.TYPE_SCROLL_SENSITIVE;
@RestController
@AssignmentHints(value = {"SqlStringInjectionHint.9.1", "SqlStringInjectionHint.9.2", "SqlStringInjectionHint.9.3", "SqlStringInjectionHint.9.4", "SqlStringInjectionHint.9.5"})
@ -70,19 +70,19 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
output.append(SqlInjectionLesson8.generateTable(results));
} else {
// no results
return trackProgress(failed().feedback("sql-injection.8.no.results").build());
return failed(this).feedback("sql-injection.8.no.results").build();
}
}
} catch (SQLException e) {
System.err.println(e.getMessage());
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
return checkSalaryRanking(connection, output);
} catch (Exception e) {
System.err.println(e.getMessage());
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
}
@ -97,13 +97,13 @@ public class SqlInjectionLesson9 extends AssignmentEndpoint {
// user completes lesson if John Smith is the first in the list
if ((results.getString(2).equals("John")) && (results.getString(3).equals("Smith"))) {
output.append(SqlInjectionLesson8.generateTable(results));
return trackProgress(success().feedback("sql-injection.9.success").output(output.toString()).build());
return success(this).feedback("sql-injection.9.success").output(output.toString()).build();
} else {
return trackProgress(failed().feedback("sql-injection.9.one").output(output.toString()).build());
return failed(this).feedback("sql-injection.9.one").output(output.toString()).build();
}
}
} catch (SQLException e) {
return trackProgress(failed().feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build());
return failed(this).feedback("sql-injection.error").output("<br><span class='feedback-negative'>" + e.getMessage() + "</span>").build();
}
}

View File

@ -48,13 +48,13 @@ public class SqlInjectionLesson10a extends AssignmentEndpoint {
if (input.toLowerCase().contains(this.results[position].toLowerCase())) {
completed = true;
} else {
return trackProgress(failed().build());
return failed(this).build();
}
position++;
}
if (completed) {
return trackProgress(success().build());
return success(this).build();
}
return trackProgress(failed().build());
return failed(this).build();
}
}

View File

@ -24,11 +24,9 @@ package org.owasp.webgoat.sql_injection.mitigation;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.tools.*;
import java.io.IOException;
import java.net.URI;
@ -45,7 +43,7 @@ public class SqlInjectionLesson10b extends AssignmentEndpoint {
@ResponseBody
public AttackResult completed(@RequestParam String editor) {
try {
if (editor.isEmpty()) return trackProgress(failed().feedback("sql-injection.10b.no-code").build());
if (editor.isEmpty()) return failed(this).feedback("sql-injection.10b.no-code").build();
editor = editor.replaceAll("\\<.*?>", "");
@ -69,18 +67,18 @@ public class SqlInjectionLesson10b extends AssignmentEndpoint {
List<Diagnostic> hasCompiled = this.compileFromString(editor);
if (hasImportant && hasCompiled.size() < 1) {
return trackProgress(success().feedback("sql-injection.10b.success").build());
return success(this).feedback("sql-injection.10b.success").build();
} else if (hasCompiled.size() > 0) {
String errors = "";
for (Diagnostic d : hasCompiled) {
errors += d.getMessage(null) + "<br>";
}
return trackProgress(failed().feedback("sql-injection.10b.compiler-errors").output(errors).build());
return failed(this).feedback("sql-injection.10b.compiler-errors").output(errors).build();
} else {
return trackProgress(failed().feedback("sql-injection.10b.failed").build());
return failed(this).feedback("sql-injection.10b.failed").build();
}
} catch (Exception e) {
return trackProgress(failed().output(e.getMessage()).build());
return failed(this).output(e.getMessage()).build();
}
}

View File

@ -22,7 +22,6 @@
package org.owasp.webgoat.sql_injection.mitigation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentHints;
@ -58,12 +57,12 @@ public class SqlInjectionLesson12a extends AssignmentEndpoint {
preparedStatement.setString(2, "webgoat-prd");
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return trackProgress(success().build());
return success(this).build();
}
return trackProgress(failed().build());
return failed(this).build();
} catch (SQLException e) {
log.error("Failed", e);
return trackProgress(failed().build());
return (failed(this).build());
}
}
}

View File

@ -37,9 +37,4 @@ public class SqlInjectionMitigations extends Lesson {
public String getTitle() {
return "3.sql.mitigation.title";
}
@Override
public String getId() {
return "SqlInjectionMitigations";
}
}

View File

@ -157,6 +157,7 @@
<option>'Smith</option>
<option>'</option>
<option>'Smith'</option>
<option>Smith'</option>
</select></td>
<td>
<select name="operator">

View File

@ -44,9 +44,4 @@ public class SSRF extends Lesson {
public String getTitle() {
return "ssrf.title";
}
@Override
public String getId() {
return "SSRF";
}
}

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