[Fix] encode user provider input for LDAP query
Remove OWASP ESAPI as it has too many dependencies
This commit is contained in:
parent
004c6775c0
commit
3c2aac3b9e
56
pom.xml
56
pom.xml
|
@ -253,62 +253,6 @@
|
|||
<artifactId>commons-csv</artifactId>
|
||||
<version>${csv.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.encoder</groupId>
|
||||
<artifactId>encoder-esapi</artifactId>
|
||||
<version>${owasp-encoder-esapi.version}</version>
|
||||
<!-- we basically exclude all its dependencies, as the code we need has no transitive dependencies -->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>xom</groupId>
|
||||
<artifactId>xom</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-configuration</groupId>
|
||||
<artifactId>commons-configuration</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<artifactId>commons-fileupload</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.apache-extras.beanshell</groupId>
|
||||
<artifactId>bsh</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.owasp.antisamy</groupId>
|
||||
<artifactId>antisamy</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>xml-apis</groupId>
|
||||
<artifactId>xml-apis</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.github.spotbugs</groupId>
|
||||
<artifactId>spotbugs-annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Database -->
|
||||
<dependency>
|
||||
|
|
|
@ -44,10 +44,6 @@
|
|||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.owasp.encoder</groupId>
|
||||
<artifactId>encoder-esapi</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
|
|
|
@ -6,7 +6,6 @@ import li.strolch.privilege.model.internal.User;
|
|||
import li.strolch.privilege.model.internal.UserHistory;
|
||||
import li.strolch.privilege.policy.PrivilegePolicy;
|
||||
import li.strolch.utils.helper.ExceptionHelper;
|
||||
import org.owasp.esapi.reference.DefaultEncoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -21,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static li.strolch.utils.LdapHelper.encodeForLDAP;
|
||||
import static li.strolch.utils.helper.StringHelper.trimOrEmpty;
|
||||
|
||||
public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
||||
|
@ -69,8 +69,7 @@ public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
|||
@Override
|
||||
protected User checkCredentialsAndUserState(String username, char[] password) throws AccessDeniedException {
|
||||
// escape the user provider username
|
||||
org.owasp.esapi.Encoder encoder = DefaultEncoder.getInstance();
|
||||
String safeUsername = encoder.encodeForLDAP(username);
|
||||
String safeUsername = encodeForLDAP(username, true);
|
||||
|
||||
// first see if this is a local user
|
||||
User internalUser = this.persistenceHandler.getUser(safeUsername);
|
||||
|
@ -83,7 +82,7 @@ public abstract class BaseLdapPrivilegeHandler extends DefaultPrivilegeHandler {
|
|||
} else {
|
||||
if (!this.domainPrefix.isEmpty() && username.startsWith(this.domainPrefix)) {
|
||||
logger.warn("Trimming domain from given username, to first search in sAMAccountName");
|
||||
safeUsername = encoder.encodeForLDAP(username.substring(this.domainPrefix.length()));
|
||||
safeUsername = encodeForLDAP(username.substring(this.domainPrefix.length()), true);
|
||||
}
|
||||
userPrincipalName = safeUsername + "@" + this.domain;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package li.strolch.utils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Copied from <a
|
||||
* href="https://github.com/ESAPI/esapi-java-legacy/blob/develop/src/main/java/org/owasp/esapi/reference/DefaultEncoder.java#L298">OWASP
|
||||
* ESAPI DefaultEncoder</a>
|
||||
*/
|
||||
public class LdapHelper {
|
||||
|
||||
public static String encodeForLDAP(String input, boolean encodeWildcards) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
// should be replaced with LDAP codec
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// According to Microsoft docs [1,2], the forward slash ('/') MUST be escaped.
|
||||
// According to RFC 4515 Section 3 [3], the forward slash (and other characters) MAY be escaped.
|
||||
// Since Microsoft is a MUST, escape forward slash for all implementations. Also see discussion at [4].
|
||||
// Characters above 0x7F are converted to UTF-8 and then hex encoded in the default case.
|
||||
// [1] https://docs.microsoft.com/en-us/windows/win32/adsi/search-filter-syntax
|
||||
// [2] https://social.technet.microsoft.com/wiki/contents/articles/5312.active-directory-characters-to-escape.aspx
|
||||
// [3] https://tools.ietf.org/search/rfc4515#section-3
|
||||
// [4] https://lists.openldap.org/hyperkitty/list/openldap-technical@openldap.org/thread/3QPDDLO356ONSJM3JUKD7NMPOOIKIQ5T/
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
switch (c) {
|
||||
case '\\':
|
||||
sb.append("\\5c");
|
||||
break;
|
||||
case '/':
|
||||
sb.append("\\2f");
|
||||
break;
|
||||
case '*':
|
||||
if (encodeWildcards) {
|
||||
sb.append("\\2a");
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
break;
|
||||
case '(':
|
||||
sb.append("\\28");
|
||||
break;
|
||||
case ')':
|
||||
sb.append("\\29");
|
||||
break;
|
||||
case '\0':
|
||||
sb.append("\\00");
|
||||
break;
|
||||
default:
|
||||
if (c >= 0x80) {
|
||||
final byte[] u = String.valueOf(c).getBytes(StandardCharsets.UTF_8);
|
||||
for (byte b : u) {
|
||||
sb.append(String.format("\\%02x", b));
|
||||
}
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue