Introducción

 

Actualmente el desarrollo de aplicaciones es un proceso que tiene un papel fundamental en la seguridad de la información. A nivel técnico, se cubre por lo general la amenaza de  ataque de inyección SQL.

En esta ocasión se revisará otro tipo de vulnerabilidad relacionada con las bases de datos SQL, que es tan peligroso como la inyección SQL. En esta entrega se demostrará la materialización de la amenaza y la manera de prevenirla.


 

Antecedentes

 

Al revisar el código fuente de las aplicaciones, se puede encontrar las funciones empleadas para el registro de un usuario, como se aprecia en la figura 1, donde el desarrollador ha intentado eliminar las posibilidades de que en el código sea vulnerable a la inyección SQL.

 

Screenshot_20170202_011001.png

 

Fig. 1 Función para registrar usuarios

 

Screenshot_20170202_011048.png

 

En la figura 2 se muestra la función que maneja la autenticación del usuario mediante la validación de la clave.

 

Fig. 2 Función para autenticación

 

Se puede verificar que hay controles de seguridad como filtros de los parámetros de usuario y uso de comillas simples para seguridad adicional, sin embargo ¡un atacante podría ingresar conociendo los usuarios registrados!

 

Contexto

 

En el contexto de este ataque, se tienen las siguientes condiciones en la base de datos:

 

  1. Uno de los tratamientos que se da a las cadenas SQL es eliminar caracteres de espacio en blanco al final de la cadena, por ejemplo ‘miusuario    ’ es tratado similar a ‘miusuario’. Esto se puede constatar en muchos casos tanto en la sentencia SELECT, en el WHERE así como en las sentencias INSERT.
  2. En cualquier sentencia INSERT, SQL forza las restricciones de longitud máxima en los tipos ‘varchar(n)’ en caso de que la cadena de caracteres sea mayor a n. Por ejemplo, si tenemos un valor de n igual a 5 e intentamos con el usuario ‘miusuario’ el registro mostrará sólo ‘miusu’.

 

El Ataque

 

Usando con una consola de MySQL se crea una base de datos de prueba.

 

 

Fig. 3 Creación de la base de datos de prueba

 

Se crea la tabla ‘users’ para registrar los usuarios con el parámetro de nombre de usuario (username) y la contraseña (password). Para el nombre de usuario se establece restricción de 25 caracteres como longitud máxima.

 

 

Fig. 4 Configuración de la tabla users

 

Ahora, se ingresa un usuario con nombre de usuario ‘miusuario’ y contraseña ‘mipassword’ y verificamos que si escribimos la consulta de un usuario con nombre de usuario

‘miusuario                1’ no obtenga resultados.

 

Fig. 5 Prueba de usuario

 

Se ingresa un nuevo usuario con el nombre de usuario siguiente ‘miusuario                1’ y una contraseña diferente.

 

Fig. 6 Creación de nuevo usuario similar

 

Esta vez se procede nuevamente a consultar los usuarios con nombre de usuario ‘miusuario’. Como se aprecia en la Fig.7, la consulta devuelve como resultado que existen dos usuarios con nombre ‘miusuario’.

 

Fig. 7 Consulta de usuarios idénticos

 

Este resultado permite la explotación de la restricción de la longitud del usuario mediante la creación de un nuevo usuario con el mismo nombre de usuario ya existente pero añadiendo caracteres en blanco para que exceda la restricción establecida de los 25 caracteres con una contraseña diferente. La función mostrada en la figura 2 permitirá autenticar a un atacante sin ningún problema como si fuera el usuario original.

 

Remediaciones

 

Esta vulnerabilidad es crítica en aplicaciones web y debe ser tomada en cuenta en las revisiones de seguridad. A continuación se listan varias medidas para mitigarlo:

 

  • Se debe agregar restricción UNIQUE a las columnas que se requieran que sean únicas. Con una restricción UNIQUE en el nombre de usuario (username), la inserción de otra entrada similar pero con mayor longitud no será posible. Las cadenas serán detectadas como iguales y la consulta INSERT fallará.
  • En el aplicativo del lado del servidor, se debe truncar la longitud de los parámetros de entrada a la longitud máxima definida en la base de datos.
  • Siempre usar 'id' como clave principal para la tabla de la base de datos. Además, los datos deben ser rastreados por su id dentro de la aplicación.

 

Pin It