Skip to content

Commit 35b79a3

Browse files
Merge pull request #6370 from github/cavadalizada-GHSA-q2pj-6v73-8rgj
2 parents 1f2ea73 + d261a7a commit 35b79a3

File tree

1 file changed

+37
-6
lines changed

1 file changed

+37
-6
lines changed

advisories/unreviewed/2025/10/GHSA-q2pj-6v73-8rgj/GHSA-q2pj-6v73-8rgj.json

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
11
{
22
"schema_version": "1.4.0",
33
"id": "GHSA-q2pj-6v73-8rgj",
4-
"modified": "2025-10-29T18:30:33Z",
4+
"modified": "2025-10-29T18:30:40Z",
55
"published": "2025-10-29T18:30:33Z",
66
"aliases": [
77
"CVE-2025-60542"
88
],
9-
"details": "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.",
10-
"severity": [],
11-
"affected": [],
9+
"summary": "SQL Inection on TypeORM+MySQL Configuration on typeorm <= 0.3.25",
10+
"details": "### 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```\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&city=Riga&name=Javad\n`\n\n_OR_\n\n`{username:\"myusername\",phone:12345,name:\"Javad\"}\n`\n\nSQL query produced:\n\n```\nUPDATE `user` \nSET `username` = 'myusername', \n `city` = 'Riga', \n `name` = 'Javad' \nWHERE `id` IN (1);\n\n```\n\nMalicious Payload:\n\n`username=myusername&city[name]=Riga&city[role]=admin\n`\n_OR_\n\n`{username:\"myusername\",city:{name:\"Javad\",role:\"admin\"}}\n`\n\nSQL query produced with Injected Column:\n\n```\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)",
11+
"severity": [
12+
{
13+
"type": "CVSS_V4",
14+
"score": "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"
15+
}
16+
],
17+
"affected": [
18+
{
19+
"package": {
20+
"ecosystem": "npm",
21+
"name": "typeorm"
22+
},
23+
"ranges": [
24+
{
25+
"type": "ECOSYSTEM",
26+
"events": [
27+
{
28+
"introduced": "0"
29+
},
30+
{
31+
"fixed": "0.3.26"
32+
}
33+
]
34+
}
35+
],
36+
"database_specific": {
37+
"last_known_affected_version_range": "<= 0.3.25"
38+
}
39+
}
40+
],
1241
"references": [
1342
{
1443
"type": "ADVISORY",
@@ -32,8 +61,10 @@
3261
}
3362
],
3463
"database_specific": {
35-
"cwe_ids": [],
36-
"severity": null,
64+
"cwe_ids": [
65+
"CWE-89"
66+
],
67+
"severity": "CRITICAL",
3768
"github_reviewed": false,
3869
"github_reviewed_at": null,
3970
"nvd_published_at": "2025-10-29T16:15:34Z"

0 commit comments

Comments
 (0)