Ldap Injection with Basic Auth
How Ldap Injection Manifests in Basic Auth
LDAP injection in Basic Auth scenarios occurs when user-supplied credentials are directly incorporated into LDAP queries without proper sanitization. This vulnerability allows attackers to bypass authentication by manipulating the LDAP filter syntax.
The most common attack pattern involves crafting a username that closes the intended LDAP filter and injects additional conditions. For example, if a Basic Auth implementation constructs an LDAP query like:
uid=,ou=users,dc=example,dc=com An attacker can submit a username like:
admin)(uid=*))(|(uid=*This transforms the query into:
uid=admin)(uid=*))(|(uid=*,ou=users,dc=example,dc=comWhich effectively becomes:
(uid=admin)(uid=*))(|(uid=*This always evaluates to true, potentially allowing authentication as any user, including administrative accounts.
Another attack vector targets the password field. If the application constructs queries like:
(&(uid=)(userPassword=)) An attacker can submit a password containing LDAP metacharacters to manipulate the query logic. For instance, using a password like )(userPassword=*))(|(userPassword=* can break out of the password condition and create a filter that always matches.
Basic Auth implementations are particularly vulnerable because they often use the provided credentials directly in backend authentication without additional validation. The Base64-decoded username and password from the Authorization header flow directly into LDAP queries in many applications.
Time-based LDAP injection is another technique where attackers can use LDAP's extensible matching syntax to create conditional delays. This allows for blind extraction of information through timing analysis, though this is less common in Basic Auth scenarios.
Basic Auth-Specific Detection
Detecting LDAP injection in Basic Auth requires examining both the authentication flow and the LDAP query construction. The first indicator is observing whether the application uses LDAP as its authentication backend for Basic Auth credentials.
Manual detection involves:
- Capturing the LDAP queries generated during authentication attempts
- Testing with usernames containing LDAP metacharacters:
)(,&,|,*, - Observing if authentication succeeds with malformed inputs
- Checking if wildcard characters in usernames bypass intended access controls
Automated detection with middleBrick specifically targets Basic Auth LDAP injection through several mechanisms:
The scanner first identifies endpoints protected by Basic Auth headers. It then attempts authentication with crafted payloads designed to trigger LDAP injection. For example:
Authorization: Basic YWRtaW4pKHZpY3Rpb25QYXNzd29yZD0pKygpKHZpY3Rpb25QYXNzd29yZD0KThis Base64-encoded payload contains LDAP injection syntax targeting the username field. middleBrick analyzes the server's response to determine if authentication succeeded unexpectedly.
The scanner also tests for LDAP injection in error messages. Some implementations reveal LDAP query structure or backend details when authentication fails with malformed inputs, providing valuable information for crafting exploits.
middleBrick's LLM/AI security module specifically checks for Basic Auth endpoints that might be exposed to AI services, as these can introduce new injection vectors when credentials are processed by language models.
The tool generates a risk score based on the severity of LDAP injection findings, with critical severity assigned when authentication can be bypassed entirely. The report includes the exact payload that succeeded and provides remediation guidance specific to Basic Auth implementations.
Basic Auth-Specific Remediation
Remediating LDAP injection in Basic Auth requires both input validation and secure query construction. The most effective approach uses parameterized LDAP queries or prepared statements, similar to SQL injection prevention.
Here's a Java example using JNDI with proper input sanitization:
import javax.naming.directory.*;
import javax.naming.ldap.*;
import java.util.Base64;
public class SecureBasicAuthLdap {
public boolean authenticate(String authHeader) throws Exception {
if (authHeader == null || !authHeader.startsWith("Basic ")) {
return false;
}
String base64Credentials = authHeader.substring("Basic ".length());
String credentials = new String(Base64.getDecoder().decode(base64Credentials));
String[] values = credentials.split(":", 2);
if (values.length < 2) {
return false;
}
String username = values[0];
String password = values[1];
// Input validation - reject LDAP metacharacters
if (!username.matches("^[a-zA-Z0-9._-]+$")) {
return false;
}
// Use parameterized search controls
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
// Use a fixed filter pattern
String searchFilter = "uid={0}";
LdapContext context = new InitialLdapContext();
NamingEnumeration<SearchResult> results = context.search(
"ou=users,dc=example,dc=com",
searchFilter,
new String[]{username},
controls
);
if (!results.hasMore()) {
return false;
}
SearchResult result = results.next();
String userDN = result.getNameInNamespace();
// Bind with credentials for verification
try {
context.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
context.reconnect(null);
return true;
} catch (Exception e) {
return false;
}
}
}For Node.js applications using LDAP.js:
const ldap = require('ldapjs');
const base64 = require('base64-js');
function authenticateBasicLdap(authHeader) {
if (!authHeader || !authHeader.startsWith('Basic ')) {
return false;
}
const base64Credentials = authHeader.slice(6);
const credentials = Buffer.from(base64Credentials, 'base64').toString();
const [username, password] = credentials.split(':');
// Validate input - only allow alphanumeric and common characters
if (!/^[a-zA-Z0-9._-]+$/.test(username)) {
return false;
}
const client = ldap.createClient({
url: 'ldap://localhost:389'
});
return new Promise((resolve) => {
client.search('ou=users,dc=example,dc=com', {
filter: `(uid=${username})`,
scope: 'sub'
}, (err, res) => {
if (err) return resolve(false);
res.on('searchEntry', (entry) => {
const userDN = entry.object.dn;
client.bind(userDN, password, (bindErr) => {
resolve(!bindErr);
});
});
res.on('error', () => resolve(false));
});
});
}Key remediation principles:
- Always validate username format before processing
- Use parameterized queries instead of string concatenation
- Never construct LDAP filters by directly inserting user input
- Test with malicious payloads to verify injection is prevented
- Consider using authentication libraries that handle LDAP securely
middleBrick's remediation guidance for Basic Auth LDAP injection specifically recommends these parameterized approaches and provides language-specific examples based on the detected technology stack.
Frequently Asked Questions
How can I test if my Basic Auth endpoint is vulnerable to LDAP injection?
Use middleBrick's self-service scanner by submitting your Basic Auth URL. The tool automatically tests with LDAP injection payloads and provides a risk score with specific findings. For manual testing, try authentication with usernames containing )( or & characters and observe if authentication succeeds unexpectedly.
Does middleBrick detect LDAP injection in Basic Auth endpoints?
Yes, middleBrick specifically tests Basic Auth endpoints for LDAP injection vulnerabilities. The scanner identifies Basic Auth protected URLs, crafts LDAP injection payloads targeting the username and password fields, and analyzes responses to detect authentication bypass. Results include the exact payload that succeeded and remediation guidance tailored to Basic Auth implementations.