Node.js MySQL Prepared Statement Object Injection
Description
Node.js applications using the mysql or mysql2 NPM packages contain a critical vulnerability where prepared statements do not properly sanitize JavaScript objects and arrays passed as query parameters. Instead of treating these as literal values, the libraries automatically convert them into SQL fragments, enabling attackers to inject SQL operators and column references that alter query logic. This undermines the security guarantees of prepared statements and can occur even when developers follow secure coding practices.
Remediation
Implement the following mitigations to prevent object injection in MySQL queries:
1. Enable the stringifyObjects option in your MySQL connection configuration to force objects and arrays to be converted to strings rather than SQL fragments:
const mysql = require('mysql');
const db = mysql.createConnection({
host: 'localhost',
user: 'user',
password: 'password',
database: 'database',
stringifyObjects: true // Prevents object-to-SQL conversion
});2. Implement input validation to reject objects and arrays where scalar values are expected:
function validateInput(param) {
if (typeof param === 'object' && param !== null) {
throw new Error('Objects and arrays not allowed');
}
return param;
}3. Use type checking middleware or schema validation libraries (such as Joi or Yup) to enforce expected parameter types before they reach database queries.
4. Review all database queries that accept user input and ensure proper type validation is in place, even when using prepared statements.