Commit bac5e9c2 authored by cdanger's avatar cdanger

- upgraded parent: 4.1.0 -> 4.1.0 (upgrades owasp dep check mvn plugin

version: 1.4.4 -> 1.4.4.1)
- Added find-sec-bugs exclusion for CRLF_INJECTION_LOGS (assumed handled
by logback configuration)
parent 32ed5a07
......@@ -5,10 +5,14 @@
put here to instruct Findbugs to ignore them.
-->
<FindBugsFilter>
<Match>
<!-- CRLF injection in logs is considered fixed in the logger configuration, e.g. logback.xml.
More info: https://github.com/find-sec-bugs/find-sec-bugs/issues/240
-->
<Bug pattern="CRLF_INJECTION_LOGS" />
</Match>
<Match>
<Class name="org.ow2.authzforce.core.pdp.api.value.XPathValue" />
<Bug pattern="DESERIALIZATION_GADGET" />
</Match>
</FindBugsFilter>
\ No newline at end of file
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-parent</artifactId>
<version>4.1.0</version>
<version>4.1.1</version>
</parent>
<artifactId>authzforce-ce-core-pdp-api</artifactId>
<version>8.1.1-SNAPSHOT</version>
......
/**
* Copyright (C) 2012-2016 Thales Services SAS.
*
* This file is part of AuthZForce CE.
*
* AuthZForce CE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AuthZForce CE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AuthZForce CE. If not, see <http://www.gnu.org/licenses/>.
*/
package org.ow2.authzforce.core.pdp.api;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Utilities for String validation, sanitizing, transformation, etc.
*
*/
public final class StringUtils
{
private StringUtils()
{
}
/**
* Replace CRLF characters with "&lt;NEWLINE&gt"; in {@code input.toString()} to prevent CRLF injection
*
* @param input
* input object
* @return encoded string
*/
public static String sanitizeForLogging(final Object input)
{
try
{
return URLEncoder.encode(input.toString(), "UTF-8");
}
catch (final UnsupportedEncodingException e)
{
// UTF-8 is supported
return null;
}
}
}
......@@ -303,7 +303,7 @@ public final class XMLUtils
final String duplicate = nsPrefixUriMap.putIfAbsent(prefix, uri);
if (duplicate != null)
{
throw new RuntimeException("Duplicate namespace prefix '" + prefix + "'");
throw new RuntimeException("Duplicate declaration of namespace prefix '" + prefix + "' (empty string refers to default namespace)");
}
super.startPrefixMapping(prefix, uri);
......
......@@ -21,7 +21,6 @@ package org.ow2.authzforce.core.pdp.api.expression;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.StatusHelper;
import org.ow2.authzforce.core.pdp.api.StringUtils;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
import org.ow2.authzforce.core.pdp.api.value.Value;
......@@ -64,8 +63,7 @@ public final class Expressions
final Value val = arg.evaluate(context);
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("eval( arg = <{}>, <context>, expectedType = <{}> ) -> <{}>", StringUtils.sanitizeForLogging(arg), StringUtils.sanitizeForLogging(returnType),
StringUtils.sanitizeForLogging(val));
LOGGER.debug("eval( arg = <{}>, <context>, expectedType = <{}> ) -> <{}>", arg, returnType, val);
}
if (val == null)
......@@ -102,7 +100,7 @@ public final class Expressions
/*
* Findsecbugs: prevent CRLF log injection
*/
LOGGER.debug("evalPrimitive( arg = <{}>, <context>) -> <{}>", StringUtils.sanitizeForLogging(arg), StringUtils.sanitizeForLogging(val));
LOGGER.debug("evalPrimitive( arg = <{}>, <context>) -> <{}>", arg, val);
}
if (val == null)
......
......@@ -56,8 +56,8 @@ public final class IPAddressValue extends SimpleValue<String>
final NetworkPortRange range;
// start out by seeing where the delimiters are
final int maskPos = val.indexOf("/");
final int rangePos = val.indexOf(":");
final int maskPos = val.indexOf('/');
final int rangePos = val.indexOf(':');
// now check to see which components we have
if (maskPos == rangePos)
......
......@@ -18,8 +18,7 @@
*/
package org.ow2.authzforce.core.pdp.api.value;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.security.auth.x500.X500Principal;
/**
* Representation of an X.500 Directory Name.
......@@ -39,56 +38,10 @@ public final class X500NameValue extends SimpleValue<String>
*/
public static final String TYPE_URI = "urn:oasis:names:tc:xacml:1.0:data-type:x500Name";
private final LdapName ldapName;
private final X500Principal x500Name;
private transient volatile int hashCode = 0; // Effective Java - Item 9
private static String escapeDN(final String name)
{
assert name != null;
final StringBuilder sb = new StringBuilder();
if (name.length() > 0 && (name.charAt(0) == ' ' || name.charAt(0) == '#'))
{
sb.append('\\'); // add the leading backslash if needed
}
for (int i = 0; i < name.length(); i++)
{
final char curChar = name.charAt(i);
switch (curChar)
{
case '\\':
sb.append("\\\\");
break;
case ',':
sb.append("\\,");
break;
case '+':
sb.append("\\+");
break;
case '"':
sb.append("\\\"");
break;
case '<':
sb.append("\\<");
break;
case '>':
sb.append("\\>");
break;
case ';':
sb.append("\\;");
break;
default:
sb.append(curChar);
}
}
if (name.length() > 1 && name.charAt(name.length() - 1) == ' ')
{
sb.insert(sb.length() - 1, '\\'); // add the trailing backslash if needed
}
return sb.toString();
}
/**
* Returns a new <code>X500NameAttributeValue</code> that represents the X500 Name value indicated by the string provided.
*
......@@ -102,11 +55,11 @@ public final class X500NameValue extends SimpleValue<String>
super(TYPE_URI, value);
try
{
this.ldapName = new LdapName(escapeDN(value));
this.x500Name = new X500Principal(value);
}
catch (final InvalidNameException e)
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException("Invalid value (X.500 Name) for datatype: " + TYPE_URI, e);
throw new IllegalArgumentException("Invalid value (X.500 Distinguished Name) for datatype: " + TYPE_URI, e);
}
}
......@@ -119,12 +72,50 @@ public final class X500NameValue extends SimpleValue<String>
*/
public boolean match(final X500NameValue other)
{
final String otherCanonicalName = other.x500Name.getName(X500Principal.CANONICAL);
final String thisCanonicalName = this.x500Name.getName(X500Principal.CANONICAL);
final boolean isStringSuffix = otherCanonicalName.endsWith(thisCanonicalName);
if (!isStringSuffix)
{
return false;
}
/*
* Not enough to be a String suffix, thisCanonicalName must be a terminal sequence of RDNs of otherCanonicalName
*/
final int otherNameLen = otherCanonicalName.length();
final int thisNameLen = thisCanonicalName.length();
if (otherNameLen == thisNameLen)
{
// same string
return true;
}
// otherNameLen >= thisNameLen +1
/*
* Not the same length so otherCanonicalName must be: '...x,thisCanonicalName' where x is not an escape string for ','. Index otherCanonicalName.length() - (thisCanonicalName.length() + 1)
* corresponds to ',' in otherCanonicalName
*/
final int indexBeforeSuffix = otherNameLen - (thisNameLen + 1);
if (otherCanonicalName.charAt(indexBeforeSuffix) != ',')
{
return false;
}
/*
* We have a comma before this name.
*/
if (otherNameLen <= thisNameLen + 1)
{
// nothing else before the comma
return true;
}
// otherNameLen >= thisNameLen +2
/*
* As the Javadoc says, "The right most RDN is at index 0, and the left most RDN is at index n-1. For example, the distinguished name: " CN=Steve Kille, O=Isode Limited, C=GB
* " is numbered in the following sequence ranging from 0 to 2: {C=GB, O=Isode Limited, CN=Steve Kille}" Therefore RDNs are in reverse order of declaration in the string representation, so to
* check the match against a terminal sequence of RDNs, we don't use the endsWith() function, but startsWith()
* We have another character before the comma. Make sure this is not a backslash to escape the comma.
*/
return other.ldapName.startsWith(this.ldapName.getRdns());
return otherCanonicalName.charAt(indexBeforeSuffix - 1) != '\\';
}
/** {@inheritDoc} */
......@@ -133,7 +124,7 @@ public final class X500NameValue extends SimpleValue<String>
{
if (hashCode == 0)
{
hashCode = this.ldapName.hashCode();
hashCode = this.x500Name.hashCode();
}
return hashCode;
......@@ -158,7 +149,7 @@ public final class X500NameValue extends SimpleValue<String>
/*
* This equals() has the same effect as the algorithm described in the spec
*/
return ldapName.equals(other.ldapName);
return x500Name.equals(other.x500Name);
}
/** {@inheritDoc} */
......@@ -169,11 +160,11 @@ public final class X500NameValue extends SimpleValue<String>
}
// For quick testing
// public static void main(String[] args) throws InvalidNameException
// public static void main(final String[] args) throws InvalidNameException
// {
// // System.out.println(new LdapName("cn=John Smith, o=Medico Corp, c=US").equals(new
// // LdapName("cn= John Smith,o =Medico Corp, C=US")));
// // System.out.println(new LdapName("ou=test+cn=bob,dc =example,dc=com"));
// System.out.println(new LdapName("cn=John Smith, o=Medico Corp, c=US").equals(new
// LdapName("cn= John Smith,o =Medico Corp, C=US")));
// System.out.println(new LdapName(escapeDN("ou=test+cn=bob,dc =example,dc=com")));
// System.out.println(new LdapName("cn=John Smith, o=Medico Corp, c=US").endsWith(new
// LdapName("o=Medico Corp, c=US").getRdns()));
// }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment