HIGH ldap injectionaspnetbearer tokens

Ldap Injection in Aspnet with Bearer Tokens

Ldap Injection in Aspnet with Bearer Tokens — how this specific combination creates or exposes the vulnerability

LDAP injection occurs when an attacker can control part of an LDAP query without proper validation or escaping. In ASP.NET applications that authenticate against an LDAP directory (for example, using System.DirectoryServices), building queries by concatenating user input enables injection. This risk persists even when the application uses bearer tokens for API authentication because bearer tokens typically guard the API boundary, while backend-to-directory communication may still build LDAP filters from sources that include claims extracted from the token or other trusted-but-untrusted data.

Consider an ASP.NET app that receives a bearer token, validates it, and then uses claims (such as user identifier or group membership) to construct an LDAP search filter. If the app directly embeds these claims into the filter string, an attacker who can influence the token or the mapping logic can inject LDAP metacharacters like *, (, ), and &. For example, a filter built as (&(objectClass=user)(sAMAccountName=) + username + )) becomes vulnerable when username contains )(&objectClass=*), potentially turning the filter into a tautology that returns all users. This can expose authentication bypass, unauthorized data retrieval, or account enumeration.

In practice, the flow may look like this: the client presents a bearer token to an ASP.NET endpoint; the server validates the token and extracts a user identifier; the server uses that identifier to query an internal LDAP service to enrich profile data or group membership. If the identifier is reflected into the LDAP filter without escaping, the unauthenticated attack surface includes the claim values within the token and any server-side mapping logic. Even when the endpoint itself is protected by bearer token validation, an injected LDAP query can expose sensitive directory information or bypass intended access controls, demonstrating that API-layer authentication does not automatically protect backend directory interactions.

Real-world impacts align with common attack patterns such as authentication bypass or information disclosure, which are mapped to OWASP API Top 10 and other frameworks. For example, an attacker might supply a username like admin*)(|(objectClass=*) to enumerate all directory entries if the filter is improperly constructed. Because LDAP injection is a backend concern, it remains critical to validate and escape all inputs used in directory queries, even when the entry point uses bearer tokens.

Bearer Tokens-Specific Remediation in Aspnet — concrete code fixes

Remediation focuses on never directly concatenating user-influenced data into LDAP filters. Use parameterized approaches and escaping for LDAP queries, and keep bearer token validation separate from directory query construction. Below are concrete, realistic code examples for ASP.NET that demonstrate secure practices.

Example 1: Safe LDAP query using DirectorySearcher with escaped input

using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.Web;

public class LdapService
{
    private readonly string _ldapPath = "LDAP://DC=example,DC=com";

    public SearchResultCollection SearchUsers(string username)
    {
        if (string.IsNullOrWhiteSpace(username))
            throw new ArgumentException("Username is required");

        // Escape special LDAP characters in the input
        string escapedUsername = EscapeLdapFilter(username);

        using (DirectoryEntry entry = new DirectoryEntry(_ldapPath))
        using (DirectorySearcher searcher = new DirectorySearcher(entry))
        {
            // Build filter using escaped value; avoid string concatenation with raw input
            searcher.Filter = $"(&(objectClass=user)(sAMAccountName={escapedUsername}))";
            searcher.PropertiesToAdd.Add("cn");
            searcher.PropertiesToAdd.Add("memberOf");
            return searcher.FindAll();
        }
    }

    private string EscapeLdapFilter(string input)
    {
        // Basic LDAP metacharacters per RFC 4515
        return input.Replace("\\", "\\\\")
                    .Replace("*", "\\2a")
                    .Replace("(", "\\28")
                    .Replace(")", "\\29")
                    .Replace("\0", "\\00");
    }
}

Example 2: Using parameterized System.DirectoryServices.Protocols queries

using System.DirectoryServices.Protocols;
using System.Net;

public class LdapProtocolService
{
    private readonly string _ldapServer = "ldap.example.com";
    private readonly string _rootDse = "DC=example,DC=com";

    public SearchResponse SearchWithEscapedFilter(string providedName)
    {
        if (string.IsNullOrWhiteSpace(providedName))
            throw new ArgumentException("Name is required");

        string safeName = EscapeLdapFilter(providedName);
        string filter = $"(name={safeName})";

        LdapConnection connection = new LdapConnection(_ldapServer);
        connection.SessionOptions.ProtocolVersion = 3;
        connection.Bind(new NetworkCredential("binduser", "password", "domain"));

        SearchRequest request = new SearchRequest(
            _rootDse,
            filter,
            SearchScope.Subtree,
            null
        );

        return (SearchResponse)connection.SendRequest(request);
    }

    private string EscapeLdapFilter(string input)
    {
        // Equivalent escaping logic; in production, centralize this helper
        return input.Replace("\\", "\\\\")
                    .Replace("*", "\\2a")
                    .Replace("(", "\\28")
                    .Replace(")", "\\29")
                    .Replace("\0", "\\00");
    }
}

In both examples, bearer token usage for API access remains intact, but the LDAP query construction uses escaped input rather than raw concatenation. This ensures that special characters cannot alter the intended logic of the LDAP filter. Centralize escaping logic and validate input against expected patterns to reduce risk across the application.

Frequently Asked Questions

Does using bearer tokens prevent LDAP injection in ASP.NET?
No. Bearer tokens protect the API boundary, but if backend code builds LDAP filters by concatenating claims or other inputs without escaping, LDAP injection remains possible. Always escape and parameterize directory queries.
What is a simple rule to avoid LDAP injection in ASP.NET?
Never embed untrusted data directly into LDAP filter strings. Use escaping for LDAP metacharacters or, when possible, parameterized APIs, and keep directory query construction separate from authentication tokens.