ReviewOS

stacks/bun-query-builder

Single-row SQLite/MySQL INSERT skips identifier quoting (column-name injection vector)

#1033
Closed glennmichael123 opened this 2 months ago ·
2 months ago

Summary

The single-row, non-Postgres INSERT "ultra-fast path" interpolates raw keys into INSERT INTO users(name,age)... with no quoteId, while the multi-row path and the Postgres path both quote. A comment nearby states SQLite identifier quoting was added specifically to close this injection slot (stacks#1858 Q-7) — but this common path bypasses it. A caller spreading Object.keys(req.body) into a single-row insert can smuggle SQL through a column name.

Evidence

sqlite single row -> INSERT INTO users(name,age)VALUES(?,?)   (unquoted)
multi-row         -> INSERT INTO "users"("name")...           (quoted)

Location

src/client.ts:~5459-5469. (createMany/insertMany ~6324/6368 also never quote identifiers.)

Suggested fix

Route the single-row path's table + keys through quoteId, matching the multi-row branch.

Severity: medium (security). Found via internal code audit.

9 days ago

Fixed in 41d569e. The single-row SQLite/MySQL INSERT fast path and createMany() now quote table + column identifiers via the dialect-aware quoteId (backticks for MySQL, double quotes otherwise) — matching the multi-row and Postgres paths — closing the identifier-injection slot. Per-dialect regression test added; full suite green.

Sign in to comment on this issue.