From 8e3b5736b2bc05a1d11c9d0054404ff76a718db1 Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sun, 18 Jun 2017 15:49:54 -0700 Subject: [PATCH 1/7] Issue 316 -- updated code to account for httpOnly and Secure ccookie options. --- .../owasp/esapi/reference/DefaultHTTPUtilities.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java index 3c460c872..659e1cc4e 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java @@ -41,6 +41,7 @@ import org.owasp.esapi.ESAPI; import org.owasp.esapi.HTTPUtilities; import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; import org.owasp.esapi.StringUtilities; import org.owasp.esapi.User; import org.owasp.esapi.ValidationErrorList; @@ -929,6 +930,9 @@ public String setRememberToken( HttpServletRequest request, HttpServletResponse String clearToken = user.getAccountName() + "|" + password; long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000); String cryptToken = ESAPI.encryptor().seal(clearToken, expiry); + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean forceSecureCookies = sg.getBooleanProp("HttpUtilities.ForceSecureCookies"); + boolean forceHttpOnly = sg.getBooleanProp("HttpUtilities.ForceHttpOnlyCookies"); // Do NOT URLEncode cryptToken before creating cookie. See Google Issue # 144, // which was marked as "WontFix". @@ -937,6 +941,8 @@ public String setRememberToken( HttpServletRequest request, HttpServletResponse cookie.setMaxAge( maxAge ); cookie.setDomain( domain ); cookie.setPath( path ); + cookie.setHttpOnly(forceHttpOnly); + cookie.setSecure(forceSecureCookies); response.addCookie( cookie ); logger.info(Logger.SECURITY_SUCCESS, "Enabled remember me token for " + user.getAccountName() ); return cryptToken; @@ -957,7 +963,9 @@ public String setRememberToken(HttpServletRequest request, HttpServletResponse r String clearToken = user.getAccountName(); long expiry = ESAPI.encryptor().getRelativeTimeStamp(maxAge * 1000); String cryptToken = ESAPI.encryptor().seal(clearToken, expiry); - + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean forceSecureCookies = sg.getBooleanProp("HttpUtilities.ForceSecureCookies"); + boolean forceHttpOnly = sg.getBooleanProp("HttpUtilities.ForceHttpOnlyCookies"); // Do NOT URLEncode cryptToken before creating cookie. See Google Issue # 144, // which was marked as "WontFix". @@ -965,6 +973,8 @@ public String setRememberToken(HttpServletRequest request, HttpServletResponse r cookie.setMaxAge( maxAge ); cookie.setDomain( domain ); cookie.setPath( path ); + cookie.setHttpOnly(forceHttpOnly); + cookie.setSecure(forceSecureCookies); response.addCookie( cookie ); logger.info(Logger.SECURITY_SUCCESS, "Enabled remember me token for " + user.getAccountName() ); } catch( IntegrityException e){ From 22663ed9ab5f17ddebe28e22d6ecaf6223763e21 Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sun, 18 Jun 2017 16:22:19 -0700 Subject: [PATCH 2/7] Issue 291 -- Closed due to Issue #376 resolving the original problem. --- src/test/resources/urisForTest.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/resources/urisForTest.txt b/src/test/resources/urisForTest.txt index 43f795e3d..df34cbc8e 100644 --- a/src/test/resources/urisForTest.txt +++ b/src/test/resources/urisForTest.txt @@ -1,4 +1,5 @@ #Format is URI,Expected test value +http://www.google.com?connectid=68470072-44c2-417b-822b-d945dc0364f4&request=GetFeature&service=wfs&version=1.1.0&typeName=DigitalGlobe%3AFinishedFeature&bbox=37.5%2C41.5%2C37.8%2C41.7&PROPERTYNAME=source%2CsourceUnit%2CproductType,FALSE https://127.0.0.1:8080/foo/bar,TRUE http://shareasale.com:8080/sem/fusce.xml?sed=sodales&tristique=scelerisque,TRUE http://shareasale.com/sem/fusce.xml?sed=sodales&tristique=scelerisque,TRUE From e5ebcab94a60ecf8a9c513ac61d8e99ac91b74f5 Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sun, 18 Jun 2017 16:42:05 -0700 Subject: [PATCH 3/7] Issue #394 -- Refactor the URI canonicalization into the Encoder class. --- src/main/java/org/owasp/esapi/Encoder.java | 12 ++ src/main/java/org/owasp/esapi/Validator.java | 11 -- .../owasp/esapi/reference/DefaultEncoder.java | 154 ++++++++++++++++++ .../esapi/reference/DefaultValidator.java | 150 +---------------- .../owasp/esapi/reference/EncoderTest.java | 28 ++++ .../owasp/esapi/reference/ValidatorTest.java | 28 ---- 6 files changed, 196 insertions(+), 187 deletions(-) diff --git a/src/main/java/org/owasp/esapi/Encoder.java b/src/main/java/org/owasp/esapi/Encoder.java index 2d2bfb7b9..cf83c472c 100644 --- a/src/main/java/org/owasp/esapi/Encoder.java +++ b/src/main/java/org/owasp/esapi/Encoder.java @@ -16,6 +16,7 @@ package org.owasp.esapi; import java.io.IOException; +import java.net.URI; import org.owasp.esapi.codecs.Codec; import org.owasp.esapi.errors.EncodingException; @@ -513,4 +514,15 @@ public interface Encoder { */ byte[] decodeFromBase64(String input) throws IOException; + /** + * + * Get a version of the input URI that will be safe to run regex and other validations against. + * It is not recommended to persist this value as it will transform user input. This method + * will not test to see if the URI is RFC-3986 compliant. + * + * @param input + * @return + */ + public String getCanonicalizedURI(URI dirtyUri); + } diff --git a/src/main/java/org/owasp/esapi/Validator.java b/src/main/java/org/owasp/esapi/Validator.java index c01dae247..12c87ea15 100644 --- a/src/main/java/org/owasp/esapi/Validator.java +++ b/src/main/java/org/owasp/esapi/Validator.java @@ -708,17 +708,6 @@ public interface Validator { */ boolean isValidURI(String context, String input, boolean allowNull); - /** - * - * Get a version of the input URI that will be safe to run regex and other validations against. - * It is not recommended to persist this value as it will transform user input. This method - * will not test to see if the URI is RFC-3986 compliant. - * - * @param input - * @return - */ - public String getCanonicalizedURI(URI dirtyUri); - /** * Will return a {@code URI} object that will represent a fully parsed and legal URI * as specified in RFC-3986. diff --git a/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java b/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java index c40c0d60b..c24fac4b5 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java @@ -17,15 +17,23 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.net.URI; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; +import java.util.EnumMap; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import org.owasp.esapi.ESAPI; import org.owasp.esapi.Encoder; import org.owasp.esapi.Logger; +import org.owasp.esapi.SecurityConfiguration; import org.owasp.esapi.codecs.Base64; import org.owasp.esapi.codecs.CSSCodec; import org.owasp.esapi.codecs.Codec; @@ -445,4 +453,150 @@ public byte[] decodeFromBase64(String input) throws IOException { } return Base64.decode( input ); } + + /** + * {@inheritDoc} + * + * This will extract each piece of a URI according to parse zone as specified in RFC-3986 section 3, + * and it will construct a canonicalized String representing a version of the URI that is safe to + * run regex against. + * + * @param dirtyUri + * @return Canonicalized URI string. + * @throws IntrusionException + */ + public String getCanonicalizedURI(URI dirtyUri) throws IntrusionException{ + +// From RFC-3986 section 3 +// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] +// +// hier-part = "//" authority path-abempty +// / path-absolute +// / path-rootless +// / path-empty + +// The following are two example URIs and their component parts: +// +// foo://example.com:8042/over/there?name=ferret#nose +// \_/ \______________/\_________/ \_________/ \__/ +// | | | | | +// scheme authority path query fragment +// | _____________________|__ +// / \ / \ +// urn:example:animal:ferret:nose + Map parseMap = new EnumMap(UriSegment.class); + parseMap.put(UriSegment.SCHEME, dirtyUri.getScheme()); + //authority = [ userinfo "@" ] host [ ":" port ] + parseMap.put(UriSegment.AUTHORITY, dirtyUri.getRawAuthority()); + parseMap.put(UriSegment.SCHEMSPECIFICPART, dirtyUri.getRawSchemeSpecificPart()); + parseMap.put(UriSegment.HOST, dirtyUri.getHost()); + //if port is undefined, it will return -1 + Integer port = new Integer(dirtyUri.getPort()); + parseMap.put(UriSegment.PORT, port == -1 ? "": port.toString()); + parseMap.put(UriSegment.PATH, dirtyUri.getRawPath()); + parseMap.put(UriSegment.QUERY, dirtyUri.getRawQuery()); + parseMap.put(UriSegment.FRAGMENT, dirtyUri.getRawFragment()); + + //Now we canonicalize each part and build our string. + StringBuilder sb = new StringBuilder(); + + //Replace all the items in the map with canonicalized versions. + + Set set = parseMap.keySet(); + + SecurityConfiguration sg = ESAPI.securityConfiguration(); + boolean allowMixed = sg.getBooleanProp("Encoder.AllowMixedEncoding"); + boolean allowMultiple = sg.getBooleanProp("Encoder.AllowMultipleEncoding"); + for(UriSegment seg: set){ + String value = canonicalize(parseMap.get(seg), allowMultiple, allowMixed); + value = value == null ? "" : value; + //In the case of a uri query, we need to break up and canonicalize the internal parts of the query. + if(seg == UriSegment.QUERY && null != parseMap.get(seg)){ + StringBuilder qBuilder = new StringBuilder(); + try { + Map> canonicalizedMap = this.splitQuery(dirtyUri); + Set>> query = canonicalizedMap.entrySet(); + Iterator>> i = query.iterator(); + while(i.hasNext()){ + Entry> e = i.next(); + String key = (String) e.getKey(); + String qVal = ""; + List list = (List) e.getValue(); + if(!list.isEmpty()){ + qVal = list.get(0); + } + qBuilder.append(key) + .append("=") + .append(qVal); + + if(i.hasNext()){ + qBuilder.append("&"); + } + } + value = qBuilder.toString(); + } catch (UnsupportedEncodingException e) { + logger.debug(Logger.EVENT_FAILURE, "decoding error when parsing [" + dirtyUri.toString() + "]"); + } + } + //Check if the port is -1, if it is, omit it from the output. + if(seg == UriSegment.PORT){ + if("-1" == parseMap.get(seg)){ + value = ""; + } + } + parseMap.put(seg, value ); + } + + return buildUrl(parseMap); + } + + /** + * All the parts should be canonicalized by this point. This is straightforward assembly. + * + * @param set + * @return + */ + protected String buildUrl(Map parseMap){ + StringBuilder sb = new StringBuilder(); + sb.append(parseMap.get(UriSegment.SCHEME)) + .append("://") + //can't use SCHEMESPECIFICPART for this, because we need to canonicalize all the parts of the query. + //USERINFO is also deprecated. So we technically have more than we need. + .append(parseMap.get(UriSegment.AUTHORITY) == null || parseMap.get(UriSegment.AUTHORITY).equals("") ? "" : parseMap.get(UriSegment.AUTHORITY)) + .append(parseMap.get(UriSegment.PATH) == null || parseMap.get(UriSegment.PATH).equals("") ? "" : parseMap.get(UriSegment.PATH)) + .append(parseMap.get(UriSegment.QUERY) == null || parseMap.get(UriSegment.QUERY).equals("") + ? "" : "?" + parseMap.get(UriSegment.QUERY)) + .append((parseMap.get(UriSegment.FRAGMENT) == null) || parseMap.get(UriSegment.FRAGMENT).equals("") + ? "": "#" + parseMap.get(UriSegment.FRAGMENT)) + ; + return sb.toString(); + } + + public enum UriSegment { + AUTHORITY, SCHEME, SCHEMSPECIFICPART, USERINFO, HOST, PORT, PATH, QUERY, FRAGMENT + } + + + /** + * The meat of this method was taken from StackOverflow: http://stackoverflow.com/a/13592567/557153 + * It has been modified to return a canonicalized key and value pairing. + * + * @param java URI + * @return a map of canonicalized query parameters. + * @throws UnsupportedEncodingException + */ + public Map> splitQuery(URI uri) throws UnsupportedEncodingException { + final Map> query_pairs = new LinkedHashMap>(); + final String[] pairs = uri.getQuery().split("&"); + for (String pair : pairs) { + final int idx = pair.indexOf("="); + final String key = idx > 0 ? canonicalize(pair.substring(0, idx)) : pair; + if (!query_pairs.containsKey(key)) { + query_pairs.put(key, new LinkedList()); + } + final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; + query_pairs.get(key).add(canonicalize(value)); + } + return query_pairs; + } } diff --git a/src/main/java/org/owasp/esapi/reference/DefaultValidator.java b/src/main/java/org/owasp/esapi/reference/DefaultValidator.java index 9b5197824..7b45f1d26 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultValidator.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultValidator.java @@ -1210,11 +1210,11 @@ private final boolean isEmpty(char[] input) { public boolean isValidURI(String context, String input, boolean allowNull) { boolean isValid = false; boolean inputIsNullOrEmpty = input == null || "".equals(input); - + Encoder encoder = ESAPI.encoder(); try{ URI compliantURI = null == input ? new URI("") : this.getRfcCompliantURI(input); if(null != compliantURI && input != null){ - String canonicalizedURI = getCanonicalizedURI(compliantURI); + String canonicalizedURI = encoder.getCanonicalizedURI(compliantURI); //if getCanonicalizedURI doesn't throw an IntrusionException, then the URI contains no mixed or //double-encoding attacks. logger.debug(Logger.SECURITY_SUCCESS, "We did not detect any mixed or multiple encoding in the uri:[" + input + "]"); @@ -1259,150 +1259,4 @@ public URI getRfcCompliantURI(String input){ } return rval; } - - /** - * {@inheritDoc} - * - * This will extract each piece of a URI according to parse zone as specified in RFC-3986 section 3, - * and it will construct a canonicalized String representing a version of the URI that is safe to - * run regex against. - * - * @param dirtyUri - * @return Canonicalized URI string. - * @throws IntrusionException - */ - public String getCanonicalizedURI(URI dirtyUri) throws IntrusionException{ - -// From RFC-3986 section 3 -// URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] -// -// hier-part = "//" authority path-abempty -// / path-absolute -// / path-rootless -// / path-empty - -// The following are two example URIs and their component parts: -// -// foo://example.com:8042/over/there?name=ferret#nose -// \_/ \______________/\_________/ \_________/ \__/ -// | | | | | -// scheme authority path query fragment -// | _____________________|__ -// / \ / \ -// urn:example:animal:ferret:nose - Map parseMap = new EnumMap(UriSegment.class); - parseMap.put(UriSegment.SCHEME, dirtyUri.getScheme()); - //authority = [ userinfo "@" ] host [ ":" port ] - parseMap.put(UriSegment.AUTHORITY, dirtyUri.getRawAuthority()); - parseMap.put(UriSegment.SCHEMSPECIFICPART, dirtyUri.getRawSchemeSpecificPart()); - parseMap.put(UriSegment.HOST, dirtyUri.getHost()); - //if port is undefined, it will return -1 - Integer port = new Integer(dirtyUri.getPort()); - parseMap.put(UriSegment.PORT, port == -1 ? "": port.toString()); - parseMap.put(UriSegment.PATH, dirtyUri.getRawPath()); - parseMap.put(UriSegment.QUERY, dirtyUri.getRawQuery()); - parseMap.put(UriSegment.FRAGMENT, dirtyUri.getRawFragment()); - - //Now we canonicalize each part and build our string. - StringBuilder sb = new StringBuilder(); - - //Replace all the items in the map with canonicalized versions. - - Set set = parseMap.keySet(); - - SecurityConfiguration sg = ESAPI.securityConfiguration(); - boolean allowMixed = sg.getBooleanProp("Encoder.AllowMixedEncoding"); - boolean allowMultiple = sg.getBooleanProp("Encoder.AllowMultipleEncoding"); - for(UriSegment seg: set){ - String value = encoder.canonicalize(parseMap.get(seg), allowMultiple, allowMixed); - value = value == null ? "" : value; - //In the case of a uri query, we need to break up and canonicalize the internal parts of the query. - if(seg == UriSegment.QUERY && null != parseMap.get(seg)){ - StringBuilder qBuilder = new StringBuilder(); - try { - Map> canonicalizedMap = this.splitQuery(dirtyUri); - Set>> query = canonicalizedMap.entrySet(); - Iterator>> i = query.iterator(); - while(i.hasNext()){ - Entry> e = i.next(); - String key = (String) e.getKey(); - String qVal = ""; - List list = (List) e.getValue(); - if(!list.isEmpty()){ - qVal = list.get(0); - } - qBuilder.append(key) - .append("=") - .append(qVal); - - if(i.hasNext()){ - qBuilder.append("&"); - } - } - value = qBuilder.toString(); - } catch (UnsupportedEncodingException e) { - logger.debug(Logger.EVENT_FAILURE, "decoding error when parsing [" + dirtyUri.toString() + "]"); - } - } - //Check if the port is -1, if it is, omit it from the output. - if(seg == UriSegment.PORT){ - if("-1" == parseMap.get(seg)){ - value = ""; - } - } - parseMap.put(seg, value ); - } - - return buildUrl(parseMap); - } - -/** - * The meat of this method was taken from StackOverflow: http://stackoverflow.com/a/13592567/557153 - * It has been modified to return a canonicalized key and value pairing. - * - * @param java URI - * @return a map of canonicalized query parameters. - * @throws UnsupportedEncodingException - */ - public Map> splitQuery(URI uri) throws UnsupportedEncodingException { - final Map> query_pairs = new LinkedHashMap>(); - final String[] pairs = uri.getQuery().split("&"); - for (String pair : pairs) { - final int idx = pair.indexOf("="); - final String key = idx > 0 ? encoder.canonicalize(pair.substring(0, idx)) : pair; - if (!query_pairs.containsKey(key)) { - query_pairs.put(key, new LinkedList()); - } - final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; - query_pairs.get(key).add(encoder.canonicalize(value)); - } - return query_pairs; - } - - public enum UriSegment { - AUTHORITY, SCHEME, SCHEMSPECIFICPART, USERINFO, HOST, PORT, PATH, QUERY, FRAGMENT - } - - /** - * All the parts should be canonicalized by this point. This is straightforward assembly. - * - * @param set - * @return - */ - protected String buildUrl(Map parseMap){ - StringBuilder sb = new StringBuilder(); - sb.append(parseMap.get(UriSegment.SCHEME)) - .append("://") - //can't use SCHEMESPECIFICPART for this, because we need to canonicalize all the parts of the query. - //USERINFO is also deprecated. So we technically have more than we need. - .append(parseMap.get(UriSegment.AUTHORITY) == null || parseMap.get(UriSegment.AUTHORITY).equals("") ? "" : parseMap.get(UriSegment.AUTHORITY)) - .append(parseMap.get(UriSegment.PATH) == null || parseMap.get(UriSegment.PATH).equals("") ? "" : parseMap.get(UriSegment.PATH)) - .append(parseMap.get(UriSegment.QUERY) == null || parseMap.get(UriSegment.QUERY).equals("") - ? "" : "?" + parseMap.get(UriSegment.QUERY)) - .append((parseMap.get(UriSegment.FRAGMENT) == null) || parseMap.get(UriSegment.FRAGMENT).equals("") - ? "": "#" + parseMap.get(UriSegment.FRAGMENT)) - ; - return sb.toString(); - } - } diff --git a/src/test/java/org/owasp/esapi/reference/EncoderTest.java b/src/test/java/org/owasp/esapi/reference/EncoderTest.java index bc2e1afde..e7979af4c 100644 --- a/src/test/java/org/owasp/esapi/reference/EncoderTest.java +++ b/src/test/java/org/owasp/esapi/reference/EncoderTest.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.io.ByteArrayOutputStream; @@ -854,5 +855,32 @@ public String javaScriptEncode(String str) { } } + public void testGetCanonicalizedUri() throws Exception { + Encoder e = ESAPI.encoder(); + + String expectedUri = "http://palpatine@foo bar.com/path_to/resource?foo=bar#frag"; + //Please note that section 3.2.1 of RFC-3986 explicitly states not to encode + //password information as in http://palpatine:password@foo.com, and this will + //not appear in the userinfo field. + String input = "http://palpatine@foo%20bar.com/path_to/resource?foo=bar#frag"; + URI uri = new URI(input); + System.out.println(uri.toString()); + assertEquals(expectedUri, e.getCanonicalizedURI(uri)); + + } + + public void testGetCanonicalizedUriWithMailto() throws Exception { + Encoder e = ESAPI.encoder(); + + String expectedUri = "http://palpatine@foo bar.com/path_to/resource?foo=bar#frag"; + //Please note that section 3.2.1 of RFC-3986 explicitly states not to encode + //password information as in http://palpatine:password@foo.com, and this will + //not appear in the userinfo field. + String input = "http://palpatine@foo%20bar.com/path_to/resource?foo=bar#frag"; + URI uri = new URI(input); + System.out.println(uri.toString()); + assertEquals(expectedUri, e.getCanonicalizedURI(uri)); + + } } diff --git a/src/test/java/org/owasp/esapi/reference/ValidatorTest.java b/src/test/java/org/owasp/esapi/reference/ValidatorTest.java index 614d25f1f..7df1227b0 100644 --- a/src/test/java/org/owasp/esapi/reference/ValidatorTest.java +++ b/src/test/java/org/owasp/esapi/reference/ValidatorTest.java @@ -1161,33 +1161,5 @@ public void testGetValidUriNullInput(){ boolean isValid = v.isValidURI("test", null, true); assertTrue(isValid); } - - public void testGetCanonicalizedUri() throws Exception { - Validator v = ESAPI.validator(); - - String expectedUri = "http://palpatine@foo bar.com/path_to/resource?foo=bar#frag"; - //Please note that section 3.2.1 of RFC-3986 explicitly states not to encode - //password information as in http://palpatine:password@foo.com, and this will - //not appear in the userinfo field. - String input = "http://palpatine@foo%20bar.com/path_to/resource?foo=bar#frag"; - URI uri = new URI(input); - System.out.println(uri.toString()); - assertEquals(expectedUri, v.getCanonicalizedURI(uri)); - - } - - public void testGetCanonicalizedUriWithMailto() throws Exception { - Validator v = ESAPI.validator(); - - String expectedUri = "http://palpatine@foo bar.com/path_to/resource?foo=bar#frag"; - //Please note that section 3.2.1 of RFC-3986 explicitly states not to encode - //password information as in http://palpatine:password@foo.com, and this will - //not appear in the userinfo field. - String input = "http://palpatine@foo%20bar.com/path_to/resource?foo=bar#frag"; - URI uri = new URI(input); - System.out.println(uri.toString()); - assertEquals(expectedUri, v.getCanonicalizedURI(uri)); - - } } From c97f70735b30b41cf4f6147b4893acf3d61795c8 Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sat, 1 Jul 2017 12:26:02 -0700 Subject: [PATCH 4/7] Issue #397 -- Restore search directory to maintain legacy search behavior. --- .../DefaultSecurityConfiguration.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java index 22b0f2067..1d59f2b24 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java @@ -15,6 +15,23 @@ */ package org.owasp.esapi.reference; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + import org.apache.commons.lang.text.StrTokenizer; import org.owasp.esapi.ESAPI; import org.owasp.esapi.Logger; @@ -22,12 +39,6 @@ import org.owasp.esapi.configuration.EsapiPropertyManager; import org.owasp.esapi.errors.ConfigurationException; -import java.io.*; -import java.net.URL; -import java.util.*; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; - /** * The reference {@code SecurityConfiguration} manages all the settings used by the ESAPI in a single place. In this reference * implementation, resources can be put in several locations, which are searched in the following order: @@ -653,8 +664,14 @@ private Properties loadConfigurationFromClasspath(String fileName) throws Illega // try resources folder if (in == null) { - currentClasspathSearchLocation = "src/main/resources/"; - in = currentLoader.getResourceAsStream("src/main/resources/" + fileName); + currentClasspathSearchLocation = "resources/"; + in = currentLoader.getResourceAsStream("resources/" + fileName); + } + + // try src/main/resources folder + if (in == null) { + currentClasspathSearchLocation = "resources/"; + in = currentLoader.getResourceAsStream("resources/" + fileName); } // now load the properties From 603408f73173145258e8677d0e1364d2e60c876e Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sat, 15 Jul 2017 12:07:52 -0700 Subject: [PATCH 5/7] Issue #399 -- Fixed mvn site so that the build no longer breaks on legacy javadoc comments. --- pom.xml | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 224f1f5c7..fd8551117 100644 --- a/pom.xml +++ b/pom.xml @@ -309,7 +309,7 @@ org.codehaus.mojo findbugs-maven-plugin - 2.5.5 + 3.0.4 true true @@ -412,6 +412,39 @@ + + doclint-java8-disable + + [1.8,) + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + -Xdoclint:none + + + + org.apache.maven.plugins + maven-site-plugin + 3.4 + + + + org.apache.maven.plugins + maven-javadoc-plugin + + -Xdoclint:none + + + + + + + + dist From a607dba2112bffcf005fdb8c9b2d4e08391e05ca Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sat, 15 Jul 2017 12:24:19 -0700 Subject: [PATCH 6/7] Issue #316 -- Fixed error where I got rid of src/main/resources and also updated the unit test to use non-deprecated asserts. --- .../DefaultSecurityConfiguration.java | 4 +- .../DefaultSecurityConfigurationTest.java | 193 +++++++++--------- 2 files changed, 101 insertions(+), 96 deletions(-) diff --git a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java index 1d59f2b24..861fced2b 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java @@ -670,8 +670,8 @@ private Properties loadConfigurationFromClasspath(String fileName) throws Illega // try src/main/resources folder if (in == null) { - currentClasspathSearchLocation = "resources/"; - in = currentLoader.getResourceAsStream("resources/" + fileName); + currentClasspathSearchLocation = "src/main/resources/"; + in = currentLoader.getResourceAsStream("src/main/resources/" + fileName); } // now load the properties diff --git a/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java b/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java index 0a7654871..fed8647af 100644 --- a/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java +++ b/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java @@ -1,8 +1,13 @@ package org.owasp.esapi.reference; -import java.util.regex.Pattern; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; -import junit.framework.Assert; +import java.util.regex.Pattern; import org.junit.Test; import org.owasp.esapi.ESAPI; @@ -21,139 +26,139 @@ private DefaultSecurityConfiguration createWithProperty(String key, String val) public void testGetApplicationName() { final String expected = "ESAPI_UnitTests"; DefaultSecurityConfiguration secConf = this.createWithProperty(DefaultSecurityConfiguration.APPLICATION_NAME, expected); - Assert.assertEquals(expected, secConf.getApplicationName()); + assertEquals(expected, secConf.getApplicationName()); } @Test public void testGetLogImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_LOG_IMPLEMENTATION, secConf.getLogImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_LOG_IMPLEMENTATION, secConf.getLogImplementation()); final String expected = "TestLogger"; secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getLogImplementation()); + assertEquals(expected, secConf.getLogImplementation()); } @Test public void testAuthenticationImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_AUTHENTICATION_IMPLEMENTATION, secConf.getAuthenticationImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_AUTHENTICATION_IMPLEMENTATION, secConf.getAuthenticationImplementation()); final String expected = "TestAuthentication"; secConf = this.createWithProperty(DefaultSecurityConfiguration.AUTHENTICATION_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getAuthenticationImplementation()); + assertEquals(expected, secConf.getAuthenticationImplementation()); } @Test public void testEncoderImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_ENCODER_IMPLEMENTATION, secConf.getEncoderImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_ENCODER_IMPLEMENTATION, secConf.getEncoderImplementation()); final String expected = "TestEncoder"; secConf = this.createWithProperty(DefaultSecurityConfiguration.ENCODER_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getEncoderImplementation()); + assertEquals(expected, secConf.getEncoderImplementation()); } @Test public void testAccessControlImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_ACCESS_CONTROL_IMPLEMENTATION, secConf.getAccessControlImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_ACCESS_CONTROL_IMPLEMENTATION, secConf.getAccessControlImplementation()); final String expected = "TestAccessControl"; secConf = this.createWithProperty(DefaultSecurityConfiguration.ACCESS_CONTROL_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getAccessControlImplementation()); + assertEquals(expected, secConf.getAccessControlImplementation()); } @Test public void testEncryptionImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_ENCRYPTION_IMPLEMENTATION, secConf.getEncryptionImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_ENCRYPTION_IMPLEMENTATION, secConf.getEncryptionImplementation()); final String expected = "TestEncryption"; secConf = this.createWithProperty(DefaultSecurityConfiguration.ENCRYPTION_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getEncryptionImplementation()); + assertEquals(expected, secConf.getEncryptionImplementation()); } @Test public void testIntrusionDetectionImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION, secConf.getIntrusionDetectionImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_INTRUSION_DETECTION_IMPLEMENTATION, secConf.getIntrusionDetectionImplementation()); final String expected = "TestIntrusionDetection"; secConf = this.createWithProperty(DefaultSecurityConfiguration.INTRUSION_DETECTION_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getIntrusionDetectionImplementation()); + assertEquals(expected, secConf.getIntrusionDetectionImplementation()); } @Test public void testRandomizerImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_RANDOMIZER_IMPLEMENTATION, secConf.getRandomizerImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_RANDOMIZER_IMPLEMENTATION, secConf.getRandomizerImplementation()); final String expected = "TestRandomizer"; secConf = this.createWithProperty(DefaultSecurityConfiguration.RANDOMIZER_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getRandomizerImplementation()); + assertEquals(expected, secConf.getRandomizerImplementation()); } @Test public void testExecutorImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_EXECUTOR_IMPLEMENTATION, secConf.getExecutorImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_EXECUTOR_IMPLEMENTATION, secConf.getExecutorImplementation()); final String expected = "TestExecutor"; secConf = this.createWithProperty(DefaultSecurityConfiguration.EXECUTOR_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getExecutorImplementation()); + assertEquals(expected, secConf.getExecutorImplementation()); } @Test public void testHTTPUtilitiesImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_HTTP_UTILITIES_IMPLEMENTATION, secConf.getHTTPUtilitiesImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_HTTP_UTILITIES_IMPLEMENTATION, secConf.getHTTPUtilitiesImplementation()); final String expected = "TestHTTPUtilities"; secConf = this.createWithProperty(DefaultSecurityConfiguration.HTTP_UTILITIES_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getHTTPUtilitiesImplementation()); + assertEquals(expected, secConf.getHTTPUtilitiesImplementation()); } @Test public void testValidationImplementation() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_VALIDATOR_IMPLEMENTATION, secConf.getValidationImplementation()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_VALIDATOR_IMPLEMENTATION, secConf.getValidationImplementation()); final String expected = "TestValidation"; secConf = this.createWithProperty(DefaultSecurityConfiguration.VALIDATOR_IMPLEMENTATION, expected); - Assert.assertEquals(expected, secConf.getValidationImplementation()); + assertEquals(expected, secConf.getValidationImplementation()); } @Test public void testGetEncryptionKeyLength() { // test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(128, secConf.getEncryptionKeyLength()); + assertEquals(128, secConf.getEncryptionKeyLength()); final int expected = 256; secConf = this.createWithProperty(DefaultSecurityConfiguration.KEY_LENGTH, String.valueOf(expected)); - Assert.assertEquals(expected, secConf.getEncryptionKeyLength()); + assertEquals(expected, secConf.getEncryptionKeyLength()); } @Test public void testGetKDFPseudoRandomFunction() { // test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("HmacSHA256", secConf.getKDFPseudoRandomFunction()); + assertEquals("HmacSHA256", secConf.getKDFPseudoRandomFunction()); final String expected = "HmacSHA1"; secConf = this.createWithProperty(DefaultSecurityConfiguration.KDF_PRF_ALG, expected); - Assert.assertEquals(expected, secConf.getKDFPseudoRandomFunction()); + assertEquals(expected, secConf.getKDFPseudoRandomFunction()); } @Test @@ -161,10 +166,10 @@ public void testGetMasterSalt() { try { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); secConf.getMasterSalt(); - Assert.fail("Expected Exception not thrown"); + fail("Expected Exception not thrown"); } catch (ConfigurationException ce) { - Assert.assertNotNull(ce.getMessage()); + assertNotNull(ce.getMessage()); } final String salt = "53081"; @@ -172,7 +177,7 @@ public void testGetMasterSalt() { java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.MASTER_SALT, property); DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(properties); - Assert.assertEquals(salt, new String(secConf.getMasterSalt())); + assertEquals(salt, new String(secConf.getMasterSalt())); } @Test @@ -181,21 +186,21 @@ public void testGetAllowedExecutables() { java.util.List allowedExecutables = secConf.getAllowedExecutables(); //is this really what should be returned? what about an empty list? - Assert.assertEquals(1, allowedExecutables.size()); - Assert.assertEquals("", allowedExecutables.get(0)); + assertEquals(1, allowedExecutables.size()); + assertEquals("", allowedExecutables.get(0)); java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.APPROVED_EXECUTABLES, String.valueOf("/bin/bzip2,/bin/diff, /bin/cvs")); secConf = new DefaultSecurityConfiguration(properties); allowedExecutables = secConf.getAllowedExecutables(); - Assert.assertEquals(3, allowedExecutables.size()); - Assert.assertEquals("/bin/bzip2", allowedExecutables.get(0)); - Assert.assertEquals("/bin/diff", allowedExecutables.get(1)); + assertEquals(3, allowedExecutables.size()); + assertEquals("/bin/bzip2", allowedExecutables.get(0)); + assertEquals("/bin/diff", allowedExecutables.get(1)); //this seems less than optimal, maybe each value should have a trim() done to it //at least we know that this behavior exists, the property should'nt have spaces between values - Assert.assertEquals(" /bin/cvs", allowedExecutables.get(2)); + assertEquals(" /bin/cvs", allowedExecutables.get(2)); } @Test @@ -203,189 +208,189 @@ public void testGetAllowedFileExtensions() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); java.util.List allowedFileExtensions = secConf.getAllowedFileExtensions(); - Assert.assertFalse(allowedFileExtensions.isEmpty()); + assertFalse(allowedFileExtensions.isEmpty()); java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.APPROVED_UPLOAD_EXTENSIONS, String.valueOf(".txt,.xml,.html,.png")); secConf = new DefaultSecurityConfiguration(properties); allowedFileExtensions = secConf.getAllowedFileExtensions(); - Assert.assertEquals(4, allowedFileExtensions.size()); - Assert.assertEquals(".html", allowedFileExtensions.get(2)); + assertEquals(4, allowedFileExtensions.size()); + assertEquals(".html", allowedFileExtensions.get(2)); } @Test public void testGetAllowedFileUploadSize() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); //assert that the default is of some reasonable size - Assert.assertTrue(secConf.getAllowedFileUploadSize() > (1024 * 100)); + assertTrue(secConf.getAllowedFileUploadSize() > (1024 * 100)); final int expected = (1024 * 1000); secConf = this.createWithProperty(DefaultSecurityConfiguration.MAX_UPLOAD_FILE_BYTES, String.valueOf(expected)); - Assert.assertEquals(expected, secConf.getAllowedFileUploadSize()); + assertEquals(expected, secConf.getAllowedFileUploadSize()); } @Test public void testGetParameterNames() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("password", secConf.getPasswordParameterName()); - Assert.assertEquals("username", secConf.getUsernameParameterName()); + assertEquals("password", secConf.getPasswordParameterName()); + assertEquals("username", secConf.getUsernameParameterName()); java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.PASSWORD_PARAMETER_NAME, "j_password"); properties.setProperty(DefaultSecurityConfiguration.USERNAME_PARAMETER_NAME, "j_username"); secConf = new DefaultSecurityConfiguration(properties); - Assert.assertEquals("j_password", secConf.getPasswordParameterName()); - Assert.assertEquals("j_username", secConf.getUsernameParameterName()); + assertEquals("j_password", secConf.getPasswordParameterName()); + assertEquals("j_username", secConf.getUsernameParameterName()); } @Test public void testGetEncryptionAlgorithm() { //test the default DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("AES", secConf.getEncryptionAlgorithm()); + assertEquals("AES", secConf.getEncryptionAlgorithm()); secConf = this.createWithProperty(DefaultSecurityConfiguration.ENCRYPTION_ALGORITHM, "3DES"); - Assert.assertEquals("3DES", secConf.getEncryptionAlgorithm()); + assertEquals("3DES", secConf.getEncryptionAlgorithm()); } @Test public void testGetCipherXProperties() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("AES/CBC/PKCS5Padding", secConf.getCipherTransformation()); - //Assert.assertEquals("AES/CBC/PKCS5Padding", secConf.getC); + assertEquals("AES/CBC/PKCS5Padding", secConf.getCipherTransformation()); + //assertEquals("AES/CBC/PKCS5Padding", secConf.getC); java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.CIPHER_TRANSFORMATION_IMPLEMENTATION, "Blowfish/CFB/ISO10126Padding"); secConf = new DefaultSecurityConfiguration(properties); - Assert.assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); + assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); secConf.setCipherTransformation("DESede/PCBC/PKCS5Padding"); - Assert.assertEquals("DESede/PCBC/PKCS5Padding", secConf.getCipherTransformation()); + assertEquals("DESede/PCBC/PKCS5Padding", secConf.getCipherTransformation()); secConf.setCipherTransformation(null);//sets it back to default - Assert.assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); + assertEquals("Blowfish/CFB/ISO10126Padding", secConf.getCipherTransformation()); } @Test public void testIV() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("random", secConf.getIVType()); + assertEquals("random", secConf.getIVType()); try { secConf.getFixedIV(); - Assert.fail(); + fail(); } catch (ConfigurationException ce) { - Assert.assertNotNull(ce.getMessage()); + assertNotNull(ce.getMessage()); } java.util.Properties properties = new java.util.Properties(); properties.setProperty(DefaultSecurityConfiguration.IV_TYPE, "fixed"); properties.setProperty(DefaultSecurityConfiguration.FIXED_IV, "ivValue"); secConf = new DefaultSecurityConfiguration(properties); - Assert.assertEquals("fixed", secConf.getIVType()); - Assert.assertEquals("ivValue", secConf.getFixedIV()); + assertEquals("fixed", secConf.getIVType()); + assertEquals("ivValue", secConf.getFixedIV()); properties.setProperty(DefaultSecurityConfiguration.IV_TYPE, "illegal"); secConf = new DefaultSecurityConfiguration(properties); try { secConf.getIVType(); - Assert.fail(); + fail(); } catch (ConfigurationException ce) { - Assert.assertNotNull(ce.getMessage()); + assertNotNull(ce.getMessage()); } try { secConf.getFixedIV(); - Assert.fail(); + fail(); } catch (ConfigurationException ce) { - Assert.assertNotNull(ce.getMessage()); + assertNotNull(ce.getMessage()); } } @Test public void testGetAllowMultipleEncoding() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertFalse(secConf.getAllowMultipleEncoding()); + assertFalse(secConf.getAllowMultipleEncoding()); secConf = this.createWithProperty(DefaultSecurityConfiguration.ALLOW_MULTIPLE_ENCODING, "yes"); - Assert.assertTrue(secConf.getAllowMultipleEncoding()); + assertTrue(secConf.getAllowMultipleEncoding()); secConf = this.createWithProperty(DefaultSecurityConfiguration.ALLOW_MULTIPLE_ENCODING, "true"); - Assert.assertTrue(secConf.getAllowMultipleEncoding()); + assertTrue(secConf.getAllowMultipleEncoding()); secConf = this.createWithProperty(DefaultSecurityConfiguration.ALLOW_MULTIPLE_ENCODING, "no"); - Assert.assertFalse(secConf.getAllowMultipleEncoding()); + assertFalse(secConf.getAllowMultipleEncoding()); } @Test public void testGetDefaultCanonicalizationCodecs() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertFalse(secConf.getDefaultCanonicalizationCodecs().isEmpty()); + assertFalse(secConf.getDefaultCanonicalizationCodecs().isEmpty()); String property = "org.owasp.esapi.codecs.TestCodec1,org.owasp.esapi.codecs.TestCodec2"; secConf = this.createWithProperty(DefaultSecurityConfiguration.CANONICALIZATION_CODECS, property); - Assert.assertTrue(secConf.getDefaultCanonicalizationCodecs().contains("org.owasp.esapi.codecs.TestCodec1")); + assertTrue(secConf.getDefaultCanonicalizationCodecs().contains("org.owasp.esapi.codecs.TestCodec1")); } @Test public void testGetDisableIntrusionDetection() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertFalse(secConf.getDisableIntrusionDetection()); + assertFalse(secConf.getDisableIntrusionDetection()); secConf = this.createWithProperty(DefaultSecurityConfiguration.DISABLE_INTRUSION_DETECTION, "TRUE"); - Assert.assertTrue(secConf.getDisableIntrusionDetection()); + assertTrue(secConf.getDisableIntrusionDetection()); secConf = this.createWithProperty(DefaultSecurityConfiguration.DISABLE_INTRUSION_DETECTION, "true"); - Assert.assertTrue(secConf.getDisableIntrusionDetection()); + assertTrue(secConf.getDisableIntrusionDetection()); secConf = this.createWithProperty(DefaultSecurityConfiguration.DISABLE_INTRUSION_DETECTION, "false"); - Assert.assertFalse(secConf.getDisableIntrusionDetection()); + assertFalse(secConf.getDisableIntrusionDetection()); } @Test public void testGetLogLevel() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(Logger.WARNING, secConf.getLogLevel()); + assertEquals(Logger.WARNING, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "trace"); - Assert.assertEquals(Logger.TRACE, secConf.getLogLevel()); + assertEquals(Logger.TRACE, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "Off"); - Assert.assertEquals(Logger.OFF, secConf.getLogLevel()); + assertEquals(Logger.OFF, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "all"); - Assert.assertEquals(Logger.ALL, secConf.getLogLevel()); + assertEquals(Logger.ALL, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "DEBUG"); - Assert.assertEquals(Logger.DEBUG, secConf.getLogLevel()); + assertEquals(Logger.DEBUG, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "info"); - Assert.assertEquals(Logger.INFO, secConf.getLogLevel()); + assertEquals(Logger.INFO, secConf.getLogLevel()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_LEVEL, "ERROR"); - Assert.assertEquals(Logger.ERROR, secConf.getLogLevel()); + assertEquals(Logger.ERROR, secConf.getLogLevel()); } @Test public void testGetLogFileName() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals("ESAPI_logging_file", secConf.getLogFileName()); + assertEquals("ESAPI_logging_file", secConf.getLogFileName()); secConf = this.createWithProperty(DefaultSecurityConfiguration.LOG_FILE_NAME, "log.txt"); - Assert.assertEquals("log.txt", secConf.getLogFileName()); + assertEquals("log.txt", secConf.getLogFileName()); } @Test public void testGetMaxLogFileSize() { DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration(new java.util.Properties()); - Assert.assertEquals(DefaultSecurityConfiguration.DEFAULT_MAX_LOG_FILE_SIZE, secConf.getMaxLogFileSize()); + assertEquals(DefaultSecurityConfiguration.DEFAULT_MAX_LOG_FILE_SIZE, secConf.getMaxLogFileSize()); int maxLogSize = (1024 * 1000); secConf = this.createWithProperty(DefaultSecurityConfiguration.MAX_LOG_FILE_SIZE, String.valueOf(maxLogSize)); - Assert.assertEquals(maxLogSize, secConf.getMaxLogFileSize()); + assertEquals(maxLogSize, secConf.getMaxLogFileSize()); } private String patternOrNull(Pattern p){ @@ -395,24 +400,24 @@ private String patternOrNull(Pattern p){ @Test public void testValidationsPropertiesFileOptions(){ DefaultSecurityConfiguration secConf = new DefaultSecurityConfiguration("ESAPI-SingleValidatorFileChecker.properties"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); - Assert.assertNull(secConf.getValidationPattern("Test2")); - Assert.assertNull(secConf.getValidationPattern("TestC")); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertNull(secConf.getValidationPattern("Test2")); + assertNull(secConf.getValidationPattern("TestC")); secConf = new DefaultSecurityConfiguration("ESAPI-DualValidatorFileChecker.properties"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); - Assert.assertNull(secConf.getValidationPattern("TestC")); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); + assertNull(secConf.getValidationPattern("TestC")); secConf = new DefaultSecurityConfiguration("ESAPI-CommaValidatorFileChecker.properties"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); - Assert.assertNull(secConf.getValidationPattern("Test1")); - Assert.assertNull(secConf.getValidationPattern("Test2")); + assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); + assertNull(secConf.getValidationPattern("Test1")); + assertNull(secConf.getValidationPattern("Test2")); secConf = new DefaultSecurityConfiguration("ESAPI-QuotedValidatorFileChecker.properties"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); - Assert.assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test1")), "ValueFromFile1"); + assertEquals(patternOrNull(secConf.getValidationPattern("Test2")), "ValueFromFile2"); + assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); } } From 283753841aa927eb535ddfddb5c899fd7721d39d Mon Sep 17 00:00:00 2001 From: Matt Seil Date: Sat, 15 Jul 2017 19:21:21 -0700 Subject: [PATCH 7/7] Issue #316 -- Added unit test to ensure search directory changes are adequately updated in the future, and upped JVM compliance level to 1.7 since we already decided that 1.6 is more than defunct. --- .../DefaultSecurityConfiguration.java | 34 +++++++++++++++---- .../DefaultSecurityConfigurationTest.java | 17 ++++++++++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java index 861fced2b..a1f551e7d 100644 --- a/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java +++ b/src/main/java/org/owasp/esapi/reference/DefaultSecurityConfiguration.java @@ -642,36 +642,36 @@ private Properties loadConfigurationFromClasspath(String fileName) throws Illega try { // try root String currentClasspathSearchLocation = "/ (root)"; - in = loaders[i].getResourceAsStream(fileName); + in = loaders[i].getResourceAsStream(DefaultSearchPath.ROOT.toString()); // try resourceDirectory folder if (in == null) { currentClasspathSearchLocation = resourceDirectory + "/"; - in = currentLoader.getResourceAsStream(resourceDirectory + "/" + fileName); + in = currentLoader.getResourceAsStream(DefaultSearchPath.RESOURCE_DIRECTORY + fileName); } // try .esapi folder. Look here first for backward compatibility. if (in == null) { currentClasspathSearchLocation = ".esapi/"; - in = currentLoader.getResourceAsStream(".esapi/" + fileName); + in = currentLoader.getResourceAsStream(DefaultSearchPath.DOT_ESAPI + fileName); } // try esapi folder (new directory) if (in == null) { currentClasspathSearchLocation = "esapi/"; - in = currentLoader.getResourceAsStream("esapi/" + fileName); + in = currentLoader.getResourceAsStream(DefaultSearchPath.ESAPI + fileName); } // try resources folder if (in == null) { currentClasspathSearchLocation = "resources/"; - in = currentLoader.getResourceAsStream("resources/" + fileName); + in = currentLoader.getResourceAsStream(DefaultSearchPath.RESOURCES + fileName); } // try src/main/resources folder if (in == null) { currentClasspathSearchLocation = "src/main/resources/"; - in = currentLoader.getResourceAsStream("src/main/resources/" + fileName); + in = currentLoader.getResourceAsStream(DefaultSearchPath.SRC_MAIN_RESOURCES + fileName); } // now load the properties @@ -1347,4 +1347,26 @@ protected boolean shouldPrintProperties() { protected Properties getESAPIProperties() { return properties; } + + public enum DefaultSearchPath { + + RESOURCE_DIRECTORY("resourceDirectory/"), + SRC_MAIN_RESOURCES("src/main/resources/"), + ROOT("/"), + DOT_ESAPI(".esapi/"), + ESAPI("esapi/"), + RESOURCES("resources/"); + + private final String path; + + + + private DefaultSearchPath(String s){ + this.path = s; + } + + public String value(){ + return path; + } + } } diff --git a/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java b/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java index fed8647af..5171da6a5 100644 --- a/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java +++ b/src/test/java/org/owasp/esapi/reference/DefaultSecurityConfigurationTest.java @@ -13,6 +13,7 @@ import org.owasp.esapi.ESAPI; import org.owasp.esapi.Logger; import org.owasp.esapi.errors.ConfigurationException; +import org.owasp.esapi.reference.DefaultSecurityConfiguration.DefaultSearchPath; public class DefaultSecurityConfigurationTest { @@ -420,4 +421,20 @@ public void testValidationsPropertiesFileOptions(){ assertEquals(patternOrNull(secConf.getValidationPattern("TestC")), "ValueFromCommaFile"); } + @Test + public void DefaultSearchPathTest(){ + assertEquals("/", DefaultSearchPath.ROOT.value()); + assertEquals("resourceDirectory/", DefaultSearchPath.RESOURCE_DIRECTORY.value()); + assertEquals(".esapi/", DefaultSearchPath.DOT_ESAPI.value()); + assertEquals("esapi/", DefaultSearchPath.ESAPI.value()); + assertEquals("resources/", DefaultSearchPath.RESOURCES.value()); + assertEquals("src/main/resources/", DefaultSearchPath.SRC_MAIN_RESOURCES.value()); + } + + @Test + public void DefaultSearchPathEnumChanges(){ + int expected = 6; + int testValue = DefaultSearchPath.values().length; + assertEquals(expected, testValue); + } }