chore(deps): update dependency kysely to v0.28.14 [security]#152
Open
renovate[bot] wants to merge 1 commit intomainfrom
Open
chore(deps): update dependency kysely to v0.28.14 [security]#152renovate[bot] wants to merge 1 commit intomainfrom
renovate[bot] wants to merge 1 commit intomainfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.28.12→0.28.14GitHub Vulnerability Alerts
CVE-2026-33442
Summary
The
sanitizeStringLiteralmethod in Kysely's query compiler escapes single quotes ('→'') but does not escape backslashes. On MySQL with the defaultBACKSLASH_ESCAPESSQL mode, an attacker can inject a backslash before a single quote to neutralize the escaping, breaking out of the JSON path string literal and injecting arbitrary SQL.Details
When a user calls
.key(value)on a JSON path builder, the value flows through:JSONPathBuilder.key(key)atsrc/query-builder/json-path-builder.ts:166stores the key as aJSONPathLegNodewith type'Member'.During compilation,
DefaultQueryCompiler.visitJSONPath()atsrc/query-compiler/default-query-compiler.ts:1609wraps the full path in single quotes ('$...').DefaultQueryCompiler.visitJSONPathLeg()atsrc/query-compiler/default-query-compiler.ts:1623callssanitizeStringLiteral(node.value)for string values (line 1630).sanitizeStringLiteral()atsrc/query-compiler/default-query-compiler.ts:1819-1821only doubles single quotes:The
MysqlQueryCompilerdoes not overridesanitizeStringLiteral— it only overridessanitizeIdentifierfor backtick escaping.The bypass mechanism:
In MySQL's default
BACKSLASH_ESCAPESmode,\'inside a string literal is interpreted as an escaped single quote (not a literal backslash followed by a string terminator). Given the input\' OR 1=1 --:sanitizeStringLiteralsees the'and doubles it:\'' OR 1=1 --'$.\'' OR 1=1 --'\'as an escaped quote character (consuming the first'of the doubled pair)'now terminates the string literalOR 1=1 --is parsed as SQL, achieving injectionThe existing test at
test/node/src/sql-injection.test.ts:61-83only tests single-quote injection (first' as ...), which the''doubling correctly prevents. It does not test the backslash bypass vector.PoC
Simplified verification of the bypass mechanics:
Note: PostgreSQL is unaffected because
standard_conforming_strings=on(default since 9.1) disables backslash escape interpretation. SQLite does not interpret backslash escapes in string literals. Only MySQL (and MariaDB) with the defaultBACKSLASH_ESCAPESmode are vulnerable.Impact
.key()JSON path builder API can inject arbitrary SQL into queries executed against MySQL databases.multipleStatements: true) or subquery-based injection can modify or delete data..key(),.at(), or other JSON path builder methods. While this is a specific API usage pattern (justifying AC:H), it is realistic in applications with dynamic JSON schema access or user-configurable JSON field selection.Recommended Fix
Escape backslashes in addition to single quotes in
sanitizeStringLiteral. This neutralizes the bypass in MySQL'sBACKSLASH_ESCAPESmode:With this fix, the input
\' OR 1=1 --becomes\\'' OR 1=1 --, where MySQL parses\\as a literal backslash,''as an escaped quote, and the string literal is never terminated.Alternatively, the MySQL-specific compiler could override
sanitizeStringLiteralto handle backslash escaping only for MySQL, keeping the base implementation unchanged for PostgreSQL and SQLite which don't need it:A corresponding test should be added to
test/node/src/sql-injection.test.ts:CVE-2026-33468
Summary
Kysely's
DefaultQueryCompiler.sanitizeStringLiteral()only escapes single quotes by doubling them ('→'') but does not escape backslashes. When used with the MySQL dialect (whereNO_BACKSLASH_ESCAPESis OFF by default), an attacker can use a backslash to escape the trailing quote of a string literal, breaking out of the string context and injecting arbitrary SQL. This affects any code path that usesImmediateValueTransformerto inline values — specificallyCreateIndexBuilder.where()andCreateViewBuilder.as().Details
The root cause is in
DefaultQueryCompiler.sanitizeStringLiteral():src/query-compiler/default-query-compiler.ts:1819-1821Where
LIT_WRAP_REGEXis defined as/'/g(line 121). This only doubles single quotes — it does not escape backslash characters.The function is called from
appendStringLiteral()which wraps the sanitized value in single quotes:src/query-compiler/default-query-compiler.ts:1841-1845This is reached when
visitValue()encounters an immediate value node (line 525-527), which is created byImmediateValueTransformerused inCreateIndexBuilder.where():src/schema/create-index-builder.ts:266-278The
MysqlQueryCompiler(atsrc/dialect/mysql/mysql-query-compiler.ts:6-75) extendsDefaultQueryCompilerbut does not overridesanitizeStringLiteral, inheriting the backslash-unaware implementation.Exploitation mechanism:
In MySQL with the default
NO_BACKSLASH_ESCAPES=OFFsetting, the backslash character (\) acts as an escape character inside string literals. Given input\' OR 1=1 --:sanitizeStringLiteraldoubles the quote:\'' OR 1=1 --appendStringLiteralwraps:'\'' OR 1=1 --'\'as an escaped (literal) single quote, so the string content is'and the second'closes the stringOR 1=1 --is parsed as SQLPoC
To verify against a live MySQL instance:
Impact
CreateIndexBuilder.where()orCreateViewBuilder.as()can inject arbitrary SQL statements when the application uses the MySQL dialect.The attack complexity is rated High (AC:H) because exploitation requires an application to pass untrusted user input into DDL schema builder methods, which is an atypical but not impossible usage pattern. The
CreateIndexBuilder.where()docstring (line 247) notes "Parameters are always sent as literals due to database restrictions" without warning about the security implications.Recommended Fix
MysqlQueryCompilershould overridesanitizeStringLiteralto escape backslashes before doubling quotes:src/dialect/mysql/mysql-query-compiler.tsAlternatively, the library could use parameterized queries for these DDL builders where the database supports it, avoiding string literal interpolation entirely. For databases that don't support parameters in DDL statements, the dialect-specific compiler must escape all characters that have special meaning in that dialect's string literal syntax.
Release Notes
kysely-org/kysely (kysely)
v0.28.14: 0.28.14Compare Source
Hey 👋
A small batch of bug fixes. Please report any issues. 🤞😰🤞
🚀 Features
🐞 Bugfixes
MySQL 🐬
\\') are used. by @igalklebanov in #1754 &054e801📖 Documentation
📦 CICD & Tooling
9e02f3b🐤 New Contributors
Full Changelog: kysely-org/kysely@v0.28.13...v0.28.14
v0.28.13: 0.28.13Compare Source
Hey 👋
A small batch of bug fixes. Please report any issues. 🤞😰🤞
🚀 Features
🐞 Bugfixes
sideEffects: falsein rootpackage.jsonresulting in bigger bundles in various bundlers. by @igalklebanov in #1746Insertableallows non-objects when a table has no required columns. by @igalklebanov in #1747PostgreSQL 🐘
ON COMMITclause not being output when using.as(query)inCREATE TABLEqueries. by @igalklebanov in #1748📖 Documentation
📦 CICD & Tooling
tsconfig.jsonfor TypeScript native. by @igalklebanov in #1749🐤 New Contributors
Full Changelog: kysely-org/kysely@v0.28.12...v0.28.13
Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.