added int test for IDOR and fixed green button issue (#801)

This commit is contained in:
René Zubcevic 2020-04-29 12:12:11 +02:00 committed by GitHub
parent 2398949396
commit 9dea696c4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 129 additions and 74 deletions

View File

@ -1081,6 +1081,17 @@ span.show-next-page, span.show-prev-page {
padding:5px; padding:5px;
} }
/* same look but not the behaviour */
.nonattack-container {
position: relative;
background-color: #f1f1f1;
border: 2px solid #a66;
border-radius: 12px;
padding: 7px;
margin-top:7px;
padding:5px;
}
/* ERROR NOTIFICATION */ /* ERROR NOTIFICATION */
#error-notification-container { #error-notification-container {
display: none; display: none;

View File

@ -166,4 +166,16 @@ public class GeneralLessonTest extends IntegrationTest {
} }
@Test
public void lessonTemplate() {
startLesson("LessonTemplate");
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("param1", "secr37Value");
params.put("param2", "Main");
checkAssignment(url("/lesson-template/sample-attack"), params, true);
checkResults("/lesson-template/");
}
} }

View File

@ -0,0 +1,98 @@
package org.owasp.webgoat;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import lombok.SneakyThrows;
public class IDORTest extends IntegrationTest {
@BeforeEach
@SneakyThrows
public void init() {
startLesson("IDOR");
}
@TestFactory
Iterable<DynamicTest> testIDORLesson() {
return Arrays.asList(
dynamicTest("login",()-> loginIDOR()),
dynamicTest("profile", () -> profile())
);
}
@AfterEach
public void shutdown() throws IOException {
checkResults("/IDOR");
}
private void loginIDOR() throws IOException {
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("username", "tom");
params.put("password", "cat");
checkAssignment(url("/WebGoat/IDOR/login"), params, true);
}
private void profile() {
Assert.assertThat(
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("/WebGoat/IDOR/profile"))
.then()
.statusCode(200)
.extract().path("userId"), CoreMatchers.is("2342384"));
Map<String, Object> params = new HashMap<>();
params.clear();
params.put("attributes", "userId,role");
checkAssignment(url("/WebGoat/IDOR/diff-attributes"), params, true);
params.clear();
params.put("url", "WebGoat/IDOR/profile/2342384");
checkAssignment(url("/WebGoat/IDOR/profile/alt-path"), params, true);
Assert.assertThat(
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.get(url("/WebGoat/IDOR/profile/2342388"))
.then()
.statusCode(200)
.extract().path("lessonCompleted"), CoreMatchers.is(true));
Assert.assertThat(
RestAssured.given()
.when()
.relaxedHTTPSValidation()
.cookie("JSESSIONID", getWebGoatCookie())
.contentType(ContentType.JSON) //part of the lesson
.body("{\"role\":\"1\", \"color\":\"red\", \"size\":\"large\", \"name\":\"Buffalo Bill\", \"userId\":\"2342388\"}")
.put(url("/WebGoat/IDOR/profile/2342388"))
.then()
.statusCode(200)
.extract().path("lessonCompleted"), CoreMatchers.is(true));
}
}

View File

