VYPR
High severityNVD Advisory· Published May 29, 2018· Updated Sep 17, 2024

CVE-2016-10556

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.

PackageAffected versionsPatched versions
sequelizenpm
< 3.20.03.20.0

Affected products

2
  • ghsa-coords
    Range: < 3.20.0
  • HackerOne/sequelize node modulev5
    Range: <=3.19.3

Patches

1
23952a2b020c

Fix 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.

https://github.com/sequelize/sequelizeMichael BuckleyFeb 8, 2016via ghsa
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

News mentions

0

No linked articles in our index yet.