Add test case for security question assignment and the tracking is now
done with a session scoped bean
This commit is contained in:
parent
18eee4df58
commit
e01c2a35ce
@ -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,44 +12,53 @@ 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;
|
||||
private static Map<String, String> questions;
|
||||
|
||||
static {
|
||||
questions = new HashMap<>();
|
||||
questions.put("What is your favorite animal?", "The answer can easily be guessed and figured out through social media.");
|
||||
questions.put("In what year was your mother born?", "Can be easily guessed.");
|
||||
questions.put("What was the time you were born?", "This may first seem like a good question, but you most likely dont know the exact time, so it might be hard to remember.");
|
||||
questions.put("What is the name of the person you first kissed?", "Can be figured out through social media, or even guessed by trying the most common names.");
|
||||
questions.put("What was the house number and street name you lived in as a child?", "Answer can be figured out through social media, or worse it might be your current address.");
|
||||
questions.put("In what town or city was your first full time job?", "In times of LinkedIn and Facebook, the answer can be figured out quite easily.");
|
||||
questions.put("In what city were you born?", "Easy to figure out through social media.");
|
||||
questions.put("What was the last name of your favorite teacher in grade three?", "Most people would probably not know the answer to that.");
|
||||
questions.put("What is the name of a college/job you applied to but didn't attend?", "It might not be easy to remember and an hacker could just try some company's/colleges in your area.");
|
||||
questions.put("What are the last 5 digits of your drivers license?", "Is subject to change, and the last digit of your driver license might follow a specific pattern. (For example your birthday).");
|
||||
questions.put("What was your childhood nickname?", "Not all people had a nickname.");
|
||||
questions.put("Who was your childhood hero?", "Most Heroes we had as a child where quite obvious ones, like Superman for example.");
|
||||
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();
|
||||
}
|
||||
static {
|
||||
questions = new HashMap<>();
|
||||
questions.put("What is your favorite animal?", "The answer can easily be guessed and figured out through social media.");
|
||||
questions.put("In what year was your mother born?", "Can be easily guessed.");
|
||||
questions.put("What was the time you were born?", "This may first seem like a good question, but you most likely dont know the exact time, so it might be hard to remember.");
|
||||
questions.put("What is the name of the person you first kissed?", "Can be figured out through social media, or even guessed by trying the most common names.");
|
||||
questions.put("What was the house number and street name you lived in as a child?", "Answer can be figured out through social media, or worse it might be your current address.");
|
||||
questions.put("In what town or city was your first full time job?", "In times of LinkedIn and Facebook, the answer can be figured out quite easily.");
|
||||
questions.put("In what city were you born?", "Easy to figure out through social media.");
|
||||
questions.put("What was the last name of your favorite teacher in grade three?", "Most people would probably not know the answer to that.");
|
||||
questions.put("What is the name of a college/job you applied to but didn't attend?", "It might not be easy to remember and an hacker could just try some company's/colleges in your area.");
|
||||
questions.put("What are the last 5 digits of your drivers license?", "Is subject to change, and the last digit of your driver license might follow a specific pattern. (For example your birthday).");
|
||||
questions.put("What was your childhood nickname?", "Not all people had a nickname.");
|
||||
questions.put("Who was your childhood hero?", "Most Heroes we had as a child where quite obvious ones, like Superman for example.");
|
||||
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)
|
||||
@ResponseBody
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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}
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user