Jul 29, 2026·5 min read·75 visits
Improper escaping of trailing backslash characters in @hypequery/clickhouse parameter substitution allows attackers to escape string literal boundaries and inject arbitrary SQL commands into ClickHouse queries.
A critical SQL injection vulnerability was identified in @hypequery/clickhouse prior to version 2.0.2. The escapeValue utility function in packages/clickhouse/src/core/utils.ts fails to escape literal backslash characters before replacing single quotes. This allows remote, unauthenticated attackers to supply input parameters ending in a backslash, neutralizing the closing quote character inside ClickHouse databases and enabling arbitrary SQL execution.
The node package @hypequery/clickhouse serves as an analytical query builder and semantic layer, translating structured object queries into ClickHouse-compatible SQL statements. Because ClickHouse often operates behind server-side APIs or is queried directly via HTTP, developer libraries typically rely on client-side parameter substitution to construct the final query string. This client-side execution path makes the query engine highly dependent on secure string-escaping utilities.
The core of this security mechanism resides in the escapeValue function within packages/clickhouse/src/core/utils.ts. This utility parses individual parameters and wraps strings in single quotes while escaping internal quotation marks. If an input value breaks these quotation boundaries, the parser shifts out of the string literal context and evaluates subsequent text as executable SQL structure.
In versions of @hypequery/clickhouse before 2.0.2, the library failed to sanitize literal backslash (\) characters during string preparation. Because ClickHouse supports C-style backslash escape sequences, an input ending with a backslash neutralizes the closing quote added by the library. This allows an attacker to construct queries that absorb application logic as a string literal, executing adjacent parameter values as raw SQL instructions.
The root cause of CVE-2026-54658 stems from a dialect mismatch between SQL-92 string-escaping conventions and ClickHouse's implementation of escape characters. Under standard SQL-92 specifications, a single quote within a string literal is escaped by doubling it (''), and backslashes have no syntactic function. However, the ClickHouse SQL parser supports C-style escapes, interpreting a backslash immediately preceding a single quote (\') as a literal single quote rather than a closing delimiter.
Prior to the patch, the escapeValue function processed string variables by replacing single quotes with doubled single quotes using the regex pattern value.replace(/'/g, "''"). No operations were performed to validate or escape literal backslash characters. When an input parameter such as test\ was passed, the utility produced the SQL literal 'test\''.
During parsing on the ClickHouse server, the sequence \' is read as an escaped quote. The string literal remains unclosed, causing the database to interpret all subsequent query components—including operators, commands, and structural clauses—as part of the string. The literal is only closed when the parser encounters the next unescaped single quote, which typically occurs in the next parameter, allowing the payload inside that parameter to execute as active SQL code.
The vulnerability inside packages/clickhouse/src/core/utils.ts is shown below, illustrating the lack of backslash handling in the string classification block:
// Vulnerable Implementation (pre-2.0.2)
export function escapeValue(value: any): string {
// ... types check
else if (typeof value === 'string') {
// Only single quotes are substituted, leaving backslashes unaltered
return `'${value.replace(/'/g, "''")}'`;
}
// ...
}To resolve this issue, commit 4dfa9d77d70a08b970e722268b75ca7d13db0bdf modified the string escaping logic. The updated code doubles all backslash characters before executing the single-quote replacement, neutralizing any attempts to escape the closing quote:
// Patched Implementation (2.0.2+)
export function escapeValue(value: any): string {
else if (typeof value === 'number') {
return value.toString();
} else if (typeof value === 'string') {
// Backslashes are doubled first to prevent escaping the closing quote
const escaped = value.replace(/\\/g, '\\\\').replace(/'/g, "''");
return `'${escaped}'`;
} else if (value instanceof Date) {
return `'${value.toISOString()}'`;
} else {
// ... fallback execution path
}
}While this patch successfully stops the trailing backslash attack vector, developers must ensure that fallback conditions do not introduce serialization bypasses. If an attacker can inject custom object types that bypass the typeof value === 'string' check but return malicious string values during execution, downstream vulnerabilities may persist. Strict input-type schema validation should be maintained on all upstream API endpoints.
Exploiting this vulnerability requires that an attacker can control at least one query parameter in a multi-parameter query, or control a parameter that precedes structurally predictable SQL operations. Consider a typical query constructed by the application interface to retrieve active database logs:
SELECT * FROM user_logs WHERE username = ? AND category = ?An attacker supplies a single backslash \ as the first parameter, and the payload OR 1=1 -- as the second parameter. The query engine uses escapeValue to prepare both parameters, yielding the SQL query:
SELECT * FROM user_logs WHERE username = '\' AND category = ' OR 1=1 -- 'The ClickHouse engine parses the first string literal starting at the single quote before the backslash. Because of the trailing backslash, the single quote at the end of the first parameter is treated as an escaped literal quote. The string literal does not close until the single quote preceding OR 1=1 is encountered. Consequently, the string literal value becomes \\' AND category = , and the database parses and executes OR 1=1 -- as unescaped SQL commands.
The impact of CVE-2026-54658 is severe, with a CVSS v3.1 score of 9.8. Because @hypequery/clickhouse is commonly deployed in analytical servers and metrics pipelines, this vulnerability allows unauthenticated remote attackers to execute arbitrary SQL commands directly against backend data store instances.
Successful exploitation results in complete data confidentiality failure, allowing attackers to bypass application-level access controls and read sensitive table structures, system logs, or user credentials. Since ClickHouse supports administrative operations, an attacker can execute resource-heavy queries to trigger a denial of service, or execute destructive commands such as dropping tables and dropping databases, compromising the overall data integrity of the system.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
@hypequery/clickhouse hypequery | < 2.0.2 | 2.0.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 |
| Attack Vector | Network (AV:N) |
| CVSS Severity | 9.8 (Critical) |
| Exploit Status | PoC (Proof of Concept) available in repository tests |
| CISA KEV Status | Not listed |
| Mitigated Version | 2.0.2 |
The software constructs an SQL command using externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements that can modify the intended SQL command when it is sent to the database.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.