Skip to content

Commit 5f91df0

Browse files
Whitelist Regex Validation Tests
Providing a structure to assert that the enviroment configurations will provide expected responses when passed controlled values. Performing a preliminary whitelist test set on HttpQueryString regex from ESAPI.properties. The test implementation asserts that the regex being tested matches the test environment's regex for a given property. If the regex strings differ, the tests associated with that property will be skipped to prevent false-positives from being provided to a client.
1 parent f006b53 commit 5f91df0

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.owasp.esapi.reference;
2+
3+
import java.util.regex.Pattern;
4+
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
import org.junit.runner.RunWith;
8+
import org.junit.runners.Parameterized;
9+
10+
11+
/**
12+
* FIXME: Document intent of class. General Function, purpose of creation, intended feature, etc.
13+
* Why do people care this exists?
14+
* @author Jeremiah
15+
* @since Jan 20, 2018
16+
*
17+
*/
18+
@RunWith (Parameterized.class)
19+
public abstract class AbstractPatternTest {
20+
21+
protected static class PatternTestTuple {
22+
String input;
23+
String regex;
24+
boolean shouldMatch;
25+
String description;
26+
/** {@inheritDoc}*/
27+
@Override
28+
public String toString() {
29+
return description != null ? description : regex;
30+
}
31+
}
32+
33+
private String input;
34+
private Pattern pattern;
35+
private boolean shouldMatch;
36+
37+
38+
public AbstractPatternTest(PatternTestTuple tuple) {
39+
this.input = tuple.input;
40+
this.pattern = Pattern.compile(tuple.regex);
41+
this.shouldMatch = tuple.shouldMatch;
42+
}
43+
44+
@Test
45+
public void checkPatternMatches() {
46+
Assert.assertEquals(shouldMatch, pattern.matcher(input).matches());
47+
}
48+
49+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package org.owasp.esapi.reference;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
6+
import org.junit.Assume;
7+
import org.junit.runners.Parameterized.Parameters;
8+
import org.owasp.esapi.reference.DefaultSecurityConfiguration;
9+
10+
/**
11+
* Extension of the AbstractPatternTest which focuses on asserting that the default whitelist regex values applied in
12+
* the validation process are performing the intended function in the environment.
13+
*
14+
* <br/>
15+
*
16+
* If the regex values in this test are found to not match the running environment configurations, then the tests will
17+
* be skipped.
18+
*
19+
* @author Jeremiah
20+
* @since Jan 20, 2018
21+
*/
22+
public class EsapiWhitelistValidationPatternTester extends AbstractPatternTest {
23+
//See ESAPI.properties
24+
private static final String HTTP_QUERY_STRING_PROP_NAME="HTTPQueryString";
25+
private static final String HTTP_QUERY_STRING_REGEX="^([a-zA-Z0-9_\\-]{1,32}=[\\p{L}\\p{N}.\\-/+=_ !$*?@%]*&?)*$";
26+
27+
@Parameters(name = "{0}-{1}")
28+
public static Collection<Object[]> createDefaultPatternTests() {
29+
Collection<Object[]> parameters = new ArrayList<>();
30+
31+
for(PatternTestTuple tuple : buildHttpQueryStringTests()) {
32+
parameters.add(new Object[] { HTTP_QUERY_STRING_PROP_NAME, tuple });
33+
}
34+
35+
36+
return parameters;
37+
}
38+
39+
private static Collection<PatternTestTuple> buildHttpQueryStringTests() {
40+
Collection <PatternTestTuple> httpQueryStringTests = new ArrayList<>();
41+
42+
//MATCHING CASES
43+
PatternTestTuple tuple = newHttpQueryStringTuple("Default Case", "b", true);
44+
httpQueryStringTests.add(tuple);
45+
tuple = newHttpQueryStringTuple("Percent Encoded Value", "%62", true);
46+
httpQueryStringTests.add(tuple);
47+
tuple = newHttpQueryStringTuple("Percent Encoded Null Character", "%00", true);
48+
httpQueryStringTests.add(tuple);
49+
tuple = newHttpQueryStringTuple("Double Equals", "=", true);
50+
httpQueryStringTests.add(tuple);
51+
52+
//NON-MATCHING CASES
53+
tuple = newHttpQueryStringTuple("Ampersand In Value", "&b", false);
54+
httpQueryStringTests.add(tuple);
55+
tuple = newHttpQueryStringTuple("Null Character", ""+Character.MIN_VALUE, false);
56+
httpQueryStringTests.add(tuple);
57+
tuple = newHttpQueryStringTuple("Encoded Null Character", "\u0000", false);
58+
httpQueryStringTests.add(tuple);
59+
60+
return httpQueryStringTests;
61+
}
62+
63+
private static PatternTestTuple newHttpQueryStringTuple(String description, String value, boolean shouldPass) {
64+
PatternTestTuple tuple = new PatternTestTuple();
65+
tuple.input = "a="+value;
66+
tuple.shouldMatch = shouldPass;
67+
tuple.regex = HTTP_QUERY_STRING_REGEX;
68+
tuple.description = description;
69+
return tuple;
70+
}
71+
72+
public EsapiWhitelistValidationPatternTester(String property, PatternTestTuple tuple) {
73+
super(tuple);
74+
/*
75+
* This next block causes the case to be skipped programatically if the regex being tested
76+
* is different than the one being loaded at runtime.
77+
* This is being done to prevent a false sense of security.
78+
* If the configurations are changed to meet additional environmental concerns, the intent of this test should
79+
* be copied into that environment and tested there to assert the additional expectations or changes in desired
80+
* behavior.
81+
*/
82+
DefaultSecurityConfiguration configuration = new DefaultSecurityConfiguration();
83+
Assume.assumeTrue(
84+
"The regular expression specified does not match the configuration settings.\n"
85+
+ "If the value was changed from the ESAPI default, it is recommended to copy "
86+
+ "this class into your project, update the regex being tested, and update all "
87+
+ "associated input expectations for your unique environment.",
88+
configuration.getValidationPattern(property).toString().equals(tuple.regex));
89+
}
90+
91+
}

0 commit comments

Comments
 (0)