FeathersJS is a popular web framework for building flexible and real-time web APIs in Node.js. However, improper input validation in some versions of FeathersJS, specifically when used with the feathers-sequelize package, led to a serious vulnerability: CVE-2022-2422. This flaw allows attackers to perform SQL Injection attacks on backend databases.
In this post, we’ll break down what this vulnerability is, show example code, provide real-world exploit details, and offer tips on how to fix and prevent it.
What is CVE-2022-2422?
Simply put, CVE-2022-2422 exists because the FeathersJS implementation (through feathers-sequelize) didn't properly validate user input before passing it to the underlying SQL database. If an attacker sends specially crafted data, they can force the application to run unwanted SQL commands, risking database leaks, data manipulation, or even a full application compromise.
References
- CVE-2022-2422 at NIST
- GitHub FeathersJS Issue
Typically, a FeathersJS service using Sequelize looks like the following
// user.service.js
const { Service } = require('feathers-sequelize');
module.exports = function (app) {
const options = {
Model: app.get('sequelizeClient').models.user,
paginate: app.get('paginate')
};
// Register the service on the Feathers application
app.use('/users', new Service(options));
};
With this setup, clients may send queries such as
GET /users?username=alice
Internally, the query parsing is meant to be safe. However, if raw input is not sanitized or validated, an attacker can inject malicious content.
Consider a request like
GET /users?username[$like]=%'; DROP TABLE users; --
If input isn't validated, Sequelize might incorrectly build SQL such as
SELECT * FROM users WHERE username LIKE '%'; DROP TABLE users; --';
This statement would delete the entire 'users' table!
`
GET /users?username=admin
`
GET /users?username[$like]=%
`
GET /users?username[$like]=%' OR 1=1; --
If all users are returned, or if error messages reference SQL, the app is likely vulnerable.
NOTE: Never test this on a system you don’t own or have permission to test against.
Always validate and sanitize API input.
const { query } = require('express-validator');
app.get('/users', [
query('username').isAlphanumeric().trim().escape(), // restrict input
], (req, res) => {
// ... your handler
});
- Use Parameterized Queries:
Sequelize’s query methods allow you to pass parameters safely:
js
username: req.query.username
}
});
`
---
## Conclusion
CVE-2022-2422 demonstrates how even powerful frameworks can suffer from classic security pitfalls like SQL Injection if input isn’t carefully handled. Always validate incoming data, keep your dependencies updated, and remember: never trust user input – even if a library seems to do the right thing.
#### Further Reading
- Feathers Security Guide
- OWASP SQL Injection
- Sequelize Docs: Security
Stay secure!
Timeline
Published on: 10/26/2022 10:15:00 UTC
Last modified on: 02/28/2023 19:06:00 UTC