Add path traversal lesson

This commit is contained in:
Nanne Baars
2020-03-03 21:37:24 +01:00
committed by Nanne Baars
parent c4c28f544f
commit 6c25cf8e43
72 changed files with 1286 additions and 146 deletions

View File

@ -64,7 +64,7 @@ public abstract class AssignmentEndpoint {
* @param assignment
*/
protected AttackResult.AttackResultBuilder success(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(true).feedback("assignment.solved").assignment(assignment);
return AttackResult.builder(messages).lessonCompleted(true).attemptWasMade().feedback("assignment.solved").assignment(assignment);
}
/**
@ -79,7 +79,7 @@ public abstract class AssignmentEndpoint {
* @param assignment
*/
protected AttackResult.AttackResultBuilder failed(AssignmentEndpoint assignment) {
return AttackResult.builder(messages).lessonCompleted(false).feedback("assignment.not.solved").assignment(assignment);
return AttackResult.builder(messages).lessonCompleted(false).attemptWasMade().feedback("assignment.not.solved").assignment(assignment);
}
protected AttackResult.AttackResultBuilder informationMessage(AssignmentEndpoint assignment) {

View File

@ -29,8 +29,6 @@ import lombok.Getter;
import org.apache.commons.lang3.StringEscapeUtils;
import org.owasp.webgoat.i18n.PluginMessages;
import java.util.Objects;
public class AttackResult {
@ -43,6 +41,7 @@ public class AttackResult {
private String output;
private Object[] outputArgs;
private AssignmentEndpoint assignment;
private boolean attemptWasMade = false;
public AttackResultBuilder(PluginMessages messages) {
this.messages = messages;
@ -80,8 +79,13 @@ public class AttackResult {
return this;
}
public AttackResultBuilder attemptWasMade() {
this.attemptWasMade = true;
return this;
}
public AttackResult build() {
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs), assignment.getClass().getSimpleName());
return new AttackResult(lessonCompleted, messages.getMessage(feedbackResourceBundleKey, feedbackArgs), messages.getMessage(output, output, outputArgs), assignment.getClass().getSimpleName(), attemptWasMade);
}
public AttackResultBuilder assignment(AssignmentEndpoint assignment) {
@ -98,12 +102,15 @@ public class AttackResult {
private String output;
@Getter
private final String assignment;
@Getter
private boolean attemptWasMade;
public AttackResult(boolean lessonCompleted, String feedback, String output, String assignment) {
public AttackResult(boolean lessonCompleted, String feedback, String output, String assignment, boolean attemptWasMade) {
this.lessonCompleted = lessonCompleted;
this.feedback = StringEscapeUtils.escapeJson(feedback);
this.output = StringEscapeUtils.escapeJson(output);
this.assignment = assignment;
this.attemptWasMade = attemptWasMade;
}
public static AttackResultBuilder builder(PluginMessages messages) {

View File

@ -1,67 +0,0 @@
.attack-container.quiz {
background: none;
border: none;
}
#q_container p {
font-weight: bold;
}
#q_container .quiz_question {
border: solid 2px white;
padding: 4px;
margin: 5px 2px 20px 2px;
box-shadow: 0px 1px 3px 1px #e4e4e4;
}
#q_container .quiz_question label {
font-weight: normal;
position: relative;
top: -2px;
}
#q_container .quiz_question input {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 2px solid #dadada;
background: white;
width: 15px;
height: 15px;
margin-right: 6px;
}
#q_container .quiz_question input:checked {
background: #51b7ff;
}
#q_container .quiz_question input:hover,
#q_container .quiz_question label:hover {
cursor: pointer;
}
#q_container .quiz_question.correct {
border: solid 2px #ddf7dd;
background: #ddf7dd;
transition: all 300ms ease-in-out;
}
#q_container .quiz_question.incorrect {
border: solid 2px #f5d3d3;
background: #f5d3d3;
transition: all 300ms ease-in-out;
}
input[name='Quiz_solutions'] {
background: white;
border: 1px solid gray;
padding: 7px 10px;
transition: 300ms all ease-in-out;
}
input[name='Quiz_solutions']:hover {
background: #51b7ff;
color: white;
border-color: white;
transition: 300ms all ease-in-out;
}

View File

@ -1,59 +0,0 @@
/**
This is the basic javascript that can be used for a quiz assignment. It is made for single choice quizzes (tho a multiple choice extension should be easy to make).
Basic steps for implementing a quiz:
1. HTML: include this js script file for the assignment, build a basic form, where you include a #q_container div element, create a submit button with "Quiz_solutions" as name attribute
2. JSON: Create a JSON-file with the name questions_lesson_name.json, include a span element #quiz_id with lesson_name as the data-quiz_id attribute. Build a JSON file like the one in sql-injection -> resources -> js
3. Java: Create a normal assignment that has a String[] where the correct solutions are contained in the form of "Solution [i]", replace [i] with the position of the solution beginning at 1.
The request parameters will contain the answer in full text with "Solution [i]" in front of the text. Use them to check the answers validity.
4. CSS: include the css/quiz.css file for styling.
**/
$(function () {
var json = "";
var client = new XMLHttpRequest();
var quiz_id = document.getElementById("quiz_id").getAttribute("data-quiz_id");
client.open('GET', '/WebGoat/lesson_js/questions_' + quiz_id + '.json');
client.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
json += client.responseText;
console.log("entry");
let questionsJson = json;
var questionsObj = JSON.parse(questionsJson);
let html = "";
jQuery.each(questionsObj, function(i, obj) {
jQuery.each(obj, function(j, quest) {
html += "<div id='question_" + j + "' class='quiz_question' name='question'><p>" + (j+1) + ".&nbsp;" + quest.text + "</p>";
html += "<fieldset>";
jQuery.each(quest.solutions, function(k, solution) {
solution = "Solution " + k + ": " + solution;
html += '<input id="question_' + j + '_' + k + '_input" type="radio" name="question_' + j +'_solution" value="' + solution + '" required><label for="question_' + j + '_' + k + '_input">' + solution + '</label><br>';
});
html += "</fieldset></div>";
});
});
document.getElementById("q_container").innerHTML = html;
}
}
client.send();
});
$(document).ready( () => {
$("#q_container").closest(".attack-container").addClass("quiz");
$("#q_container").closest("form").on("submit", function(e) {
setTimeout(getFeedback, 200, this);
}); // end listener
}); // end ready
function getFeedback(context) {
$.ajax({
url: $(context).attr("action")
}).done( (result) => {
if (!result) return;
for(let i=0; i<result.length; i++) {
if (result[i] === true)
$("#q_container .quiz_question:nth-of-type(" + (i+1) + ")").removeClass("incorrect").addClass("correct");
else if (result[i] === false)
$("#q_container .quiz_question:nth-of-type(" + (i+1) + ")").removeClass("correct").addClass("incorrect");
}
}); // end ajax-done
} // end getFeedback