Add test case for security question assignment and the tracking is now

done with a session scoped bean
This commit is contained in:
Nanne Baars 2019-08-06 19:03:40 +02:00
parent 18eee4df58
commit e01c2a35ce
4 changed files with 145 additions and 30 deletions

View File

@ -3,6 +3,7 @@ package org.owasp.webgoat.plugin;
import org.owasp.webgoat.assignments.AssignmentEndpoint;
import org.owasp.webgoat.assignments.AssignmentPath;
import org.owasp.webgoat.assignments.AttackResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@ -11,15 +12,19 @@ import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
import static java.util.Optional.of;
/**
* Assignment for picking a good security question.
*
* @author Tobias Melzer
* @since 11.12.18
*/
@AssignmentPath("/PasswordReset/SecurityQuestions")
public class SecurityQuestionAssignment extends AssignmentEndpoint {
private static int triedQuestions = 0;
@Autowired
private TriedQuestions triedQuestions;
private static Map<String, String> questions;
@ -40,15 +45,20 @@ public class SecurityQuestionAssignment extends AssignmentEndpoint {
questions.put("On which wrist do you were your watch?", "There are only to possible real answers, so really easy to guess.");
questions.put("What is your favorite color?", "Can easily be guessed.");
}
@RequestMapping(method = RequestMethod.POST)
public
@ResponseBody
AttackResult completed(@RequestParam String question) {
triedQuestions+=1;
String answer = questions.get(question);
answer = "<b>" + answer + "</b>";
if(triedQuestions > 1)
return trackProgress(success().output(answer).build());
return failed().output(answer).build();
public AttackResult completed(@RequestParam String question) {
var answer = of(questions.get(question));
if (answer.isPresent()) {
triedQuestions.incr(question);
if (triedQuestions.isComplete()) {
return trackProgress(success().output("<b>" + answer + "</b>").build());
}
}
return informationMessage()
.feedback("password-questions-one-successful")
.output(answer.orElse("Unknown question, please try again..."))
.build();
}
}

View File

@ -0,0 +1,22 @@
package org.owasp.webgoat.plugin;
import com.google.common.collect.Sets;
import org.springframework.stereotype.Component;
import org.springframework.web.context.annotation.SessionScope;
import java.util.Set;
@Component
@SessionScope
public class TriedQuestions {
private Set<String> answeredQuestions = Sets.newHashSet();
public void incr(String question) {
answeredQuestions.add(question);
}
public boolean isComplete() {
return answeredQuestions.size() > 1;
}
}

View File

@ -7,6 +7,7 @@ password-reset-simple.email_mismatch=Of course you can send mail to user {0} how
password-questions-wrong-user=You need to find a different user you are logging in with 'webgoat'.
password-questions-unknown-user=User {0} is not a valid user.
password-questions-one-successful=You answered one question successfully please try another one.
password-reset-no-user=Please supply a valid e-mail address.
password-reset-solved=Congratulations you solved the assignment, please type in the following code in the e-mail field: {0}

View File

@ -0,0 +1,82 @@
package org.owasp.webgoat.plugin;
import org.hamcrest.CoreMatchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.owasp.webgoat.plugins.LessonTest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringJUnit4ClassRunner.class)
public class SecurityQuestionAssignmentTest extends LessonTest {
@Before
public void setup() {
PasswordReset assignment = new PasswordReset();
Mockito.when(webSession.getCurrentLesson()).thenReturn(assignment);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
Mockito.when(webSession.getUserName()).thenReturn("unit-test");
}
@Test
public void oneQuestionShouldNotSolveTheAssignment() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("password-questions-one-successful"))))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)))
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()));
}
@Test
public void twoQuestionsShouldSolveTheAssignment() throws Exception {
MockHttpSession mocksession = new MockHttpSession();
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?").session(mocksession))
.andExpect(status().isOk())
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "In what year was your mother born?").session(mocksession))
.andExpect(status().isOk())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("assignment.solved"))))
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
}
@Test
public void answeringSameQuestionTwiceShouldNotSolveAssignment() throws Exception {
MockHttpSession mocksession = new MockHttpSession();
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?").session(mocksession))
.andExpect(status().isOk());
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?").session(mocksession))
.andExpect(status().isOk())
.andExpect(jsonPath("$.feedback", CoreMatchers.is(messages.getMessage("password-questions-one-successful"))))
.andExpect(jsonPath("$.output", CoreMatchers.notNullValue()))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
}
@Test
public void solvingForOneUserDoesNotSolveForOtherUser() throws Exception {
MockHttpSession mocksession = new MockHttpSession();
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?").session(mocksession));
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "In what year was your mother born?").session(mocksession))
.andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(true)));
MockHttpSession mocksession2 = new MockHttpSession();
mockMvc.perform(MockMvcRequestBuilders.post("/PasswordReset/SecurityQuestions")
.param("question", "What is your favorite animal?").session(mocksession2)).
andExpect(jsonPath("$.lessonCompleted", CoreMatchers.is(false)));
}
}