Checker Ldap

belongs to group Basic
Identify potential LDAP poisoning attacks

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28

Warnings generated by this checker

  • LDAPPoisoningWarning: an LDAP poisoning attack seems possible [ CWE349 ]

Options accepted by this checker

  • none

Annotations understood by this checker

  • @com.juliasoft.julia.checkers.ldap.LDAPPoisoningIfTrue


Queries against Ldap databases return objects representing data stored in the database. Modifications to such objects should not be reflected into actual updates to the database, or otherwise everybody holding a reference to such objects might corrupt the database, in a kind of attack known as Ldap poisoning. This checker identifies such situations.

Action: Do not allow Ldap queries to return objects whose modification gets reflected into the database. Typically, a specific flag should not be set for such queries.


Consider the following program:

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import com.juliasoft.julia.extraction.EntryPoint;

public class LdapPoisoning {

  public @EntryPoint List<Object> search(int controls, String[] attributes, String base, String filter, String[] args) 
  																									throws NamingException {
    LdapContext ctx = null;
    List<Object> result = new ArrayList<>();

    try {
      Properties env = createEnvironment();
      ctx = new InitialLdapContext(env, null);

      SearchControls ctls = new SearchControls();

      NamingEnumeration<SearchResult> enm =, filter, args, ctls);
      while (enm.hasMoreElements()) {
        SearchResult sr = enm.nextElement();
    catch (NamingException ne) {
      throw ne;
    finally {
      if (ctx != null)

    return result;

  public boolean exists(String dn) throws NamingException {
    Properties env = createEnvironment();
    LdapContext ctx = new InitialLdapContext(env, null);
    SearchControls ctls = new SearchControls();
    ctls.setReturningAttributes(new String[0]);

    try {, "(objectClass=*)", ctls);
      return true;
    catch (NameNotFoundException nne) {
      return false;

  protected Properties createEnvironment() {
    Properties env = new Properties();
    env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.setProperty(Context.PROVIDER_URL, "");
    env.setProperty(Context.OBJECT_FACTORIES, "my.factory");
    env.setProperty(Context.SECURITY_PRINCIPAL, "user");
    env.setProperty(Context.SECURITY_CREDENTIALS, "verysecretpassword");

    return env;

This checker issues the following warning: [Ldap: LDAPPoisoningWarning] A potential LDAP poisoning attack seems possible here

since the call to setReturningObjFlag(true) at line 30 allows method getObject() at line 35 to return an object whose modification gets reflected into the database. The object is stored into the list result returned at line 46 and hence accessible by the callers of method search(). Note that no warning is issued at line 55 instead.

In this example, the programmer should not call setReturningObjFlag(true) or should guarantee that the result of the search at line 32 does not escape from the local scope of the method.