Joven hacker sonriendo

Hackeamos su software

cero falsos positivos

Inteligencia experta + Tecnología especializada
DXST - SAST - IAST - SCA - DevSecOps
Caja blanca - Caja gris - Caja negra
Atacando Aplicaciones Web, APIs, Apps Móviles,
Cliente Servidor, Servidores, Redes, Dispositivos IoT
IoT SCI: Sistemas de Control Industrial

Evitar Inyección LDAP

Nuestros ethical hackers explican en que consiste el protocolo LDAP, uno de los principales ataques que se realizan contra el mismo (inyección LDAP), y la manera de prevenir dicho ataque en aplicaciones realizadas en Java mediante el uso de expresiones regulares.

Necesidad

Evitar ataques de inyección LDAP en Java.

Contexto

A continuación se describen las circunstancias bajo las cuales la siguiente solución tiene sentido.

  1. Se está desarrollando una aplicación en Java.

  2. Se realizan conexiones contra un servidor LDAP.

Solución

LDAP o protocolo ligero de acceso a directorios (en inglés Lightweight Directory Access Protocol), es un conjunto de protocolos abiertos usados para acceder a la información guardada de manera central a través de la red. LDAP organiza la información en un modo jerárquico usando directorios. Estos directorios pueden almacenar una gran variedad de información. Cualquier usuario registrado puede tener acceso a la información almacenada en el LDAP [1].

Entonces, una inyección de LDAP es un ataque utilizado con la finalidad de explotar aplicaciones basadas en servicios Web y que construyen sentencias LDAP basadas en la entrada del usuario, es decir, la información ingresada por estos. Debido a que una aplicación no puede desinfectar correctamente los datos introducidos por el usuario, se hace posible modificar las instrucciones LDAP mediante técnicas similares a un ataque de SQLInjection. Este tipo de ataques pueden dar lugar a que el atacante obtenga permisos o realice consultas no autorizadas. Tambien es posible que un atacante pueda realizar alguna modificación del contenido dentro del árbol LDAP [2].

En esta solución se pretende explicar como evitar este tipo de ataques en una aplicación Java que implementa dicho protocolo.

  1. La inyección ocurre cuando los datos introducidos por el usuario se envían al intérprete como parte de un comando o petición. Un atacante, proporcionando datos especialmente diseñados, puede hacer que se ejecute determinados comandos a su antojo.

  2. Las formas más usuales de evitar esta inyección es usando mecanismos que validen aspectos como la longitud, tipos, sintaxis y reglas del negocio. Dicha validación se debe hacer antes de aceptar los datos para ser almacenados o utilizados en la aplicación.

  3. También es recomendable rechazar el contenido inválido en lugar de intentar limpiar datos hostiles o malintencionadas ingresados por el usuario.

  4. Por último, validar la entrada de parámetros haciendo uso expresiones regulares es una excelente alternativa para evitar una inyección LDAP.

  5. El siguiente código es vulnerable a inyección LDAP.

    inyeccion.java
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    // String userSN = "S*"; // Valor Invalido
    // String userPassword = "*"; // Valor Invalido
    //Parte de una función de consulta
    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    try {
       DirContext dctx = new InitialDirContext(env);
       SearchControls sc = new SearchControls();
       String[] attributeFilter = {"cn", "mail"};
       sc.setReturningAttributes(attributeFilter);
       sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
       String base = "dc=example,dc=com";
       // La siguiente instrucción puede resolver (&(sn=S*)(userPassword=*))
       // Entrada no validada, lo cual permite el uso de caracteres especiales.
       String filter = "(&(sn=" + userSN + ")(userPassword=" + userPassword + "))"
       //Ejecución de la consulta LDAP
       NamingEnumeration<?> results = dctx.search(base, filter, sc);
    
  6. El siguiente código muestra como se puede prevenir la inyección.

    prevencion.java
    1
    2
    3
    4
    5
    6
    7
    8
    String base = "dc=example,dc=com";
    //Con esta validación se estable que el valor de userSN debe contener caracteres
    alfanuméricos y
    //el valor de userPassword sólo debe contener caracteres alfanuméricos
    if(! userSN.matches("[\\w\\s]*") || ! userPassword.matches("[\\w]*")) {
      throw new IllegalArgumentException("Invalid input");
    }
    String filter = "(&(sn = " + userSN + ")(userPassword=" + userPassword + "))";
    

Referencias

  1. Protocolo Ligero de Acceso a Directorios

  2. LDAP Injection Prevention Cheat Sheet

  3. REQ.0168: El sistema debe descartar toda la información potencialmente insegura que sea recibida por entradas de datos.




Haz un comentario

Estado de los servicios - Términos de Uso