{"id":"CVE-2025-60542","aliases":["EUVD-2025-36689","GHSA-q2pj-6v73-8rgj","ROOT-APP-NPM-CVE-2025-60542"],"status":"published","title":"TypeORM vulnerable to SQL injection via crafted request to repository.save or repository.update","description":"SQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.","severity":{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium","assessor":"adp","from":"cve"},"epss":{"day":"2026-11-12","score":0.00265,"percentile":0.18554,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-89"],"published":"2025-10-29T00:00:00Z","modified":"2026-10-29T02:30:29Z","fixes":[{"ecosystem":"npm","package":"typeorm","fixed_in":["0.3.26"],"sources":["ghsa","osv"]},{"ecosystem":"Root:npm","package":"typeorm","fixed_in":["0.3.19-aikido.1"],"sources":["osv"]},{"ecosystem":"Root:npm","package":"@rootio/typeorm","fixed_in":["0.3.19-root.io.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.26"}]}]},{"source":"osv","ecosystem":"npm","package":"typeorm","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.3.26"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.19-aikido.1"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"@rootio/typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.19-root.io.1"}]}]}],"references":[{"url":"https://github.com/typeorm/typeorm/releases?q=security\u0026expanded=true","tags":["package","web"]},{"url":"https://github.com/typeorm/typeorm/pull/11574","tags":["fix","web"]},{"url":"https://github.com/typeorm/typeorm/releases/tag/0.3.26","tags":["web"]},{"url":"https://medium.com/@alizada.cavad/cve-2025-60542-typeorm-mysql-sqli-0-3-25-a1b32bc60453","tags":["web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2025-60542","tags":["advisory"]},{"url":"https://github.com/typeorm/typeorm/commit/d57fe3bd8578b0b8f9847647fd046bccf825a7ef","tags":["web"]},{"url":"https://github.com/mysqljs/sqlstring/blob/cd528556b4b6bcf300c3db515026935dedf7cfa1/lib/SqlString.js#L54","tags":["web"]},{"url":"https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/base/connection.js#L524","tags":["web"]},{"url":"https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/connection_config.js#L124","tags":["web"]},{"url":"https://github.com/typeorm/typeorm/blob/0.3.25/src/driver/mysql/MysqlConnectionOptions.ts","tags":["web"]},{"url":"https://github.com/advisories/GHSA-q2pj-6v73-8rgj"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/60xxx/CVE-2025-60542.json","tags":["advisory"]},{"url":"http://github.com/typeorm/typeorm","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2025-60542","description":"SQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.","status":"published","published":"2025-10-29T00:00:00Z","modified":"2025-10-30T20:28:41.544Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium","assessor":"adp"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T14:32:39.719629Z"}],"euvd":[{"id":"EUVD-2025-36689","description":"SQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.","status":"published","published":"2025-10-29T00:00:00Z","modified":"2025-10-30T20:28:41Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T19:49:35.368666Z"}],"ghsa":[{"id":"GHSA-q2pj-6v73-8rgj","title":"TypeORM vulnerable to SQL injection via crafted request to repository.save or repository.update","description":"### Summary\n\nSQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.\n\n### Details\n\nVulnerable Code:\n\n```js\nconst { username, city, name} = req.body;\nconst updateData = {\n    username,\n    city,\n    name,\n    id:userId\n  }; // Developer aims to only allow above three fields to be updated    \nconst result = await userRepo.save(updateData);\n```\n\nIntended Payload (non-malicious):\n\n\n`\nusername=myusername\u0026city=Riga\u0026name=Javad\n`\n\n_OR_\n\n`{username:\\\"myusername\\\",phone:12345,name:\\\"Javad\\\"}\n`\n\nSQL query produced:\n\n```sql\nUPDATE `user` \nSET `username` = 'myusername', \n    `city` = 'Riga', \n    `name` = 'Javad' \nWHERE `id` IN (1);\n\n```\n\nMalicious Payload:\n\n`username=myusername\u0026city[name]=Riga\u0026city[role]=admin\n`\n\n_OR_\n\n`{username:\\\"myusername\\\",city:{name:\\\"Javad\\\",role:\\\"admin\\\"}}\n`\n\nSQL query produced with Injected Column:\n\n```sql\nUPDATE `user` \nSET `username` = 'myusername', \n    `city` = `name` = 'Javad', \n    `role` = 'admin' \nWHERE `id` IN (1);\n\n```\n_Above query is valid as `city` = `name` = `Javad` is a boolean expression resulting in `city` = 1 (false). “role” column is injected and updated._\n\nUnderlying issue was due to TypeORM using mysql2 [without specifying a value for the stringifyObjects option](https://github.com/typeorm/typeorm/blob/0.3.25/src/driver/mysql/MysqlConnectionOptions.ts). In both mysql and mysql2 this [option defaults to false](https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/connection_config.js#L124). This option is then passed into [SQLString library as false](https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/base/connection.js#L524). This results in sqlstring [parsing objects in a strange way using objectToValues.](https://github.com/mysqljs/sqlstring/blob/cd528556b4b6bcf300c3db515026935dedf7cfa1/lib/SqlString.js#L54)","status":"published","published":"2025-10-29T18:30:33Z","modified":"2025-10-31T17:38:01Z","cvss":[{"version":"4.0","score":8.9,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:L/SC:L/SI:H/SA:L/E:P","level":"high"},{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T14:39:04.350802Z"}],"nvd":[{"id":"CVE-2025-60542","description":"SQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.","status":"published","published":"2025-10-29T16:15:34.057Z","modified":"2026-10-27T12:10:00.343Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T14:11:41.607433Z"}],"osv":[{"id":"CVE-2025-60542","description":"SQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.","status":"published","published":"2025-10-29T00:00:00Z","modified":"2026-10-29T02:30:29.79411376Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:44:51.516975Z"},{"id":"GHSA-q2pj-6v73-8rgj","title":"TypeORM vulnerable to SQL injection via crafted request to repository.save or repository.update","description":"### Summary\n\nSQL Injection vulnerability in TypeORM before 0.3.26 via crafted request to repository.save or repository.update due to the sqlstring call using stringifyObjects default to false.\n\n### Details\n\nVulnerable Code:\n\n```js\nconst { username, city, name} = req.body;\nconst updateData = {\n    username,\n    city,\n    name,\n    id:userId\n  }; // Developer aims to only allow above three fields to be updated    \nconst result = await userRepo.save(updateData);\n```\n\nIntended Payload (non-malicious):\n\n\n`\nusername=myusername\u0026city=Riga\u0026name=Javad\n`\n\n_OR_\n\n`{username:\\\"myusername\\\",phone:12345,name:\\\"Javad\\\"}\n`\n\nSQL query produced:\n\n```sql\nUPDATE `user` \nSET `username` = 'myusername', \n    `city` = 'Riga', \n    `name` = 'Javad' \nWHERE `id` IN (1);\n\n```\n\nMalicious Payload:\n\n`username=myusername\u0026city[name]=Riga\u0026city[role]=admin\n`\n\n_OR_\n\n`{username:\\\"myusername\\\",city:{name:\\\"Javad\\\",role:\\\"admin\\\"}}\n`\n\nSQL query produced with Injected Column:\n\n```sql\nUPDATE `user` \nSET `username` = 'myusername', \n    `city` = `name` = 'Javad', \n    `role` = 'admin' \nWHERE `id` IN (1);\n\n```\n_Above query is valid as `city` = `name` = `Javad` is a boolean expression resulting in `city` = 1 (false). “role” column is injected and updated._\n\nUnderlying issue was due to TypeORM using mysql2 [without specifying a value for the stringifyObjects option](https://github.com/typeorm/typeorm/blob/0.3.25/src/driver/mysql/MysqlConnectionOptions.ts). In both mysql and mysql2 this [option defaults to false](https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/connection_config.js#L124). This option is then passed into [SQLString library as false](https://github.com/sidorares/node-mysql2/blob/e359f454a76ba5dc31b91adf7bdb4099ca317bb5/lib/base/connection.js#L524). This results in sqlstring [parsing objects in a strange way using objectToValues.](https://github.com/mysqljs/sqlstring/blob/cd528556b4b6bcf300c3db515026935dedf7cfa1/lib/SqlString.js#L54)","status":"published","published":"2025-10-29T18:30:33Z","modified":"2026-09-10T03:50:30.128177147Z","cvss":[{"version":"3.1","score":6.5,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N","level":"medium"},{"version":"4.0","score":8.9,"vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:L/SC:L/SI:H/SA:L/E:P","level":"high"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T15:46:53.700556Z"},{"id":"ROOT-APP-NPM-CVE-2025-60542","title":"CVE-2025-60542 in typeorm - Patched by Root","description":"Root has patched CVE-2025-60542 in the typeorm package for Root:npm. Multiple fixed versions available.","status":"published","published":"2026-08-24T06:30:16Z","modified":"2026-08-24T08:15:10.950859327Z","updated_at":"2026-11-02T15:53:27.362922Z"}]}}
