CVE-2026-73651
TypeORM: migration:generate template-literal code injection
TypeORM is a TypeScript and JavaScript ORM for Node.js that supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and other databases. Prior to versions 0.3.31 and 1.1.0, typeorm migration:generate embeds database schema metadata into JavaScript or TypeScript template literals in src/commands/MigrationGenerateCommand.ts, escaping backticks but not ${...} interpolation. An attacker with database schema write access can place a payload in column COMMENT or DEFAULT metadata, or another introspected schema string, and the JavaScript engine evaluates the payload when the generated migration is loaded through migration:run, import, or require. This issue is fixed in versions 0.3.31 and 1.1.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- High
- User interaction
- Required
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.7
TypeORM: migration:generate template-literal code injection
TypeORM is a TypeScript and JavaScript ORM for Node.js that supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and other databases. Prior to versions 0.3.31 and 1.1.0, typeorm migration:generate embeds database schema metadata into JavaScript or TypeScript template literals in src/commands/MigrationGenerateCommand.ts, escaping backticks but not ${...} interpolation. An attacker with database schema write access can place a payload in column COMMENT or DEFAULT metadata, or another introspected schema string, and the JavaScript engine evaluates the payload when the generated migration is loaded through migration:run, import, or require. This issue is fixed in versions 0.3.31 and 1.1.0.
- Record
CVE-2026-73651- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-94
- Updated
- 2026-11-02
EUVDEUVD-2026-58194
5.7
TypeORM is a TypeScript and JavaScript ORM for Node.js that supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and other databases. Prior to versions 0.3.31 and 1.1.0, typeorm migration:generate embeds database schema metadata into JavaScript or TypeScript template literals in src/commands/MigrationGenerateCommand.ts, escaping backticks but not ${...} interpolation. An attacker with database schema write access can place a payload in column COMMENT or DEFAULT metadata, or another introspected schema string, and the JavaScript engine evaluates the payload when the generated migration is loaded through migration:run, import, or require. This issue is fixed in versions 0.3.31 and 1.1.0.
- Record
EUVD-2026-58194- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-2rp8-mm9q-fp49
5.7
TypeORM: migration:generate template-literal code injection
Summary
typeorm migration:generate embeds database schema metadata into JS/TS template literals, escaping backticks but not ${...}. An attacker who can write schema metadata (column comments, defaults, view definitions) achieves arbitrary code execution on the host that loads the generated migration.
Details
MigrationGenerateCommand.ts (L117-138) wraps each SQL statement in a JS template literal, escaping only backticks:
" await queryRunner.query(`" +
upQuery.query.replaceAll("`", "\\`") +
"`" + ...
Introspected schema strings reach this sink through driver query runners:
| Driver | Metadata source | Source |
|---|---|---|
| Postgres | column DEFAULT, COMMENT, CHECK constraints, view definitions | PostgresQueryRunner.ts:1782, L1898, L2287, L4125 |
| MySQL/MariaDB | COLUMN_DEFAULT, COLUMN_COMMENT | MysqlQueryRunner.ts:2873-2974, L3580-3583 |
| CockroachDB | Same patterns as Postgres | CockroachQueryRunner.ts |
escapeComment() on each driver strips only null bytes, leaving ${...} intact:
protected escapeComment(comment?: string) {
if (!comment) return comment
comment = comment.replaceAll("\u0000", "")
return comment
}
When the migration file is loaded (migration:run, import, or require), the JS engine evaluates ${...} as live interpolation.
Affected source:
| File | Lines | Role |
|---|---|---|
| MigrationGenerateCommand.ts | 117-138 | Template-literal construction (sink) |
| PostgresDriver.ts | 1886-1891 | escapeComment() — Postgres |
| MysqlDriver.ts | 1322-1328 | escapeComment() — MySQL |
| CockroachDriver.ts | 1236-1241 | escapeComment() — CockroachDB |
Confirmed injection vectors (MySQL):
| Vector | Result | Notes |
|---|---|---|
| Column COMMENT | Confirmed | Proven in PoC below |
| Column DEFAULT | Confirmed | Attacker sets ALTER TABLE ... DEFAULT '${...}'; payload appears in generated migration |
| CHECK constraint | Not exploitable | MySQL information_schema.CHECK_CONSTRAINTS strips content from CHECK_CLAUSE |
| View definitions | Not tested | Requires PostgreSQL ViewEntity introspection; likely exploitable via pg_get_viewdef() |
Suggested fix: Escape ${ to \${ (and \\ to \\\\) before embedding query strings into template literals, or switch to emitting the SQL as a JSON.stringify()-encoded regular string argument.
PoC
Prerequisites:
- Any supported RDBMS (PostgreSQL, MySQL, MariaDB, CockroachDB, SQL Server, Oracle, SAP HANA, or Spanner) accessible to the developer running
migration:generate - The attacker has DDL/write access to the database, or the application exposes a feature allowing users to set column
COMMENT,DEFAULT, or view definition text
Steps:
- Inject payload into schema metadata. Set a column comment or default…
- Record
GHSA-2rp8-mm9q-fp49- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-94
- Updated
- 2026-11-02
NVD
5.7
TypeORM is a TypeScript and JavaScript ORM for Node.js that supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and other databases. Prior to versions 0.3.31 and 1.1.0, typeorm migration:generate embeds database schema metadata into JavaScript or TypeScript template literals in src/commands/MigrationGenerateCommand.ts, escaping backticks but not ${...} interpolation. An attacker with database schema write access can place a payload in column COMMENT or DEFAULT metadata, or another introspected schema string, and the JavaScript engine evaluates the payload when the generated migration is loaded through migration:run, import, or require. This issue is fixed in versions 0.3.31 and 1.1.0.
- Record
CVE-2026-73651- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-94
- Updated
- 2026-11-02
OSV
5.7
TypeORM: migration:generate template-literal code injection
TypeORM is a TypeScript and JavaScript ORM for Node.js that supports PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, and other databases. Prior to versions 0.3.31 and 1.1.0, typeorm migration:generate embeds database schema metadata into JavaScript or TypeScript template literals in src/commands/MigrationGenerateCommand.ts, escaping backticks but not ${...} interpolation. An attacker with database schema write access can place a payload in column COMMENT or DEFAULT metadata, or another introspected schema string, and the JavaScript engine evaluates the payload when the generated migration is loaded through migration:run, import, or require. This issue is fixed in versions 0.3.31 and 1.1.0.
- Record
CVE-2026-73651- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-94
- Updated
- 2026-11-02
OSVGHSA-2rp8-mm9q-fp49
5.7
TypeORM: migration:generate template-literal code injection
Summary
typeorm migration:generate embeds database schema metadata into JS/TS template literals, escaping backticks but not ${...}. An attacker who can write schema metadata (column comments, defaults, view definitions) achieves arbitrary code execution on the host that loads the generated migration.
Details
MigrationGenerateCommand.ts (L117-138) wraps each SQL statement in a JS template literal, escaping only backticks:
" await queryRunner.query(`" +
upQuery.query.replaceAll("`", "\\`") +
"`" + ...
Introspected schema strings reach this sink through driver query runners:
| Driver | Metadata source | Source |
|---|---|---|
| Postgres | column DEFAULT, COMMENT, CHECK constraints, view definitions | PostgresQueryRunner.ts:1782, L1898, L2287, L4125 |
| MySQL/MariaDB | COLUMN_DEFAULT, COLUMN_COMMENT | MysqlQueryRunner.ts:2873-2974, L3580-3583 |
| CockroachDB | Same patterns as Postgres | CockroachQueryRunner.ts |
escapeComment() on each driver strips only null bytes, leaving ${...} intact:
protected escapeComment(comment?: string) {
if (!comment) return comment
comment = comment.replaceAll("\u0000", "")
return comment
}
When the migration file is loaded (migration:run, import, or require), the JS engine evaluates ${...} as live interpolation.
Affected source:
| File | Lines | Role |
|---|---|---|
| MigrationGenerateCommand.ts | 117-138 | Template-literal construction (sink) |
| PostgresDriver.ts | 1886-1891 | escapeComment() — Postgres |
| MysqlDriver.ts | 1322-1328 | escapeComment() — MySQL |
| CockroachDriver.ts | 1236-1241 | escapeComment() — CockroachDB |
Confirmed injection vectors (MySQL):
| Vector | Result | Notes |
|---|---|---|
| Column COMMENT | Confirmed | Proven in PoC below |
| Column DEFAULT | Confirmed | Attacker sets ALTER TABLE ... DEFAULT '${...}'; payload appears in generated migration |
| CHECK constraint | Not exploitable | MySQL information_schema.CHECK_CONSTRAINTS strips content from CHECK_CLAUSE |
| View definitions | Not tested | Requires PostgreSQL ViewEntity introspection; likely exploitable via pg_get_viewdef() |
Suggested fix: Escape ${ to \${ (and \\ to \\\\) before embedding query strings into template literals, or switch to emitting the SQL as a JSON.stringify()-encoded regular string argument.
PoC
Prerequisites:
- Any supported RDBMS (PostgreSQL, MySQL, MariaDB, CockroachDB, SQL Server, Oracle, SAP HANA, or Spanner) accessible to the developer running
migration:generate - The attacker has DDL/write access to the database, or the application exposes a feature allowing users to set column
COMMENT,DEFAULT, or view definition text
Steps:
- Inject payload into schema metadata. Set a column comment or default…
- Record
GHSA-2rp8-mm9q-fp49- CVSS 3.1
- 5.7 Medium
CVSS:3.1/AV:N/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:N - Weakness
- CWE-94
- Updated
- 2026-11-02
OSVROOT-APP-NPM-GHSA-2rp8-mm9q-fp49 No score
GHSA-2rp8-mm9q-fp49 in typeorm - Patched by Root
Root has patched GHSA-2rp8-mm9q-fp49 in the typeorm package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-GHSA-2rp8-mm9q-fp49- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
typeormnpm |
before 0.3.31 | 0.3.31 |
typeormnpm |
1.0.0 up to 1.1.0 | 1.1.0 |
typeormRoot:npm |
before 1.0.0-aikido.1 | 1.0.0-aikido.1 |
@rootio/typeormRoot:npm |
before 1.0.0-root.io.1 | 1.0.0-root.io.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-73651 is a medium vulnerability (CVSS 5.7) in Typeorm, published July 21, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.39%, the 33rd percentile. Fixed in typeorm 0.3.31.
References
github.com/typeorm/typeorm/security/advisories/GHSA-2rp8-mm9q-fp49
github.com/typeorm/typeorm/commit/41d1c62fe49f99c3ca916d4d986f61ee9f45d519
github.com/typeorm/typeorm/commit/b175f9b8be422edd2a2ac035ba90c3f2ce782dfe
github.com/typeorm/typeorm/releases/tag/0.3.31
github.com/typeorm/typeorm/releases/tag/1.1.0
github.com/advisories/GHSA-2rp8-mm9q-fp49
github.com/CVEProject/cvelistV5/tree/main/cves/2026/73xxx/CVE-2026-73651.json
nvd.nist.gov/vuln/detail/CVE-2026-73651
github.com/typeorm/typeorm
Left out here: the rest of 2 source descriptions. The JSON record has them.