{"id":"GHSA-9ggv-8w38-r7pm","aliases":["ROOT-APP-NPM-GHSA-9ggv-8w38-r7pm"],"status":"published","title":"TypeORM: SQL Injection in UpdateQueryBuilder/SoftDeleteQueryBuilder orderBy (MySQL/MariaDB)","description":"### Impact\n\nBlind SQL injection vulnerability in `UpdateQueryBuilder` and `SoftDeleteQueryBuilder` affecting MySQL and MariaDB users.\n\n`UpdateQueryBuilder` and `SoftDeleteQueryBuilder` (including their `addOrderBy` variants) do not validate the `order` parameter against an allowlist of permitted values (`ASC`/`DESC`). The caller-supplied value is stored verbatim and concatenated directly into the generated SQL string without quoting or parameterization. `SelectQueryBuilder.orderBy` performs this validation correctly; the affected builders do not.\n\nIf any code path passes user-controlled input to `orderBy`/`addOrderBy` on an update or soft-delete query, an attacker can inject arbitrary SQL via the sort direction — even when the column name itself is hardcoded.\n\nDemonstrated impact includes:\n- **Data exfiltration** via time-based blind extraction (e.g. using `SLEEP()` to infer secret values bit by bit)\n- **Row targeting manipulation** in queries using `LIMIT` patterns\n- **Denial of service** via `SLEEP()`-based query exhaustion\n\nCVSS 3.1: **8.6 (High)** — `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L`\n\nAffected files (relative to commit `73fda419`):\n- `src/query-builder/UpdateQueryBuilder.ts`: lines 383–419 and 718–744\n- `src/query-builder/SoftDeleteQueryBuilder.ts`: lines 352–388 and 520–546\n\nThe vulnerability was introduced in commit `03799bd2` (v0.1.12) and is present through the latest release (v0.3.28).\n\n### Patches\n\nA fix has been released in 0.3.29 (1b66c44) and 1.0.0 (93eec63).\n\n### Workarounds\n\nApplications can manually validate the `order` argument before passing it to `orderBy` or `addOrderBy` on update or soft-delete query builders:\n\n```ts\nconst direction = userInput.toUpperCase();\nif (direction !== 'ASC' \u0026\u0026 direction !== 'DESC') {\n  throw new Error('Invalid sort direction');\n}\nqb.orderBy(column, direction as 'ASC' | 'DESC');\n```\n\nDo not pass user-controlled values to `orderBy`/`addOrderBy` on `UpdateQueryBuilder` or `SoftDeleteQueryBuilder` without this validation.\n\n### References\n\n- Introduced in commit 03799bd2 (v0.1.12)\n- Confirmed present in v0.3.28 (commit 73fda419)\n- See `SelectQueryBuilder.orderBy` for the correct validation pattern this fix should mirror","severity":{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium","from":"ghsa"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-89"],"published":"2026-06-19T19:18:49Z","modified":"2026-09-10T03:50:49Z","fixes":[{"ecosystem":"npm","package":"typeorm","fixed_in":["0.3.29"],"sources":["ghsa","osv"]},{"ecosystem":"Root:npm","package":"@rootio/typeorm","fixed_in":["0.3.28-root.io.1"],"sources":["osv"]},{"ecosystem":"Root:npm","package":"typeorm","fixed_in":["0.3.28-aikido.1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0.1.12"},{"last_affected":"0.3.28"},{"fixed":"0.3.29"}]}]},{"source":"osv","ecosystem":"npm","package":"typeorm","ranges":[{"type":"SEMVER","events":[{"introduced":"0.1.12"},{"fixed":"0.3.29"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"@rootio/typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.28-root.io.1"}]}]},{"source":"osv","ecosystem":"Root:npm","package":"typeorm","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"0.3.28-aikido.1"}]}]}],"references":[{"url":"https://github.com/typeorm/typeorm/security/advisories/GHSA-9ggv-8w38-r7pm","tags":["web"]},{"url":"https://github.com/typeorm/typeorm/commit/1b66c44d0410bdc56a0dcefb46be41867ec0fffc","tags":["web"]},{"url":"https://github.com/typeorm/typeorm/commit/93eec630630b219b162ba4e0c072afa851697cff","tags":["web"]},{"url":"https://github.com/advisories/GHSA-9ggv-8w38-r7pm"},{"url":"https://github.com/typeorm/typeorm","tags":["package"]}],"sources":{"ghsa":[{"id":"GHSA-9ggv-8w38-r7pm","title":"TypeORM: SQL Injection in UpdateQueryBuilder/SoftDeleteQueryBuilder orderBy (MySQL/MariaDB)","description":"### Impact\n\nBlind SQL injection vulnerability in `UpdateQueryBuilder` and `SoftDeleteQueryBuilder` affecting MySQL and MariaDB users.\n\n`UpdateQueryBuilder` and `SoftDeleteQueryBuilder` (including their `addOrderBy` variants) do not validate the `order` parameter against an allowlist of permitted values (`ASC`/`DESC`). The caller-supplied value is stored verbatim and concatenated directly into the generated SQL string without quoting or parameterization. `SelectQueryBuilder.orderBy` performs this validation correctly; the affected builders do not.\n\nIf any code path passes user-controlled input to `orderBy`/`addOrderBy` on an update or soft-delete query, an attacker can inject arbitrary SQL via the sort direction — even when the column name itself is hardcoded.\n\nDemonstrated impact includes:\n- **Data exfiltration** via time-based blind extraction (e.g. using `SLEEP()` to infer secret values bit by bit)\n- **Row targeting manipulation** in queries using `LIMIT` patterns\n- **Denial of service** via `SLEEP()`-based query exhaustion\n\nCVSS 3.1: **8.6 (High)** — `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L`\n\nAffected files (relative to commit `73fda419`):\n- `src/query-builder/UpdateQueryBuilder.ts`: lines 383–419 and 718–744\n- `src/query-builder/SoftDeleteQueryBuilder.ts`: lines 352–388 and 520–546\n\nThe vulnerability was introduced in commit `03799bd2` (v0.1.12) and is present through the latest release (v0.3.28).\n\n### Patches\n\nA fix has been released in 0.3.29 (1b66c44) and 1.0.0 (93eec63).\n\n### Workarounds\n\nApplications can manually validate the `order` argument before passing it to `orderBy` or `addOrderBy` on update or soft-delete query builders:\n\n```ts\nconst direction = userInput.toUpperCase();\nif (direction !== 'ASC' \u0026\u0026 direction !== 'DESC') {\n  throw new Error('Invalid sort direction');\n}\nqb.orderBy(column, direction as 'ASC' | 'DESC');\n```\n\nDo not pass user-controlled values to `orderBy`/`addOrderBy` on `UpdateQueryBuilder` or `SoftDeleteQueryBuilder` without this validation.\n\n### References\n\n- Introduced in commit 03799bd2 (v0.1.12)\n- Confirmed present in v0.3.28 (commit 73fda419)\n- See `SelectQueryBuilder.orderBy` for the correct validation pattern this fix should mirror","status":"published","published":"2026-06-19T19:18:49Z","modified":"2026-06-19T19:18:51Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T14:40:30.53004Z"}],"osv":[{"id":"GHSA-9ggv-8w38-r7pm","title":"TypeORM: SQL Injection in UpdateQueryBuilder/SoftDeleteQueryBuilder orderBy (MySQL/MariaDB)","description":"### Impact\n\nBlind SQL injection vulnerability in `UpdateQueryBuilder` and `SoftDeleteQueryBuilder` affecting MySQL and MariaDB users.\n\n`UpdateQueryBuilder` and `SoftDeleteQueryBuilder` (including their `addOrderBy` variants) do not validate the `order` parameter against an allowlist of permitted values (`ASC`/`DESC`). The caller-supplied value is stored verbatim and concatenated directly into the generated SQL string without quoting or parameterization. `SelectQueryBuilder.orderBy` performs this validation correctly; the affected builders do not.\n\nIf any code path passes user-controlled input to `orderBy`/`addOrderBy` on an update or soft-delete query, an attacker can inject arbitrary SQL via the sort direction — even when the column name itself is hardcoded.\n\nDemonstrated impact includes:\n- **Data exfiltration** via time-based blind extraction (e.g. using `SLEEP()` to infer secret values bit by bit)\n- **Row targeting manipulation** in queries using `LIMIT` patterns\n- **Denial of service** via `SLEEP()`-based query exhaustion\n\nCVSS 3.1: **8.6 (High)** — `AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L`\n\nAffected files (relative to commit `73fda419`):\n- `src/query-builder/UpdateQueryBuilder.ts`: lines 383–419 and 718–744\n- `src/query-builder/SoftDeleteQueryBuilder.ts`: lines 352–388 and 520–546\n\nThe vulnerability was introduced in commit `03799bd2` (v0.1.12) and is present through the latest release (v0.3.28).\n\n### Patches\n\nA fix has been released in 0.3.29 (1b66c44) and 1.0.0 (93eec63).\n\n### Workarounds\n\nApplications can manually validate the `order` argument before passing it to `orderBy` or `addOrderBy` on update or soft-delete query builders:\n\n```ts\nconst direction = userInput.toUpperCase();\nif (direction !== 'ASC' \u0026\u0026 direction !== 'DESC') {\n  throw new Error('Invalid sort direction');\n}\nqb.orderBy(column, direction as 'ASC' | 'DESC');\n```\n\nDo not pass user-controlled values to `orderBy`/`addOrderBy` on `UpdateQueryBuilder` or `SoftDeleteQueryBuilder` without this validation.\n\n### References\n\n- Introduced in commit 03799bd2 (v0.1.12)\n- Confirmed present in v0.3.28 (commit 73fda419)\n- See `SelectQueryBuilder.orderBy` for the correct validation pattern this fix should mirror","status":"published","published":"2026-06-19T19:18:49Z","modified":"2026-09-10T03:50:49.287611219Z","cvss":[{"version":"3.1","score":5.9,"vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","level":"medium"}],"cwes":["CWE-89"],"updated_at":"2026-11-02T15:46:43.875515Z"},{"id":"ROOT-APP-NPM-GHSA-9ggv-8w38-r7pm","title":"GHSA-9ggv-8w38-r7pm in @rootio/typeorm - Patched by Root","description":"Root has patched GHSA-9ggv-8w38-r7pm in the @rootio/typeorm package for Root:npm. Multiple fixed versions available.","status":"published","published":"2026-07-27T12:11:24Z","modified":"2026-07-27T19:45:07.921673449Z","updated_at":"2026-11-02T15:53:27.940619Z"}]}}
