HIGH ldap injectionexpress

Ldap Injection in Express

How Ldap Injection Manifests in Express

LDAP injection in Express applications typically occurs when user input is directly incorporated into LDAP queries without proper sanitization. Express's flexible middleware architecture and common authentication patterns create specific attack vectors that developers must understand.

The most common scenario involves Express applications using LDAP for authentication or directory lookups. When a user submits credentials through a login form, Express middleware might construct an LDAP query like:

const dn = `uid=${username},ou=users,dc=example,dc=com`;

If username contains malicious input like john)(&(objectClass=person, the resulting LDAP filter becomes:

(&(uid=john)(&(objectClass=person),ou=users,dc=example,dc=com)

This can bypass authentication or retrieve unauthorized directory information.

Express route handlers that process LDAP queries are particularly vulnerable. Consider this pattern:

app.post('/api/search', async (req, res) => {
  const { searchTerm } = req.body;
  const filter = `(cn=${searchTerm})`;
  const result = await ldapClient.search(baseDN, { filter });
  res.json(result);
});

An attacker could submit *)(cn=* as the search term, creating a filter that matches all objects. More sophisticated payloads can extract specific attributes or enumerate directory structure.

Express applications often use middleware like Passport.js with LDAP strategies. These libraries may not properly escape all user inputs when constructing queries, especially when developers customize authentication logic. The combination of Express's dynamic routing and LDAP's query syntax creates a perfect storm for injection attacks.

Third-party LDAP libraries commonly used in Express (ldapjs, adldap2, strong-auth-ldap) may have inconsistent escaping mechanisms. Developers might assume these libraries handle sanitization automatically, but many require explicit escaping of special characters: (, ), &, |, *, , , .

Express-Specific Detection

Detecting LDAP injection in Express applications requires examining both the code patterns and runtime behavior. The most effective approach combines static analysis with dynamic scanning.

Static analysis should focus on Express route handlers that construct LDAP queries. Look for patterns where request parameters are directly interpolated into query strings:

const filter = `(uid=${req.query.username})`;

Express's req.params, req.query, and req.body objects are common sources of untrusted input. Tools like ESLint with custom rules can flag direct interpolation of these values into LDAP filters.

Dynamic scanning with middleBrick specifically tests Express endpoints for LDAP injection vulnerabilities. The scanner sends payloads designed to manipulate LDAP query logic:

POST /api/ldap/search
Content-Type: application/json

{"searchTerm":"*)(cn=*"}

middleBrick analyzes the response structure and timing to detect successful injection. The scanner tests multiple LDAP injection patterns including boolean logic manipulation, attribute enumeration, and filter injection.

Express applications often expose LDAP functionality through REST APIs. middleBrick's black-box scanning approach tests these endpoints without requiring source code access. The scanner identifies vulnerable patterns by observing how the application handles malformed LDAP queries.

For applications using Passport.js LDAP strategies, middleBrick can detect if the strategy properly escapes credentials. The scanner attempts authentication with specially crafted usernames containing LDAP metacharacters and observes whether authentication succeeds unexpectedly.

middleBrick's LLM/AI security module also checks for AI-powered LDAP query generation systems that might be vulnerable to prompt injection attacks, where malicious prompts could cause the AI to generate vulnerable LDAP queries.

Express-Specific Remediation

Remediating LDAP injection in Express requires a defense-in-depth approach combining proper escaping, input validation, and architectural patterns that minimize injection surface area.

The most critical fix is using proper LDAP escaping for all user inputs. The ldapjs library provides an escapeFilter function:

const { escapeFilter } = require('ldapjs');

app.post('/api/search', async (req, res) => {
  const { searchTerm } = req.body;
  const safeSearchTerm = escapeFilter(searchTerm);
  const filter = `(cn=${safeSearchTerm})`;
  const result = await ldapClient.search(baseDN, { filter });
  res.json(result);
});

For applications using other LDAP libraries, implement consistent escaping:

function escapeLdapFilter(value) {
  return value
    .replace(/\/g, '\\5c')
    .replace(/\*/g, '\\2a')
    .replace(/\(/g, '\\28')
    .replace(/\)/g, '\\29')
    .replace(/\0/g, '\\00')
    .replace(/\n/g, '\\0a')
    .replace(/\r/g, '\\0d');
}

app.post('/api/authenticate', async (req, res) => {
  const { username } = req.body;
  const safeUsername = escapeLdapFilter(username);
  const filter = `(uid=${safeUsername})`;
  // ... authentication logic
});

Express middleware can centralize LDAP input sanitization:

function ldapSanitizeMiddleware(req, res, next) {
  const sanitize = (obj) => {
    if (typeof obj === 'string') {
      return escapeLdapFilter(obj);
    } else if (Array.isArray(obj)) {
      return obj.map(sanitize);
    } else if (typeof obj === 'object' && obj !== null) {
      return Object.fromEntries(
        Object.entries(obj).map(([k, v]) => [k, sanitize(v)])
      );
    }
    return obj;
  };
  
  req.body = sanitize(req.body);
  req.query = sanitize(req.query);
  req.params = sanitize(req.params);
  next();
}

app.use(express.json());
app.use(ldapSanitizeMiddleware);

app.post('/api/search', async (req, res) => {
  // All inputs already sanitized
  const filter = `(cn=${req.body.searchTerm})`;
  const result = await ldapClient.search(baseDN, { filter });
  res.json(result);
});

Input validation should complement escaping. Use Express middleware to validate LDAP query parameters against expected patterns:

const { body, param } = require('express-validator');

app.post('/api/search', [
  body('searchTerm')
    .isLength({ min: 1, max: 50 })
    .matches(/^[a-zA-Z0-9\s\-_]*$/)
    .withMessage('Invalid search term'),
  ldapSanitizeMiddleware
], async (req, res) => {
  // Safe to use req.body.searchTerm
  const filter = `(cn=${req.body.searchTerm})`;
  const result = await ldapClient.search(baseDN, { filter });
  res.json(result);
});

Consider using parameterized LDAP queries if your library supports them, similar to SQL prepared statements:

app.post('/api/search', async (req, res) => {
  const { searchTerm } = req.body;
  const filter = '(cn=?))';
  const result = await ldapClient.search(baseDN, { 
    filter,
    filterParams: [searchTerm] 
  });
  res.json(result);
});

For Express applications using LDAP for authentication, implement rate limiting and account lockout mechanisms to prevent brute-force attacks that exploit LDAP injection:

const rateLimit = require('express-rate-limit');

const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: 'Too many login attempts'
});

app.post('/login', loginLimiter, async (req, res) => {
  // LDAP authentication logic
});

Finally, use middleBrick's continuous monitoring to ensure LDAP injection vulnerabilities don't reappear in your Express application. The scanner can be integrated into your CI/CD pipeline to automatically test for LDAP injection before deployment.

Frequently Asked Questions

How can I test my Express application for LDAP injection vulnerabilities?
Use middleBrick's black-box scanning to test your Express API endpoints. The scanner sends LDAP injection payloads to your routes and analyzes responses for signs of successful injection. You can also perform manual testing by submitting LDAP metacharacters like *, (, ), & in your application's search and authentication forms, then observing if the behavior changes unexpectedly.
Does middleBrick detect LDAP injection in Express applications using Passport.js LDAP strategies?
Yes, middleBrick specifically tests Express applications using Passport.js LDAP strategies. The scanner attempts authentication with crafted LDAP payloads and analyzes whether the strategy properly escapes credentials. It also checks for vulnerabilities in custom authentication logic that might bypass Passport's built-in protections.