@ -31,7 +31,7 @@ import org.springframework.web.bind.annotation.*;
@AssignmentHints({"idor.hints.idorDiffAttributes1", "idor.hints.idorDiffAttributes2", "idor.hints.idorDiffAttributes3"}) @AssignmentHints({"idor.hints.idorDiffAttributes1", "idor.hints.idorDiffAttributes2", "idor.hints.idorDiffAttributes3"})
public class IDORDiffAttributes extends AssignmentEndpoint { public class IDORDiffAttributes extends AssignmentEndpoint {
@PostMapping("IDOR/diff-attributes") @PostMapping("/IDOR/diff-attributes")
@ResponseBody @ResponseBody
public AttackResult completed(@RequestParam String attributes) { public AttackResult completed(@RequestParam String attributes) {
attributes = attributes.trim(); attributes = attributes.trim();

View File

@ -36,7 +36,7 @@ public class IDOREditOtherProfiile extends AssignmentEndpoint {
@Autowired @Autowired
private UserSessionData userSessionData; private UserSessionData userSessionData;
@PutMapping(path = "IDOR/profile/{userId}", consumes = "application/json") @PutMapping(path = "/IDOR/profile/{userId}", consumes = "application/json")
@ResponseBody @ResponseBody
public AttackResult completed(@PathVariable("userId") String userId, @RequestBody UserProfile userSubmittedProfile) { public AttackResult completed(@PathVariable("userId") String userId, @RequestBody UserProfile userSubmittedProfile) {

View File

@ -43,7 +43,7 @@ public class IDORViewOtherProfile extends AssignmentEndpoint {
@Autowired @Autowired
UserSessionData userSessionData; UserSessionData userSessionData;
@GetMapping(path = "IDOR/profile/{userId}", produces = {"application/json"}) @GetMapping(path = "/IDOR/profile/{userId}", produces = {"application/json"})
@ResponseBody @ResponseBody
public AttackResult completed(@PathVariable("userId") String userId, HttpServletResponse resp) { public AttackResult completed(@PathVariable("userId") String userId, HttpServletResponse resp) {
Map<String, Object> details = new HashMap<>(); Map<String, Object> details = new HashMap<>();

View File

@ -39,7 +39,7 @@ public class IDORViewOwnProfile {
@Autowired @Autowired
UserSessionData userSessionData; UserSessionData userSessionData;
@GetMapping(path = {"IDOR/own", "IDOR/profile"}, produces = {"application/json"}) @GetMapping(path = {"/IDOR/own", "/IDOR/profile"}, produces = {"application/json"})
@ResponseBody @ResponseBody
public Map<String, Object> invoke() { public Map<String, Object> invoke() {
Map<String,Object> details = new HashMap<>(); Map<String,Object> details = new HashMap<>();

View File

@ -37,7 +37,7 @@ public class IDORViewOwnProfileAltUrl extends AssignmentEndpoint {
@Autowired @Autowired
UserSessionData userSessionData; UserSessionData userSessionData;
@PostMapping("IDOR/profile/alt-path") @PostMapping("/IDOR/profile/alt-path")
@ResponseBody @ResponseBody
public AttackResult completed(@RequestParam String url) { public AttackResult completed(@RequestParam String url) {
try { try {

View File

@ -1,66 +0,0 @@
//package org.owasp.webgoat.plugin;
//
//import com.google.common.collect.Lists;
//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;
//import org.springframework.web.bind.annotation.PathVariable;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.ResponseBody;
//
//import javax.servlet.ServletException;
//import javax.servlet.http.HttpServletRequest;
//import javax.servlet.http.HttpServletResponse;
//import java.io.IOException;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//
///**
// * Created by jason on 1/5/17.
// */
//
//@AssignmentPath("/IDOR/viewprofile/{id}")
//@AssignmentHints({"idor.hints.otherProfile1","idor.hints.otherProfile2","idor.hints.otherProfile3"})
//public class ViewOtherUserProfile extends AssignmentEndpoint {
//
// private String color;
// private String size;
// private boolean isAdmin;
//
// @Autowired
// UserSessionData userSessionData;
//
// @RequestMapping(produces = {"application/json"})
// public @ResponseBody
// AttackResult completed(@PathVariable String userId, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// List json = Lists.newArrayList();
// // can be re-used
// Map<String, Object> errorMap = new HashMap();
// errorMap.put("error","not logged in, go back and log in first");
//
// if (userSessionData.getValue("idor-authenticated-as") == null) {
// json.add(errorMap);
// return trackProgress(failed().feedback("idor.view.other.profile.failure1").build());
// } else {
// if (userSessionData.getValue("idor-authenticated-as").equals("bill") || userSessionData.getValue("idor-authenticated-as").equals("tom")) {
// System.out.println("**** authenticated as " + userSessionData.getValue("idor-authenticated-as"));
// //logged in
// String authUserId = (String)userSessionData.getValue("idor-authenticated-user-id");
// //secure code would check to make sure authUserId matches userId or some similar access control
// // ... and in this endpoint, we won't bother with that
// UserProfile userProfile = new UserProfile(userId);
// return trackProgress(failed().feedback("idor.view.other.profile.failure2").build());
// }
// }
// // else
// return trackProgress(failed().build());
// }
//
//
//
//
//}

View File

@ -47,7 +47,7 @@
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files, <!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc --> which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:IDOR_viewDiffs.adoc"></div> <div class="adoc-content" th:replace="doc:IDOR_viewDiffs.adoc"></div>
<div class="attack-container"> <div class="nonattack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div> <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat --> <!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat --> <!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
@ -124,7 +124,7 @@
<!-- include content here, or can be placed in another location. Content will be presented via asciidocs files, <!-- include content here, or can be placed in another location. Content will be presented via asciidocs files,
which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc --> which you put in src/main/resources/plugin/lessonplans/{lang}/{fileName}.adoc -->
<div class="adoc-content" th:replace="doc:IDOR_viewOtherProfile.adoc"></div> <div class="adoc-content" th:replace="doc:IDOR_viewOtherProfile.adoc"></div>
<div class="attack-container"> <div class="nonattack-container">
<div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div> <div class="assignment-success"><i class="fa fa-2 fa-check hidden" aria-hidden="true"></i></div>
<!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat --> <!-- using attack-form class on your form, will allow your request to be ajaxified and stay within the display framework for webgoat -->
<!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat --> <!-- using attack-form class on your form will allow your request to be ajaxified and stay within the display framework for webgoat -->
@ -161,7 +161,7 @@
action="/WebGoat/IDOR/profile/{userId}"> action="/WebGoat/IDOR/profile/{userId}">
<script th:src="@{/lesson_js/idor.js}" /> <script th:src="@{/lesson_js/idor.js}" />
<input name="View Profile" value="View Profile" type="submit" /> <input name="Edit Profile" value="Edit Profile" type="submit" />
</form> </form>
<!-- do not remove the two following div's, this is where your feedback/output will land --> <!-- do not remove the two following div's, this is where your feedback/output will land -->