A dangerous vulnerability in the popular Sequelize library





Hello, Habr! This article will be of interest to those who are already using the Sequelize library or are just going to work with it. Under the cut, we will tell you how the built-in operatorAliases functionality can be harmful and how to avoid a leak from your own database.



What is Sequelize, where is it used and what for?



Sequelize is a Node.js ORM library for Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server that maps tables in databases and their relationships with classes. When using Sequelize, we do not have to write SQL queries, but we must work with data as with ordinary objects. It has robust transactional support, relationships, active and lazy loading, read replication, and more.



What is operatorAliases and what is the danger?



Sequelize uses character operators by default. Using Sequelize without symbolic aliases, of course, improves security. Although the lack of string aliases makes operator injection extremely unlikely, we must always correctly validate and clean up user input.



And the operatorAliases option itself allows you to set whether alias operators will be available. Here's what an example of activation looks like in code:







When everything works right



Let's look at the demo application code. The model file user.model.js contains: You







can see that there are three fields in the users table, and they all have a string data type.



The auth.controller.js controller file contains:







The code uses the findOne method on the User model. And the findOne method returns the first row from the database according to the passed query condition. In this case, the application receives the username and password data from the user, applies them to a query against the users table.



The generated request in this case will look something like this:

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







Since ORM is used to form queries, trivial SQL injection will not work. If there are no matches for the user in the database, the application will return the User Not found error. If the input data matches at the database level, the application will compare the entered password with the password stored in the database, and either return an "Invalid Password!" if it doesn't match, or an authorization token if successful. The input data validation algorithm was chosen specifically for testing the vulnerability.



The table will contain the following data:











Authorization is working properly.



What about operators and aliases?









Aliases are denoted by the β€œ$” symbol, the syntax for aliases is similar to MongoDB. Search operators, comparisons and many others are available to us. Despite the strong typing of the data in the model, the transfer of data from the user to the ORM in JSON format entails normalization. And here the fun begins!



When trouble knocks on the DOM



Batching attack







This kind of request to the application initiates a request to the database:

Executing (default): With this attack, you can check many logins for a specific password for validity in one request to the server and vice versa. The attack works in the latest version of the library for December 2020 (6.3.5) and with the operatorsAliases option disabled. 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;











Data type conversion attack



If you pass data like ...







... to the application , then nothing will happen in our case. Although the logical condition in the database will be correct, checking the password in the application under study at the application level and comparing different data types cannot return true.



Comparison Operator Attack







According to the data in the screenshot, a query will be generated to the database of the form: The database returns data, since there is a match between username = admin and a password that is not equal to β€œaaa”. In order to go through the authorization process completely, we need to get a password.

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











Regex and string search attack



You can get the raw data by using the aliases of the $ like search operators or the $ regexp operators for working with regular expressions.







When the symbol does not converge, an error will be thrown that the user was not found.







If the symbol matches, there will be an error about the wrong password. A query of the form is executed into the database: Thus, character by character, you can restore data from the table.

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











Column comparison attack in a table



There is an interesting alias $ col that allows you to compare a field to a field.







The query to the database will: Execute the following query to the database: Thus, it will fulfill the logical condition at the database level.

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;









Getting rid of vulnerabilities



  • You need to install the latest version of the Sequalize library, where support for aliases has been removed.



    ( Source )

  • Disable the use of aliases by setting operatorAliases: false.
  • Thoroughly validate data types and their values ​​from the user before using them in the ORM.


Thank you for your interest!



All Articles