<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet href="/static/style.xsl" type="text/xsl"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>Most recent entries from all</title>
    <link>https://vulnerability.circl.lu</link>
    <description>Contains only the most 10 recent entries.</description>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Tue, 29 Sep 2026 19:49:33 +0000</lastBuildDate>
    <item>
      <title>GHSA-6457-6jrx-69cr — Sequelize v6 Vulnerable to SQL Injection via JSON Column Cast Type</title>
      <link>https://vulnerability.circl.lu/vuln/ghsa-6457-6jrx-69cr</link>
      <description>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; npm: sequelize&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;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 &amp;lt;type&amp;gt;)` SQL. An attacker who controls JSON object keys can inject arbitrary SQL and exfiltrate data from any table.&lt;/p&gt;
&lt;p&gt;Affected: v6.x through 6.37.7. v7 (`@sequelize/core`) is not affected.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;In `src/dialects/abstract/query-generator.js`, `_traverseJSON()` extracts a cast type from `::` in JSON keys without validation:&lt;/p&gt;
&lt;p&gt;```javascript
// line 1892
_traverseJSON(items, baseKey, prop, item, path) {
    let cast;
    if (path[path.length - 1].includes(&amp;#34;::&amp;#34;)) {
      const tmp = path[path.length - 1].split(&amp;#34;::&amp;#34;);
      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 }));
}
```&lt;/p&gt;
&lt;p&gt;`_castKey()` (line 1925) passes it to `Utils.Cast`, and `handleSequelizeMethod()` (line 1692) interpolates it directly:&lt;/p&gt;
&lt;p&gt;```javascript
return `CAST(${result} AS ${smth.type.toUpperCase()})`;
```&lt;/p&gt;
&lt;p&gt;JSON path **values** are escaped via `this.escape()` in `jsonPathExtractionQuery()`, but the cast **type** is not.&lt;/p&gt;
&lt;p&gt;**Suggested fix** — whitelist known SQL data types:&lt;/p&gt;
&lt;p&gt;```javascript
const ALLOWED_CAST_TYPES = new Set([
  &amp;#39;integer&amp;#39;, &amp;#39;text&amp;#39;, &amp;#39;real&amp;#39;, &amp;#39;numeric&amp;#39;, &amp;#39;boolean&amp;#39;, &amp;#39;date&amp;#39;,
  &amp;#39;timestamp&amp;#39;, &amp;#39;timestamptz&amp;#39;, &amp;#39;json&amp;#39;, &amp;#39;jsonb&amp;#39;, &amp;#39;float&amp;#39;,
  &amp;#39;do…&lt;/p&gt;</description>
      <content:encoded>&lt;p&gt;&lt;strong&gt;Affected:&lt;/strong&gt; npm: sequelize&lt;/p&gt;
&lt;p&gt;### Summary&lt;/p&gt;
&lt;p&gt;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 &amp;lt;type&amp;gt;)` SQL. An attacker who controls JSON object keys can inject arbitrary SQL and exfiltrate data from any table.&lt;/p&gt;
&lt;p&gt;Affected: v6.x through 6.37.7. v7 (`@sequelize/core`) is not affected.&lt;/p&gt;
&lt;p&gt;### Details&lt;/p&gt;
&lt;p&gt;In `src/dialects/abstract/query-generator.js`, `_traverseJSON()` extracts a cast type from `::` in JSON keys without validation:&lt;/p&gt;
&lt;p&gt;```javascript
// line 1892
_traverseJSON(items, baseKey, prop, item, path) {
    let cast;
    if (path[path.length - 1].includes(&amp;#34;::&amp;#34;)) {
      const tmp = path[path.length - 1].split(&amp;#34;::&amp;#34;);
      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 }));
}
```&lt;/p&gt;
&lt;p&gt;`_castKey()` (line 1925) passes it to `Utils.Cast`, and `handleSequelizeMethod()` (line 1692) interpolates it directly:&lt;/p&gt;
&lt;p&gt;```javascript
return `CAST(${result} AS ${smth.type.toUpperCase()})`;
```&lt;/p&gt;
&lt;p&gt;JSON path **values** are escaped via `this.escape()` in `jsonPathExtractionQuery()`, but the cast **type** is not.&lt;/p&gt;
&lt;p&gt;**Suggested fix** — whitelist known SQL data types:&lt;/p&gt;
&lt;p&gt;```javascript
const ALLOWED_CAST_TYPES = new Set([
  &amp;#39;integer&amp;#39;, &amp;#39;text&amp;#39;, &amp;#39;real&amp;#39;, &amp;#39;numeric&amp;#39;, &amp;#39;boolean&amp;#39;, &amp;#39;date&amp;#39;,
  &amp;#39;timestamp&amp;#39;, &amp;#39;timestamptz&amp;#39;, &amp;#39;json&amp;#39;, &amp;#39;jsonb&amp;#39;, &amp;#39;float&amp;#39;,
  &amp;#39;do…&lt;/p&gt;</content:encoded>
      <guid isPermaLink="false">https://vulnerability.circl.lu/vuln/ghsa-6457-6jrx-69cr</guid>
    </item>
  </channel>
</rss>
