Una peligrosa vulnerabilidad en la popular biblioteca Sequelize





¡Hola, Habr! Este artículo será de interés para aquellos que ya están usando la biblioteca Sequelize o simplemente van a trabajar con ella. Debajo del corte, le diremos cómo la funcionalidad incorporada de operatorAliases puede ser dañina y cómo evitar una fuga de su propia base de datos.



¿Qué es Sequelize, dónde se usa y para qué?



Sequelize es una biblioteca ORM de Node.js para Postgres, MySQL, MariaDB, SQLite y Microsoft SQL Server que mapea tablas en bases de datos y sus relaciones con clases. Cuando usamos Sequelize, no tenemos que escribir consultas SQL, pero debemos trabajar con datos como con objetos ordinarios. Tiene un sólido soporte transaccional, relaciones, carga activa y diferida, replicación de lectura y más.



¿Qué es operatorAliases y cuál es el peligro?



Sequelize usa operadores de caracteres por defecto. El uso de Sequelize sin alias simbólicos, por supuesto, mejora la seguridad. Aunque la falta de alias de cadena hace que la inyección del operador sea extremadamente improbable, siempre debemos validar y limpiar correctamente la entrada del usuario.



Y la propia opción operatorAliases le permite establecer si los operadores de alias estarán disponibles. Así es como se ve un ejemplo de activación en el código:







Cuando todo funciona bien



Veamos el código de la aplicación de demostración. El archivo de modelo user.model.js contiene: Puede







ver que hay tres campos en la tabla de usuarios y que todos tienen un tipo de datos de cadena.



El archivo de controlador auth.controller.js contiene:







El código usa el método findOne en el modelo de usuario. Y el método findOne devuelve la primera fila de la base de datos de acuerdo con la condición de consulta pasada. En este caso, la aplicación recibe los datos de nombre de usuario y contraseña del usuario, los aplica a una consulta contra la tabla de usuarios.



En este caso, la solicitud generada se verá así:

SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = :username AND `users`.`password` = :password LIMIT 1;







Dado que ORM se utiliza para realizar consultas, la inyección SQL trivial no funcionará. Si no hay coincidencias para el usuario en la base de datos, la aplicación devolverá el error Usuario no encontrado. Si los datos de entrada coinciden en el nivel de la base de datos, la aplicación comparará la contraseña ingresada con la contraseña almacenada en la base de datos, y devolverá una "Contraseña no válida". si no coincide, o un token de autorización si tiene éxito. El algoritmo de validación de datos de entrada se eligió específicamente para probar la vulnerabilidad.



La tabla contendrá los siguientes datos: La











autorización funciona correctamente.



¿Qué pasa con los operadores y los alias?









Los alias se indican con el símbolo "$", la sintaxis de los alias es similar a MongoDB. Tenemos disponibles operadores de búsqueda, comparaciones y muchos otros. A pesar de la fuerte tipificación de los datos en el modelo, la transferencia de datos del usuario al ORM en formato JSON conlleva normalización. ¡Y aquí empieza la diversión!



Cuando los problemas golpean el DOM



Ataque por lotes







Este tipo de solicitud a la aplicación inicia una solicitud a la base de datos:

Ejecutando (predeterminado): con este ataque, puede verificar muchos inicios de sesión para una contraseña específica para la validez en una solicitud al servidor y viceversa. El ataque funciona en la última versión de la biblioteca para diciembre de 2020 (6.3.5) y con la opción operatorAliases desactivada. SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` IN ('admin', 'more', 'much more') AND `users`.`password` = 'wrong pass' LIMIT 1;











Ataque de conversión de tipo de datos



Si pasa datos como ...







... a la aplicación , no pasará nada en nuestro caso. Aunque la condición lógica en la base de datos será correcta, verificar la contraseña en la aplicación en estudio a nivel de aplicación y comparar diferentes tipos de datos no puede devolver verdadero.



Ataque del operador de comparación







De acuerdo con los datos de la captura de pantalla, se generará una consulta a la base de datos de la forma: La base de datos devuelve datos, ya que existe una coincidencia entre el nombre de usuario = admin y una contraseña que no es igual a “aaa”. Para pasar por el proceso de autorización por completo, necesitamos obtener una contraseña.

SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = 'admin' AND `users`.`password` != 'aaa' LIMIT 1;











Ataque de búsqueda de cadenas y expresiones regulares



Puede obtener los datos sin procesar utilizando los alias para los operadores de búsqueda $ like o los operadores $ regexp para trabajar con expresiones regulares.







Cuando el símbolo no converge, se lanzará un error que indica que no se encontró al usuario.







Si el símbolo coincide, habrá un error sobre la contraseña incorrecta. Se ejecuta una consulta del formulario en la base de datos: así, carácter a carácter, puede restaurar los datos de la tabla.

SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = 'admin' AND `users`.`password` LIKE 'E%' LIMIT 1;











Ataque de comparación de columnas en una tabla



Hay un alias interesante $ col que le permite comparar un campo con un campo.







La consulta a la base de datos: Ejecutará la siguiente consulta a la base de datos: Así, cumplirá la condición lógica a nivel de base de datos.

SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = 'admin' AND `users`.`password` = `aaaaa` LIMIT 1;













SELECT `id`, `username`, `email`, `password`, `createdAt`, `updatedAt` FROM `users` AS `users` WHERE `users`.`username` = 'admin' AND `users`.`password` = `password` LIMIT 1;









Deshacerse de las vulnerabilidades



  • Debe instalar la última versión de la biblioteca Sequalize, donde se ha eliminado la compatibilidad con alias.



    ( Fuente )

  • Deshabilite el uso de alias configurando operatorAliases: false.
  • Valide a fondo los tipos de datos y sus valores del usuario antes de usarlos en el ORM.


¡Gracias por su interés!



All Articles