AF
HomeTagSubmit NotesAsk AnythingLoginSubscribe Us
AF
1. Feel Free to ask and submit anything on Anyforum.in and get satisfactory answer
2. Registration is not compulsory, you can directly login via google or facebook
3. Our Experts are looking for yours ?.



java-security: How to resolve LDAP Injection Issue in java?

Hi,
I have written code for LDAP authentication,it works fine but when we run it in security tool i am facing issue like "The method getUserAttrs() invokes a dynamically generated LDAP filter with unvalidated input" message and saying that its LDAP Injection issue.Please help how can i correct my code.

Code snippet :
private void getUserAttrsNoAuth(HttpServletRequest request,
LDAPConnection ld, HttpSession hs) throws LDAPException {
String uid = getUid(request);
String LDAPUserDN = "uid=" + uid + "," + LDAPPeopleBase;


Hashtable ldapProfile = new Hashtable();

try {
LDAPEntry entry = ld.read(LDAPUserDN);
LDAPAttributeSet attSet = entry.getAttributeSet();
Enumeration enumAttrs = attSet.getAttributes();
while (enumAttrs.hasMoreElements()) {
LDAPAttribute anAttr = (LDAPAttribute) enumAttrs.nextElement();
String attrName = anAttr.getName();
String[] vals = anAttr.getStringValueArray();

if (attrName != null
&& !attrName.equalsIgnoreCase("objectclass")
&& !attrName.equalsIgnoreCase("ugroups")) {
ldapProfile.put(attrName, vals);
}
}

hs.setAttribute("ldapUserProfile", ldapProfile);
} catch (LDAPException le) {
getServletContext().log("LDAPException in Login.getUserAttrs(): ",
le);
} catch (Throwable t) {
getServletContext().log("Exception: ", t);

}
}

java x 211
security x 9
Posted On : 2015-03-31 15:29:20.0
profile Adarsh S - anyforum.in Adarsh S
3100
up-rate
3
down-rate

Answers


To prevent LDAP injection, it is always recommended to enforce stringent input validation functions before processing data for LDAP persistence. In the case of an application that relies on client-side data validation, it becomes important to re-verify and validate them on the server side as well. The data validation should verify the input in terms of required LDAP attributes and its known data type, locale, meta characters, format, length, legal values, etc. To prevent issues with insecure LDAP configuration and access control policies, it is often recommended to verify LDAP configuration and enforce principle of least privilege and role-based access control (RBAC) policies.

LDAP injection is also very similar to the SQL injection vulnerability with relational databases (RDBMS). Using RDBMS is not a viable alternative to LDAP. LDAP is a directory protocol commonly used to represent organizational structure and its users as a hierarchy of objects. The hierarchical representation of LDAP information is one of the biggest advantages over RDBMS that helps implement faster lookup, query and delegation of responsibilities based on an organizational structure, sub-organization, location, users, groups, roles and access-control policies.

The examples below present Java methods that could be used to perform this escaping:
------------------------------------------------------------------------------------------------------------------------
public String escapeDN (String name) {
//From RFC 2253 and the / character for JNDI
final char[] META_CHARS = {´+´, ´"´, ´<´, ´>´, ´;´, ´/´};
String escapedStr = new String(name);
//Backslash is both a Java and an LDAP escape character, so escape it first
escapedStr = escapedStr.replaceAll("\\\\\\\\","\\\\\\\\");
//Positional characters - see RFC 2253
escapedStr = escapedStr.replaceAll("\^#","\\\\\\\\#");
escapedStr = escapedStr.replaceAll("\^ | $","\\\\\\\\ ");
for (int i=0;i < META_CHARS.length;i++) {
escapedStr = escapedStr.replaceAll("\\\\"+META_CHARS[i],"\\\\\\\\" + META_CHARS[i]);
}
return escapedStr;
}
Note, that the backslash character is a Java String literal and a regular expression escape character.
public String escapeSearchFilter (String filter) {
//From RFC 2254
String escapedStr = new String(filter);
escapedStr = escapedStr.replaceAll("\\\\\\\\","\\\\\\\\5c");
escapedStr = escapedStr.replaceAll("\\\\\*","\\\\\\\\2a");
escapedStr = escapedStr.replaceAll("\\\\(","\\\\\\\\28");
escapedStr = escapedStr.replaceAll("\\\\)","\\\\\\\\29");
escapedStr = escapedStr.replaceAll("\\\\"+Character.toString(´\\u0000´), "\\\\\\\\00");
return escapedStr;
}


Optimized version of the previous code (about 8 times faster for escaping LDAP search and 13 times for escapeDN on my PC). Further ,

public static String escapeDN(String name) {
StringBuffer sb = new StringBuffer(); // If using JDK >= 1.5 consider using 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++) {
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();
}
public static final String escapeLDAPSearchFilter(String filter) {
StringBuffer sb = new StringBuffer(); // If using JDK >= 1.5 consider using StringBuilder
for (int i = 0; i < filter.length(); i++) {
char curChar = filter.charAt(i);
switch (curChar) {
case ´\\\\´:
sb.append("\\\\5c");
break;
case ´\*´:
sb.append("\\\\2a");
break;
case ´(´:
sb.append("\\\\28");
break;
case ´)´:
sb.append("\\\\29");
break;
case ´\\u0000´:
sb.append("\\\\00");
break;
default:
sb.append(curChar);
}
}
return sb.toString();
}


Test class for assertion :
-----------------------------------------------------------
//escapeDN
assertEquals("No special characters to escape", "Hello?", escapeDN("Hello?"));
assertEquals("leading #", "\\\\# Hello?", escapeDN("# Hello?"));
assertEquals("leading space", "\\\\ Hello?", escapeDN(" Hello?"));
assertEquals("trailing space", "Hello?\\\\ ", escapeDN("Hello? "));
assertEquals("only 3 spaces", "\\\\ \\\\ ", escapeDN(" "));
assertEquals("Christmas Tree DN", "\\\\ Hello\\\\\\\\ \\\\+ \\\\, \\\\\\"World\\\\\\" \\\\;\\\\ ", Test.escapeDN(" Hello\\\\ + , \\"World\\" ; "));
Special case :

assertEquals("No special characters to escape", "Hi This is a test #??", SecTool.escapeLDAPSearchFilter("Hi This is a test #??"));
assertEquals("LDAP Christams Tree", "Hi \\\\28This\\\\29 = is \\\\2a a \\\\5c test # ? ? ?", SecTool.escapeLDAPSearchFilter("Hi (This) = is \* a \\\\ test # ? ? ?"));


How do you fix the LDAP Injection vulnerability?
=======================================================
Input validation!!! The underlying code needs to verify the correct input using a white list. If the input is verified against a white list using a regular expression then the input could be rejected and the end user would need to input the correct data. Don´t let a malicious user mis-use your application. Verify that the input is validated and that there is not the ability to inject additional ldap information, especially the () | \* characters.

Posted On : 2015-04-01 02:26:40
Satisfied : 2 Yes  0 No
profile Rishi Kumar - anyforum.in Rishi Kumar
523188247637
Reply This Thread
up-rate
4
down-rate



Post Answer
Please Login First to Post Answer: Login login with facebook - anyforum.in