HIGH ldap injectionfastapidynamodb

Ldap Injection in Fastapi with Dynamodb

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

LDAP Injection occurs when an attacker can manipulate LDAP query construction, typically through unsanitized user input. In a Fastapi application that uses LDAP for authentication or group membership checks, if input is concatenated directly into LDAP filter strings, the application becomes vulnerable. When this same application stores or references user data in Amazon DynamoDB, the presence of DynamoDB does not introduce the injection, but it can amplify impact depending on how identity information is linked between LDAP and DynamoDB records.

For example, a Fastapi route might first bind to LDAP to validate credentials, then query DynamoDB to retrieve additional profile attributes. If the LDAP filter is built by string interpolation using user-supplied values (e.g., (uid=*) combined with input without escaping), an attacker can supply filter metacharacters such as *, (, ), or encoded null bytes to change the filter semantics. Common LDAP injection payloads include )(uid=*) to break out of a filter group or admin* to broaden matches. Because DynamoDB is often used as a secondary identity store, an attacker may try to leverage LDAP injection to gain unauthorized access to records that map to DynamoDB items, especially if the application trusts the LDAP identity to authorize DynamoDB operations.

In this combination, the vulnerability is created by insecure string handling in Fastapi route logic, not by DynamoDB itself. However, DynamoDB can expose a wider attack surface if the application uses identity attributes derived from LDAP (such as username or group membership) to construct DynamoDB key conditions without additional authorization checks. For instance, a query like SELECT * FROM users WHERE username = ? mapped to a DynamoDB Query on a partition key may be influenced by LDAP-derived values that were improperly sanitized. This can lead to horizontal or vertical privilege escalation if attackers manipulate LDAP filters to retrieve or affect other users’ DynamoDB data.

Additionally, if the Fastapi service performs group membership checks using LDAP queries and then uses the resulting group names to filter DynamoDB queries, unsanitized input can forge group membership assertions. This can cause the application to grant access to DynamoDB resources that should be restricted. Therefore, the interaction between Fastapi’s LDAP authentication layer and DynamoDB storage requires careful input validation and strict separation of authentication logic from data access patterns.

Dynamodb-Specific Remediation in Fastapi — concrete code fixes

To remediate LDAP injection in Fastapi when working with DynamoDB, you must ensure that LDAP filters are never constructed via string concatenation. Use parameterized filter building provided by LDAP libraries, and apply strict allowlist validation on any input that influences directory queries. DynamoDB access should be governed by its own authorization logic, independent of LDAP-derived values, and should never directly reflect unsanitized user input.

Below is a secure Fastapi example using the ldap3 library and boto3 for DynamoDB. The LDAP filter uses escape to neutralize dangerous characters, and DynamoDB queries rely on parameterized conditionals with strict attribute validation.

from fastapi import FastAPI, Depends, HTTPException, Query
from ldap3 import Server, Connection, ALL, escape
import boto3
from pydantic import BaseModel
import re

app = FastAPI()

# LDAP connection parameters (example)
LDAP_SERVER = 'ldap://example.com'
BASE_DN = 'dc=example,dc=com'

# DynamoDB client
 dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('users')

# Allowlist for username: alphanumeric and underscore only
USERNAME_ALLOWLIST = re.compile(r'^[a-zA-Z0-9_]{1,64}$')

def validate_username(username: str) -> str:
    if not USERNAME_ALLOWLIST.match(username):
        raise ValueError('Invalid username format')
    return username

def get_ldap_connection():
    server = Server(LDAP_SERVER, get_info=ALL)
    conn = Connection(server, auto_bind=True)
    return conn

@app.get('/search')
def search_user(username: str = Query(..., description='Username to search')):
    safe_username = validate_username(username)
    
    # Secure LDAP filter using ldap3.escape to prevent injection
    safe_ldap_filter = f'(uid={escape(safe_username)})'
    
    conn = get_ldap_connection()
    if not conn.bind():
        raise HTTPException(status_code=401, detail='LDAP bind failed')
    
    try:
        conn.search(search_base=BASE_DN,
                    search_filter=safe_ldap_filter,
                    attributes=['cn', 'mail', 'memberOf'])
        ldap_entries = conn.entries
    finally:
        conn.unbind()
    
    if not ldap_entries:
        raise HTTPException(status_code=404, detail='User not found in LDAP')
    
    # Independent DynamoDB fetch using safe key
    try:
        response = table.get_item(Key={'username': safe_username})
        user_data = response.get('Item')
        if not user_data:
            raise HTTPException(status_code=404, detail='User not found in DynamoDB')
    except Exception as e:
        raise HTTPException(status_code=500, detail=f'DynamoDB error: {str(e)}')
    
    return {
        'ldap': str(ldap_entries[0]) if ldap_entries else None,
        'dynamodb': user_data
    }

Key remediation points:

  • Use ldap3.escape or equivalent to sanitize input before embedding in LDAP filters; never concatenate raw strings.
  • Apply a strict allowlist regex for identifiers like usernames before using them in LDAP or DynamoDB operations.
  • Keep LDAP authentication and DynamoDB data retrieval logically separate; do not allow LDAP-derived values to directly form DynamoDB key expressions without validation.
  • Handle errors independently for LDAP and DynamoDB to avoid leaking internal details.

For DynamoDB, ensure that your table’s partition key and any secondary indexes are designed to avoid over-fetching, and that application-level authorization is applied regardless of LDAP group results. This layered approach reduces the risk that LDAP injection vectors can pivot to unauthorized DynamoDB access.

Frequently Asked Questions

Does middleBrick test for LDAP Injection as part of its scans?
middleBrick includes checks for authentication mechanisms and input validation that can surface LDAP injection risks when an API endpoint relies on directory services. Findings are provided with severity ratings and remediation guidance.
Can I scan my Fastapi service with DynamoDB using the free plan?
Yes, the free plan provides 3 scans per month, which is suitable for trying out scans against Fastapi endpoints that integrate with DynamoDB. For continuous monitoring or more scans, the Starter or higher plans increase limits and add features like GitHub Action integration.