- Added testcases for bypassing frontend validation.

- Improved layout of the lesson
- Fixed JavaScript issues with 'let'
This commit is contained in:
Nanne Baars 2017-06-16 01:16:31 +02:00
parent bf210de013
commit edceba73fe
5 changed files with 105 additions and 48 deletions

View File

@ -8,27 +8,4 @@
<artifactId>webgoat-lessons-parent</artifactId>
<version>8.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>4.1.3.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<type>jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -52,63 +52,63 @@
enctype="application/json;charset=UTF-8"
onsubmit="return validate()">
<div>
Field1: exactly three lowercase characters(^[a-z]{3}$)
<strong>Field 1:</strong> exactly three lowercase characters(^[a-z]{3}$)
</div>
<div>
<textarea cols="25" name="field1" rows="1">abc</textarea>
</div>
<p></p>
<div>Field2: exactly three digits(^[0-9]{3}$)</div>
<div><strong>Field 2:</strong> exactly three digits(^[0-9]{3}$)</div>
<div>
<textarea cols="25" name="field2" rows="1">123</textarea>
</div>
<p></p>
<div>Field3: letters, numbers, and space only(^[a-zA-Z0-9 ]*$)</div>
<div><strong>Field 3:</strong> letters, numbers, and space only(^[a-zA-Z0-9 ]*$)</div>
<div>
<textarea cols="25" name="field3" rows="1">abc 123 ABC</textarea>
</div>
<p></p>
<div>Field4: enumeration of numbers (^(one|two|three|four|five|six|seven|eight|nine)$)</div>
<div><strong>Field 4:</strong> enumeration of numbers (^(one|two|three|four|five|six|seven|eight|nine)$)</div>
<div>
<textarea cols="25" name="field4" rows="1">seven</textarea>
</div>
<p></p>
<div>Field5: simple zip code (^\d{5}$)</div>
<div><strong>Field 5:</strong> simple zip code (^\d{5}$)</div>
<div>
<textarea cols="25" name="field5" rows="1">01101</textarea>
</div>
<p></p>
<div>Field6: zip with optional dash four (^\d{5}(-\d{4})?$)</div>
<div><strong>Field 6:</strong> zip with optional dash four (^\d{5}(-\d{4})?$)</div>
<div>
<textarea cols="25" name="field6" rows="1">90210-1111</textarea>
</div>
<p></p>
<div>Field7: US phone number with or without dashes (^[2-9]\d{2}-?\d{3}-?\d{4}$)</div>
<div><strong>Field 7:</strong> US phone number with or without dashes (^[2-9]\d{2}-?\d{3}-?\d{4}$)</div>
<div>
<textarea cols="25" name="field7" rows="1">301-604-4882</textarea>
</div>
<input type="hidden" value="" name="error" />
<p><input type="submit" value="Submit" /></p>
<p><button type="submit" class="btn btn-primary">Submit</button></p>
</form>
<script>
let regex1=/^[a-z]{3}$/;
let regex2=/^[0-9]{3}$/;
let regex3=/^[a-zA-Z0-9 ]*$/;
let regex4=/^(one|two|three|four|five|six|seven|eight|nine)$/;
let regex5=/^\d{5}$/;
let regex6=/^\d{5}(-\d{4})?$/;
let regex7=/^[2-9]\d{2}-?\d{3}-?\d{4}$/;
var regex1=/^[a-z]{3}$/;
var regex2=/^[0-9]{3}$/;
var regex3=/^[a-zA-Z0-9 ]*$/;
var regex4=/^(one|two|three|four|five|six|seven|eight|nine)$/;
var regex5=/^\d{5}$/;
var regex6=/^\d{5}(-\d{4})?$/;
var regex7=/^[2-9]\d{2}-?\d{3}-?\d{4}$/;
var validate = function() {
let msg='JavaScript found form errors';
let err=0;
if (!regex1.test(document.frontendValidation.field1.value)) {err+=1; msg+='\n bad field1';}
if (!regex2.test(document.frontendValidation.field2.value)) {err+=1; msg+='\n bad field2';}
if (!regex3.test(document.frontendValidation.field3.value)) {err+=1; msg+='\n bad field3';}
if (!regex4.test(document.frontendValidation.field4.value)) {err+=1; msg+='\n bad field4';}
if (!regex5.test(document.frontendValidation.field5.value)) {err+=1; msg+='\n bad field5';}
if (!regex6.test(document.frontendValidation.field6.value)) {err+=1; msg+='\n bad field6';}
if (!regex7.test(document.frontendValidation.field7.value)) {err+=1; msg+='\n bad field7';}
var msg='JavaScript found form errors';
var err=0;
if (!regex1.test(document.frontendValidation.field1.value)) {err+=1; msg+='\n Value entered for field 1 is not correct';}
if (!regex2.test(document.frontendValidation.field2.value)) {err+=1; msg+='\n Value entered for field 2 is not correct';}
if (!regex3.test(document.frontendValidation.field3.value)) {err+=1; msg+='\n Value entered for field 3 is not correct';}
if (!regex4.test(document.frontendValidation.field4.value)) {err+=1; msg+='\n Value entered for field 4 is not correct';}
if (!regex5.test(document.frontendValidation.field5.value)) {err+=1; msg+='\n Value entered for field 5 is not correct';}
if (!regex6.test(document.frontendValidation.field6.value)) {err+=1; msg+='\n Value entered for field 6 is not correct';}
if (!regex7.test(document.frontendValidation.field7.value)) {err+=1; msg+='\n Value entered for field 7 is not correct';}
document.frontendValidation.error.value = err
if ( err > 0 ) {
alert(msg)
@ -117,6 +117,8 @@
return true;
}
</script>
<br/>
<br/>
<div class="attack-feedback"></div>
<div class="attack-output"></div>
</div>

View File

@ -1,4 +1,5 @@
== Validation
Often, there is some mechanism in place to prevent users from sending altered
field values to server, such as validation before sending. Most of popular browsers
such as Chrome don't allow editing scripts during runtime. We will have to circumvent

View File

@ -1,10 +1,11 @@
== Concept
Users have a great degree of control over the front-end of the web application.
They can alter HTML code, sometimes also scripts. This is why
apps that require certain format of input should also validate on server-side.
== Goals
* The user should have a basic knowledge of HTML
* The user should be able to tamper a request before sending (with proxy or other tool)
* The user will be able to tamper with field restrictions and bypass client-side validation

View File

@ -0,0 +1,76 @@
package org.owasp.webgoat.plugin;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.owasp.webgoat.plugins.LessonTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.is;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author nbaars
* @since 6/16/17.
*/
@RunWith(SpringJUnit4ClassRunner.class)
public class BypassRestrictionsFrontendValidationTest extends LessonTest {
@Before
public void setup() throws Exception {
when(webSession.getCurrentLesson()).thenReturn(new BypassRestrictions());
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void noChangesShouldNotPassTheLesson() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
.param("field1", "abc")
.param("field2", "123")
.param("field3", "abc ABC 123")
.param("field4", "seven")
.param("field5", "01101")
.param("field6", "90201 1111")
.param("field7", "301-604-4882")
.param("error", "2"))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
}
@Test
public void bypassAllFieldShouldPass() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
.param("field1", "abcd")
.param("field2", "1234")
.param("field3", "abc $ABC 123")
.param("field4", "ten")
.param("field5", "01101AA")
.param("field6", "90201 1111AA")
.param("field7", "301-604-4882$$")
.param("error", "0"))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(true)));
}
@Test
public void notBypassingAllFieldShouldNotPass() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.post("/BypassRestrictions/frontendValidation")
.param("field1", "abc")
.param("field2", "1234")
.param("field3", "abc $ABC 123")
.param("field4", "ten")
.param("field5", "01101AA")
.param("field6", "90201 1111AA")
.param("field7", "301-604-4882AA")
.param("error", "0"))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk()).andExpect(jsonPath("$.lessonCompleted", is(false)));
}
}