CVE-2016-10556
Description
sequelize is an Object-relational mapping, or a middleman to convert things from Postgres, MySQL, MariaDB, SQLite and Microsoft SQL Server into usable data for NodeJS In Postgres, SQLite, and Microsoft SQL Server there is an issue where arrays are treated as strings and improperly escaped. This causes potential SQL injection in sequelize 3.19.3 and earlier, where a malicious user could put ["test", "'); DELETE TestTable WHERE Id = 1 --')"] inside of `` database.query('SELECT * FROM TestTable WHERE Name IN (:names)', { replacements: { names: directCopyOfUserInput } }); ` and cause the SQL statement to become SELECT Id FROM Table WHERE Name IN ('test', '\'); DELETE TestTable WHERE Id = 1 --')`. In Postgres, MSSQL, and SQLite, the backslash has no special meaning. This causes the the statement to delete whichever Id has a value of 1 in the TestTable table.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Sequelize 3.19.3 and earlier has SQL injection in Postgres, SQLite, and MSSQL due to improper array escaping in query replacements.
Vulnerability
Sequelize versions 3.19.3 and earlier have an SQL injection vulnerability in Postgres, SQLite, and Microsoft SQL Server when using arrays as replacements in parameterized queries. The arrays are treated as strings and improperly escaped, allowing an attacker to inject malicious SQL [1][3][4].
Exploitation
An attacker can pass a crafted array, such as ["test", "'); DELETE TestTable WHERE Id = 1 --')"], as a replacement value for a named parameter in a database.query() call. The improper escaping causes the backslash to lose its escaping meaning, enabling the injection [1].
Impact
Successful exploitation allows an attacker to execute arbitrary SQL statements, potentially leading to data deletion, modification, or disclosure. The example in the advisory demonstrates deletion of a row from a table [1].
Mitigation
The vulnerability is fixed in sequelize v3.20.0 [2][3]. Users should upgrade to v3.20.0 or later. If upgrading is not immediately possible, avoid using user-supplied input directly in array replacements for PostgreSQL, SQLite, and MSSQL queries until a patch is applied.
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
sequelizenpm | < 3.20.0 | 3.20.0 |
Affected products
2- HackerOne/sequelize node modulev5Range: <=3.19.3
Patches
123952a2b020cFix bug in SqlString.escape which caused the function to be recursively called with the wrong parameters when passed an array of strings. This would cause the incorrect escape algorithm to be used on the strings within the array when the dialect was set to postgres, sqlite, or mssql.
3 files changed · +11 −1
changelog.md+1 −0 modified@@ -3,6 +3,7 @@ - [ADDED] `validationFailed` hook [#1626](https://github.com/sequelize/sequelize/issues/1626) - [FIXED] Mark index as `unique: true` when `type: 'UNIQUE'`. Fixes [#5351](https://github.com/sequelize/sequelize/issues/5351) - [ADDED[ Support for IEEE floating point literals in postgres and sqlite [#5194](https://github.com/sequelize/sequelize/issues/5194) +- [FIXED] Improper escaping of bound arrays of strings on Postgres, SQLite, and Microsoft SQL Server # 3.19.3 - [FIXED] `updatedAt` and `createdAt` values are now set before validation [#5367](https://github.com/sequelize/sequelize/pull/5367)
lib/sql-string.js+1 −1 modified@@ -48,7 +48,7 @@ SqlString.escape = function(val, timeZone, dialect, format) { } if (Array.isArray(val)) { - var escape = _.partialRight(SqlString.escape, timeZone, dialect); + var escape = _.partial(SqlString.escape, _, timeZone, dialect, format); if (dialect === 'postgres' && !format) { return dataTypes.ARRAY.prototype.stringify(val, {escape: escape}); }
test/integration/sequelize.test.js+9 −0 modified@@ -583,6 +583,15 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() { }); }); + if (dialect === 'postgres' || dialect === 'sqlite' || dialect === 'mssql') { + it ('does not improperly escape arrays of strings bound to named parameters', function() { + var logSql; + return this.sequelize.query('select :stringArray as foo', { raw: true, replacements: { stringArray: [ '"string"' ] }, logging: function(s) { logSql = s; } }).then(function(result) { + expect(result[0]).to.deep.equal([{ foo: '"string"' }]); + }); + }); + } + it('throw an exception when binds passed with object and numeric $1 is also present', function() { var self = this; var typeCast = (dialect === 'postgres') ? '::int' : '';
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-9c2p-jw8p-f84vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2016-10556ghsaADVISORY
- github.com/sequelize/sequelize/commit/23952a2b020cc3571f090e67dae7feb084e1be71ghsaWEB
- github.com/sequelize/sequelize/commits/v3.20.0ghsaWEB
- github.com/sequelize/sequelize/issues/5671ghsax_refsource_MISCWEB
- nodesecurity.io/advisories/102mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.