Drizzle 0.45.2: security fix for sql.identifier / sql.as escaping
Source: Drizzle ORM (GitHub release)
A focused security release. If you build dynamic identifiers with Drizzle's SQL helpers anywhere in your codebase, this one belongs in your changelog and probably in your incident channel.
Fixedsql.identifier(),sql.as()escaping issues. Previously all the values passed to these functions were not properly escaped causing a possible SQL Injection (CWE-89) vulnerability.
What was vulnerable
Two helpers were affected:
- `sql.identifier(name)` — emits a quoted SQL identifier (table name, column name, alias) into a query.
- `sql.as(alias)` — applies an
AS …alias to an expression in the SELECT list, ORDER BY, or similar.
Both helpers were intended to take trusted strings, but the docs and the typical call site read like they sanitized inputs. They didn't. Strings passed in were embedded into the generated SQL with insufficient escaping for double quotes and backslashes inside identifiers, which means a sufficiently shaped value could break out of the identifier context and inject SQL.
In practical terms: any service that took a column name, table name, or alias from a request parameter — even after type-checking it as a string — and passed it through sql.identifier / sql.as was at risk. Common shapes include "let the client pick the sort column", "let the client pick the columns to project", and "expose a generic search endpoint over multiple tables".
CWE-89 in plain terms
CWE-89 is the standard CWE entry for SQL injection. The patch fixes the escaping; the classification acknowledges that any service exposing user-controlled identifiers through the affected helpers had a real injection surface, not a theoretical one.
Action items
- Upgrade to 0.45.2 (or newer) on every service that uses the affected helpers.
- Audit call sites. Search your codebase for
sql.identifierandsql.as. For each match, ask: can the input be influenced by an HTTP request, a websocket message, a file upload, or any external source? If yes, treat the deployed service as potentially vulnerable on versions before 0.45.2. - Add an allowlist. Even with the patched helpers, accepting arbitrary identifiers from clients is rarely what you want. Validate against a known list of column names per endpoint before passing anything to
sql.identifier. - Check your deploy log. If you've shipped a version older than 0.45.2 in production while it was online, log review may be warranted depending on your risk profile.
Scope of the fix
The fix landed on the stable 0.45.x line. Related beta releases received parallel fixes during the same window — read the changelog for the exact tags. The fix does not change the public API; you do not need to refactor call sites, only upgrade.
A small example of safe usage post-fix
Even with the patch, you should still validate user input against a fixed allowlist. The helper protects against syntactic injection, but it cannot stop an attacker from picking, say, the password_hash column if your endpoint exposes one:
const ALLOWED_SORT = new Set(["created_at", "updated_at", "title"]);
if (!ALLOWED_SORT.has(req.query.sortBy)) {
return res.status(400).json({ error: "invalid sort column" });
}
const rows = await db
.select()
.from(posts)
.orderBy(sql`${sql.identifier(req.query.sortBy)} desc`);The allowlist makes the intent explicit and limits the blast radius of any future regression — defense in depth.
Treat `npm outdated` as a security habit
Most ORM CVEs are quiet — patch releases without much fanfare. The 0.45.2 fix is a useful reminder to schedule a recurring npm outdated review on services that touch a database. A weekly cron that opens a PR with patch-level bumps catches releases like this one before they sit unpatched for a sprint.
Where this connects
If you're tracking the Drizzle 1.0 line, see the v1.0.0-rc.1 release post — the casing migration and JIT mappers land there, but the security fix exists on both lines, so 0.45.x users do not need to bump to the RC to get the patched escape behavior.
References
Source / further reading: Drizzle ORM (GitHub release)