Aug 28, 2026·7 min read·49 visits
A client-side escaping flaw in MariaDB's Node.js driver allows SQL injection when using legacy multi-byte encodings (e.g., GBK, BIG5). Upgrading or switching to utf8mb4 mitigates the issue.
CVE-2026-55855 is a client-side SQL injection vulnerability in the MariaDB Connector/Node.js library that occurs when using legacy multi-byte character sets. The flaw arises from naive, byte-wise client-side parameter escaping. Attackers can leverage specific multi-byte lead bytes to absorb backslash escape characters on the server side, allowing them to terminate string literals and execute arbitrary SQL commands.
The MariaDB Connector/Node.js client library contains a critical client-side SQL injection vulnerability (CVE-2026-55855) within its query parameter escaping mechanism. This vulnerability affects applications that utilize the connector to interact with MariaDB or MySQL databases while configured with legacy multi-byte character sets. The attack surface is exposed via standard query parameter binding when using the text protocol, such as calling conn.query().
The core issue is classified under CWE-89 (Improper Neutralization of Special Elements used in an SQL Command) and CWE-116 (Improper Encoding or Escaping of Output). By supplying carefully crafted binary or Buffer parameters, an attacker can manipulate the client-side escaping process to introduce unescaped single quotes. This allows arbitrary SQL execution with the privileges of the active database session.
Unlike vulnerabilities that rely on server-side flaws, this defect resides entirely within the client-side deserialization and stream serialization layers. The default utf8mb4 character set is structurally immune because it does not share the trail-byte characteristics that make the exploit possible. Similarly, the binary protocol, which uses server-side prepared statements via conn.execute(), is not affected.
The vulnerability represents a multi-byte character set (MBCS) SQL injection bypass. In legacy East Asian encodings such as big5, gbk, sjis, cp932, and gb18030, character sequences consist of variable-length bytes. A valid double-byte character begins with a lead byte followed by a trail byte.
The technical conflict arises because the valid range for a trail byte in these encodings includes 0x5C, which is the ASCII representation of the backslash character. For example, in the GBK encoding, the valid trail-byte range is 0x40 to 0x7E and 0x80 to 0xFE. Because the backslash character 0x5C falls within these ranges, a valid multi-byte character can end with a backslash.
When client-side escaping is performed naively, the library processes the user-provided Buffer parameter byte-by-byte. If an attacker passes a lead byte (like 0xBF in GBK) followed by a single quote (0x27), the naive escaper inserts an escape byte (0x5C) before the quote. The resulting raw sequence transmitted over the wire is 0xBF 0x5C 0x27.
The final stage of the bypass occurs on the database server. The database's SQL lexer checks for multi-byte character structures before processing escape characters. When the server scans 0xBF 0x5C, it interprets this sequence as a single valid multi-byte character rather than an escaped character. This leaves the subsequent 0x27 single quote unescaped, terminating the SQL string literal and enabling SQL injection.
The vulnerability resides in lib/io/packet-output-stream.js within the writeBufferEscape method, which was renamed to writeBufferEscapeFast. This method walked through the input buffer byte-by-byte without checking the multi-byte boundaries of the connection's active encoding.
Below is the vulnerable implementation of the byte-wise escaping loop:
// Vulnerable implementation in lib/io/packet-output-stream.js
writeBufferEscapeFast(val) {
let valLen = val.length;
for (let i = 0; i < valLen; i++) {
const b = val[i];
if (b === QUOTE || b === SLASH || b === DBL_QUOTE || b === ZERO_BYTE) {
this.buf[this.pos++] = SLASH; // Inserts 0x5C indiscriminately
}
this.buf[this.pos++] = b;
}
}The patch remedies this by introducing a stateful, charset-aware loop. The method writeBufferEscapeMb uses a character recognizer (such as getMbRecognizer(encoding) from lib/misc/charset-mb.js) to parse valid multi-byte sequences.
// Patched implementation utilizing charset-aware logic
writeBufferEscapeMb(mb, val) {
const valLen = val.length;
let i = 0;
while (i < valLen) {
const b = val[i];
if (mb.isHead(b)) {
const mbLen = mb.length(val, i, valLen);
if (mbLen >= 2) {
for (let j = 0; j < mbLen; j++) {
this.buf[this.pos++] = val[i + j];
}
i += mbLen;
continue;
}
this.buf[this.pos++] = SLASH;
this.buf[this.pos++] = b;
i++;
continue;
}
if (b === QUOTE || b === SLASH || b === DBL_QUOTE || b === ZERO_BYTE) {
this.buf[this.pos++] = SLASH;
}
this.buf[this.pos++] = b;
i++;
}
}This modification ensures that if a sequence forms a valid multi-byte character, it passes through untouched. If a lone lead byte is provided, it is escaped as \ followed by the lead byte, neutralizing the attack vector.
To successfully exploit this vulnerability, the target application must connect to a MariaDB or MySQL database using a legacy multi-byte character set such as GBK, BIG5, or SJIS. The database connection must be configured to use this encoding, and the query must use the text-protocol interface via conn.query().
The attacker must have a vector to supply raw buffer or binary parameters to the query. If the parameter is parsed as a string on the Node.js side before serialization, the encoding conversions might corrupt the high-order bytes before they reach the escaper. However, when the input is passed directly as a Buffer or binary parameter, the raw bytes are processed exactly as provided.
An attack sequence begins by generating a payload where a valid lead byte immediately precedes the character to be escaped. For example, using GBK, the byte 0xBF is a valid lead byte. An input of 0xBF 0x27 0x20 0x4f 0x52... translates to ¿' OR.... The client-side escaper converts this to 0xBF 0x5C 0x27 0x20 0x4f 0x52....
The database server treats 0xBF 0x5C as a single character (縗), causing the backslash to disappear. The parser then processes 0x27 (the single quote) as a control character rather than a literal value. This breaks out of the SQL string literal, appending the attacker's commands to the query structure.
The security impact of CVE-2026-55855 is critical, as it facilitates unauthenticated remote SQL injection. Depending on the architecture of the backend database, an attacker can bypass authentication mechanisms, retrieve sensitive system data, modify records, or execute administrative actions.
The CVSS v3.1 base score is established at 6.5 (Medium) with the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N. The complexity is designated as high because of the requirement for specific legacy multi-byte character sets to be active on the client connection. If these encodings are active, the vulnerability can be exploited with low complexity.
The vulnerability does not allow direct remote code execution on the underlying operating system unless database-level features (such as LOAD DATA INFILE or specific user-defined functions) are misconfigured or accessible. However, the compromise of database integrity and confidentiality remains high.
The primary remediation strategy is upgrading the mariadb npm package to a patched version. Fixed versions have been released across all supported release branches: 3.2.4 (for 3.2.x), 3.3.3 (for 3.3.x), 3.4.6 (for 3.4.x), and 3.5.3 (for 3.5.x).
If immediate upgrading is not feasible, several defensive workarounds can be applied. The most effective mitigation is migrating database connections to the modern, standard utf8mb4 character set. This encoding does not suffer from trail-byte conflicts and is completely immune to backslash-swallowing attacks.
// Secure Connection Setup using modern UTF-8
const connection = await mariadb.createConnection({
host: "db.local",
user: "app_user",
charset: "utf8mb4" // Immune to CVE-2026-55855
});Additionally, developers should replace conn.query() with conn.execute() for parameterized queries. The conn.execute() interface utilizes the binary prepared statement protocol on the server side. Because parameter values are bound separately from the SQL statement template, they are never processed by the SQL lexer, eliminating client-side text escaping entirely.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
mariadb-connector-nodejs MariaDB | < 3.2.4 | 3.2.4 |
mariadb-connector-nodejs MariaDB | >= 3.3.0, < 3.3.3 | 3.3.3 |
mariadb-connector-nodejs MariaDB | >= 3.4.0, < 3.4.6 | 3.4.6 |
mariadb-connector-nodejs MariaDB | >= 3.5.0, < 3.5.3 | 3.5.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-89 / CWE-116 |
| Attack Vector | Network |
| CVSS Severity | 6.5 (Medium) |
| Exploit Status | Proof-of-Concept |
| KEV Status | Not Listed |
| Impact | Client-Side SQL Injection Bypass |
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.