LDAP Injection in .NET Directory Services

High Risk Injection
csharpdotnetldapinjectionauthenticationdirectory-services

What it is

LDAP injection vulnerabilities occur when untrusted input is concatenated into LDAP filters without proper escaping, allowing attackers to modify query logic. This can lead to authentication bypass, unauthorized access to directory entries, information disclosure, and privilege escalation within Active Directory or other LDAP systems.

using System.DirectoryServices;

public bool AuthenticateUser(string username, string password)
{
    // VULNERABLE: direct concatenation allows LDAP injection
    string filter = $"(&(objectClass=user)(sAMAccountName={username}))";
    
    using (var searcher = new DirectorySearcher())
    {
        searcher.Filter = filter;
        SearchResult result = searcher.FindOne();
        
        if (result != null)
        {
            return true;
        }
    }
    return false;
}

// Attack: username = "*)(objectClass=*))(&(objectClass=void"
// Result: (&(objectClass=user)(sAMAccountName=*)(objectClass=*))(&(objectClass=void))
// This bypasses authentication by matching any user
using System.DirectoryServices;
using System.Text.RegularExpressions;

public bool AuthenticateUser(string username, string password)
{
    // Validate input format
    if (!IsValidUsername(username))
    {
        return false;
    }
    
    // SECURE: escape LDAP special characters
    string escapedUsername = EscapeLdapFilterValue(username);
    string filter = $"(&(objectClass=user)(sAMAccountName={escapedUsername}))";
    
    using (var searcher = new DirectorySearcher())
    {
        searcher.Filter = filter;
        SearchResult result = searcher.FindOne();
        
        if (result != null)
        {
            return AuthenticateWithCredentials(result, password);
        }
    }
    return false;
}

private bool IsValidUsername(string username)
{
    // Only allow alphanumeric and specific characters
    return !string.IsNullOrEmpty(username) &&
           Regex.IsMatch(username, @"^[a-zA-Z0-9._-]+$") &&
           username.Length <= 100;
}

private string EscapeLdapFilterValue(string input)
{
    return input
        .Replace("\\", "\\5C")
        .Replace("*", "\\2A")
        .Replace("(", "\\28")
        .Replace(")", "\\29")
        .Replace("\0", "\\00")
        .Replace("/", "\\2F");
}

💡 Why This Fix Works

The vulnerable code concatenates user input directly into the LDAP filter, allowing attackers to inject malicious LDAP syntax to bypass authentication. The secure version validates the username format and escapes special LDAP characters before constructing the filter.

Why it happens

Using string concatenation or interpolation to build LDAP filters with user input.

Root causes

Direct String Concatenation in LDAP Filters

Using string concatenation or interpolation to build LDAP filters with user input.

Missing LDAP Character Escaping

Not escaping special LDAP characters like *, (, ), \, and null bytes.

Insufficient Input Validation

Not validating username format before using in LDAP queries.

Fixes

1

Escape LDAP Special Characters

Escape \, *, (, ), null, and / characters in user input before using in filters.

2

Validate Input Format

Use allowlist validation to only accept alphanumeric characters and specific allowed characters.

3

Use Parameterized LDAP Libraries

Where available, use libraries that support safe LDAP filter construction.

Detect This Vulnerability in Your Code

Sourcery automatically identifies ldap injection in .net directory services and many other security issues in your codebase.