HIGH ldap injectionfastapiapi keys

Ldap Injection in Fastapi with Api Keys

Ldap Injection in Fastapi with Api Keys — how this specific combination creates or exposes the vulnerability

LDAP injection is an injection technique where untrusted input is concatenated into LDAP queries without proper sanitization or parameterization. In FastAPI applications that rely on API keys for access control, developers may assume that authentication via an API key is sufficient and may inadvertently construct LDAP filters or bind queries using string formatting. This combination creates a dangerous trust boundary: authentication is present, but authorization and query construction are flawed.

Consider a FastAPI endpoint that accepts an API key in the Authorization header and uses an LDAP service to validate group membership. If the username or search filter is built using Python string formatting, an attacker can supply a specially crafted username such as admin)(objectClass=*) or (&(uid=admin)(objectClass=*)) to manipulate the LDAP query logic. This can bypass intended filters, enumerate users, or extract sensitive directory information. For example:

import ldap
from fastapi import FastAPI, Header, HTTPException

app = FastAPI()

@app.get("/group-check")
def check_group(api_key: str = Header(...), username: str = ""):
    if not validate_api_key(api_key):
        raise HTTPException(status_code=401, detail="Invalid API key")
    # Vulnerable: string concatenation in LDAP filter
    user_filter = f"(uid={username})"
    conn.simple_bind_s("cn=admin,dc=example,dc=com", "secret")
    result = conn.search_s("dc=example,dc=com", ldap.SCOPE_SUBTREE, user_filter)
    return {"result": result}

In this pattern, the API key protects entry, but the LDAP query remains vulnerable to injection because the username parameter is interpolated directly into the filter string. An attacker could provide username as admin)(uid=* to alter the filter semantics. Because the scan dimensions of middleBrick include Input Validation and Authentication, such a misconfiguration would be flagged: the scanner detects that unauthenticated-style input (the attacker-controlled username) reaches the LDAP query path, and that the authentication (API key) does not constrain query construction.

Additionally, if the API key is leaked or shared, the LDAP binding may use a high-privilege account, amplifying the impact of injection. middleBrick’s LLM/AI Security checks are not directly relevant here, but its Authentication and Input Validation checks would highlight the absence of parameterized queries and insufficient separation between authentication and directory query logic.

Even when API keys are rotated frequently, injection remains possible if the application does not treat user input as untrusted. The risk is not theoretical; patterns like this have led to user enumeration and unauthorized directory reads in real-world services. Remediation requires strict input validation and use of parameterized LDAP APIs, not just stronger API keys.

Api Keys-Specific Remediation in Fastapi — concrete code fixes

To remediate LDAP injection in FastAPI while retaining API key authentication, you must ensure that user input never directly concatenates into LDAP queries. Use parameterized search APIs or construct filters using strict allow-lists. Below are two concrete, working FastAPI examples that demonstrate secure handling with API keys.

Example 1: Parameterized LDAP search with strict username allow-list

import re
from fastapi import FastAPI, Header, HTTPException
import ldap

app = FastAPI()

def validate_api_key(api_key: str) -> bool:
    # Replace with your key validation logic
    return api_key == "VALID_API_KEY"

@app.get("/group-check-secure")
def check_group_secure(api_key: str = Header(...), username: str = ""):
    if not validate_api_key(api_key):
        raise HTTPException(status_code=401, detail="Invalid API key")
    # Enforce a strict allow-list for usernames
    if not re.match(r"^[a-zA-Z0-9._-]{1,64}$", username):
        raise HTTPException(status_code=400, detail="Invalid username format")
    # Use parameterized search where supported, or safely escaped filter
    escaped_username = ldap.filter.escape_filter_chars(username)
    user_filter = f"(uid={escaped_username})"
    conn = ldap.initialize("ldap://ldap.example.com")
    conn.simple_bind_s("cn=admin,dc=example,dc=com", "secret")
    result = conn.search_s("dc=example,dc=com", ldap.SCOPE_SUBTREE, user_filter, attrlist=["cn", "mail"])
    conn.unbind_s()
    return {"result": result}

Example 2: Using an LDAP library that supports parameterized filters (preferred)

from fastapi import FastAPI, Header, HTTPException
import ldap

app = FastAPI()

def validate_api_key(api_key: str) -> bool:
    return api_key == "VALID_API_KEY"

@app.get("/group-check-parameterized")
def check_group_parameterized(api_key: str = Header(...), username: str = ""):
    if not validate_api_key(api_key):
        raise HTTPException(status_code=401, detail="Invalid API key")
    if not re.match(r"^[a-zA-Z0-9._-]{1,64}$", username):
        raise HTTPException(status_code=400, detail="Invalid username format")
    conn = ldap.initialize("ldap://ldap.example.com")
    conn.simple_bind_s("cn=admin,dc=example,dc=com", "secret")
    # Use filter format with tuple substitution where the library supports it
    user_filter = "(uid=%s)"
    result = conn.search_s("dc=example,dc=com", ldap.SCOPE_SUBTREE, user_filter % (username,), attrlist=["cn", "mail"])
    conn.unbind_s()
    return {"result": result}

Key remediation points: always validate and sanitize API key usage separately from directory query logic; never trust the API key to enforce query safety; escape or use allow-lists for any user-controlled data entering LDAP filters; and prefer libraries that support parameterized queries to avoid manual escaping. These changes align with the findings and remediation guidance that middleBrick’s scans provide, including its checks for Input Validation and Authentication in the context of API key usage.

Frequently Asked Questions

Can API keys alone prevent LDAP injection in FastAPI?
No. API keys provide authentication (identifying the client), but they do not sanitize user input. If your LDAP queries concatenate user-controlled values, injection is possible regardless of API key presence. You must validate, escape, or use parameterized queries.
Does middleBrick fix LDAP injection findings automatically?
middleBrick detects and reports findings with remediation guidance; it does not automatically fix code. You should apply the secure coding patterns shown above and re-scan to verify the issues are resolved.