Skip to content

CWE-90: LDAP Injection

Overview

LDAP Injection occurs when untrusted user input is used to construct LDAP queries without proper validation or escaping, allowing attackers to modify queries and access or manipulate directory data.

OWASP Classification

A05:2025 - Injection

Risk

High: Attackers can bypass authentication, escalate privileges, or extract sensitive directory information. LDAP Injection can lead to unauthorized access and data breaches.

Remediation Steps

Core principle: Never concatenate untrusted input into LDAP filters/queries; use safe LDAP APIs and strict allowlists.

Trace the Data Path and Locate the Vulnerability

Analyze how untrusted data reaches LDAP query construction:

  • Review the flaw details to identify the specific file, line number, and code pattern
  • Source: Where untrusted data enters (user input, external file, database, network request)
  • Sink: LDAP query construction or search function
  • String concatenation: Look for untrusted data being directly embedded in LDAP filters
  • Understand the data flow from source to sink

Use Parameterized LDAP APIs (Primary Defense)

Replace string concatenation with safe LDAP API usage:

  • Use APIs that separate query structure from data
  • Avoid string concatenation when building LDAP queries
  • Use framework-specific safe query builders where available
  • Follow the secure code examples provided in language-specific guidance

Escape Special LDAP Characters

If parameterization isn't available, properly escape all untrusted data:

  • Escape special LDAP characters: *, (, ), \, \0, /
  • Use language-specific LDAP escaping functions
  • Apply escaping before incorporating input into LDAP filters
  • Never trust client-side validation alone

Validate and Sanitize Input (Defense in Depth)

Add input validation as an additional security layer:

  • Enforce strict type and format checks on all untrusted data
  • Validate expected patterns (username format, email addresses)
  • Use allowlists for enumerated values
  • Reject or sanitize unexpected characters
  • Implement length limits to prevent DoS

Apply Least Privilege to Directory Accounts

Limit the impact of potential LDAP injection:

  • Use LDAP bind accounts with minimal permissions
  • Read-only access for search operations only
  • Avoid using admin/root accounts for application queries
  • Restrict access to sensitive directory attributes
  • Use separate accounts for different application functions

Monitor and Test

Verify your fixes and enable detection:

  • Test with LDAP injection payloads: *)(uid=*))(|(uid=*, admin)(|(password=*)), *)(objectClass=*
  • Log all LDAP queries and failed authentication attempts
  • Alert on anomalous or suspicious query patterns
  • Verify the specific input that triggered the finding no longer causes the vulnerability
  • Ensure legitimate functionality still works correctly
  • Re-scan with the security scanner to confirm the issue is resolved

Common Vulnerable Patterns

  • Directly embedding untrusted data in LDAP filters
  • Accepting arbitrary input for search or bind operations

Unescaped User Input in LDAP Filter (Pseudocode)

# Dangerous: user input in LDAP filter
search_filter = f"(uid={user_input})"

Secure Patterns

LDAP Filter Escaping (Pseudocode)

# Safe: use parameterized query or escape input
safe_input = escape_filter_chars(user_input)  # Escapes *, (, ), \, NUL
search_filter = f"(uid={safe_input})"

Why this works:

  • Escapes LDAP special characters (*, (, ), \, NUL) to prevent filter manipulation
  • Prevents attackers from injecting additional filter conditions like (uid=*)(|(password=*)) to bypass authentication
  • Treats user input as literal data rather than LDAP filter syntax
  • Blocks wildcard searches (*) that could enumerate all directory entries
  • Prevents attackers from modifying query logic to access unauthorized user accounts or data

Language-Specific Guidance

  • C# - DirectoryEntry with parameterized filters
  • Java - javax.naming, LdapName with DN validation
  • JavaScript/Node.js - ldapjs with filter escaping
  • Python - ldap3 with parameterized search filters

Additional Resources