Ldap Injection with Mutual Tls
How Ldap Injection Manifests in Mutual Tls
LDAP injection vulnerabilities in Mutual TLS environments exploit the trust established between client and server certificates to bypass authentication controls. When an application uses LDAP for user authentication over Mutual TLS connections, attackers can manipulate LDAP queries to escalate privileges or access unauthorized data.
The most common manifestation occurs in certificate-based authentication workflows. Consider a Java application using Spring Security with LDAP authentication over Mutual TLS. The application extracts the certificate's Common Name (CN) or Subject Alternative Name (SAN) to construct LDAP queries:
DistinguishedName dn = new DistinguishedName(certificate.getSubjectDN().getName());
String cn = dn.getValue("CN");
String ldapQuery = "(&(objectClass=person)(cn=" + cn + "))";
An attacker with a compromised certificate can craft a CN value containing LDAP metacharacters. If the certificate contains CN="admin*)(|(objectClass=*", the resulting query becomes:
(&(objectClass=person)(cn=admin*)(|(objectClass=*)))
This query bypasses the intended CN match and returns all user objects, potentially allowing authentication as any user.
Mutual TLS-specific attack patterns include:
- Certificate Attribute Manipulation: Exploiting certificate fields (CN, OU, SAN) that are directly used in LDAP filters without proper escaping
- Certificate Chain Injection: Using intermediate certificates with crafted attributes to manipulate LDAP queries
- Subject DN Spoofing: Crafting Distinguished Names that break out of intended LDAP query contexts
The trust established by Mutual TLS creates a false sense of security, leading developers to skip input validation on certificate-derived values. This is particularly dangerous when certificate attributes are used to construct LDAP filters for authorization decisions.
Mutual Tls-Specific Detection
Detecting LDAP injection in Mutual TLS environments requires examining both the certificate handling code and LDAP query construction patterns. The key is identifying where certificate attributes flow directly into LDAP queries without proper sanitization.
Static analysis should focus on:
grep -r "getSubjectDN|getCN|getSAN" --include="*.java"
grep -r "ldapQuery|searchFilter" --include="*.java"
Look for code patterns where certificate attributes are concatenated into LDAP filters:
String filter = "(" + attribute + "=" + value + ")";
Dynamic testing involves crafting malicious certificates and observing LDAP query behavior. Using OpenSSL, create a certificate with crafted CN values:
openssl req -x509 -newkey rsa:2048 -keyout malicious.key -out malicious.crt -days 365 -subj "/CN=admin*)(|(objectClass=*)"
middleBrick's scanner specifically tests for LDAP injection vulnerabilities in Mutual TLS contexts by:
- Analyzing certificate attribute extraction code paths
- Testing LDAP query construction with crafted certificate values
- Checking for proper escaping of LDAP metacharacters in certificate-derived inputs
- Verifying that certificate trust doesn't bypass authentication controls
The scanner examines OpenAPI specifications to identify endpoints that use certificate-based authentication and then tests the runtime behavior of LDAP queries constructed from certificate attributes. It specifically looks for patterns like:
searchRequest.setFilter("(&(objectClass=inetOrgPerson)(cn=" + cn + "))");
middleBrick's LLM security module also checks for AI-powered authentication systems that might use LDAP queries based on certificate attributes, testing for prompt injection vulnerabilities that could manipulate these queries.
Mutual Tls-Specific Remediation
Remediating LDAP injection in Mutual TLS environments requires a defense-in-depth approach that addresses both certificate handling and LDAP query construction.
Certificate Attribute Sanitization
Always sanitize certificate attributes before using them in LDAP queries. For Java applications:
import javax.naming.directory.SearchControls;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
public static String sanitizeCertificateAttribute(String attribute) {
if (attribute == null) return null;
// Escape LDAP metacharacters
String escaped = attribute
.replace("\"", "\"") // escape quotes
.replace("*", "\*") // escape asterisk
.replace("(", "\(") // escape left parenthesis
.replace(")", "\)") // escape right parenthesis
.replace("\"", "\\"); // escape backslash
return escaped;
}
// Usage in LDAP query construction
String cn = sanitizeCertificateAttribute(certificateCN);
String ldapQuery = MessageFormat.format(
"(&(objectClass=person)(cn={0}))",
cn
);
Parameterized LDAP Queries
Use parameterized queries instead of string concatenation:
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
public SearchResult ldapSearchByCertificate(String certificateCN) throws NamingException {
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// Use SearchControls.SUBTREE_SCOPE with proper filtering
String baseDN = "ou=users,dc=example,dc=com";
String filter = "(&(objectClass=person)(cn=?))";
// Use a SearchResult enumeration with proper timeout
NamingEnumeration<SearchResult> results = ctx.search(baseDN, filter, new String[]{certificateCN}, controls);
return results.hasMore() ? results.next() : null;
}
Certificate Validation Enhancements
Implement strict certificate validation that checks for crafted attributes:
public class CertificateValidator {
private static final Pattern LDAP_META_CHARS = Pattern.compile("[\\*\\(\\)\\"\\"\\"\\"]");
public static boolean isValidCertificateForLdap(X509Certificate cert) {
String subjectDN = cert.getSubjectDN().getName();
String cn = extractCN(subjectDN);
// Check for suspicious patterns
if (LDAP_META_CHARS.matcher(cn).find()) {
return false; // Reject certificates with LDAP metacharacters
}
// Additional validation: check certificate policies, extended key usage
return validateCertificatePolicies(cert);
}
private static String extractCN(String subjectDN) {
try {
LdapName ldapName = new LdapName(subjectDN);
for (Rdn rdn : ldapName.getRdns()) {
if (rdn.getType().equalsIgnoreCase("CN")) {
return rdn.getValue().toString();
}
}
} catch (NamingException e) {
return null;
}
return null;
}
}
Runtime Protection with middleBrick
Integrate middleBrick's CLI scanner into your CI/CD pipeline to continuously test for LDAP injection vulnerabilities:
# Install middleBrick CLI
npm install -g middlebrick
# Scan your API endpoint
middlebrick scan https://api.example.com --auth-cert /path/to/client.crt --auth-key /path/to/client.key --output report.json
# Example GitHub Action workflow
name: API Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run middleBrick scan
run: |
npm install -g middlebrick
middlebrick scan ${{ secrets.API_URL }} \
--auth-cert ./client.crt \
--auth-key ./client.key \
--fail-below B
- name: Upload report
uses: actions/upload-artifact@v3
with:
name: middleBrick-report
path: report.json
This approach ensures that LDAP injection vulnerabilities are caught before deployment, with middleBrick providing specific findings about certificate attribute handling and LDAP query construction patterns.