At ZeroDay.Cloud 2025, Xint Code discovered a heap buffer overflow in MariaDB's JSON schema validation logic that leads to remote code execution.

MariaDB is one of the most widely deployed open-source relational databases, powering production workloads across cloud providers, managed services, and on-prem infrastructure alike. Any authenticated user — including low-privilege application accounts — can reach the vulnerable code path with a single SQL statement. No special grants, extensions, or plugins are required.
CVE-2026-32710 is a heap buffer overflow in MariaDB's JSON_SCHEMA_VALID() function that allows an authenticated user to escalate privileges and execute arbitrary operating system commands on the database host. The bug lives in json_get_normalized_string() inside sql/json_schema_helper.cc, which copies a JSON string value into a fixed 128-byte heap buffer without a bounds check.
The vulnerability was discovered by Xint Code, a fully autonomous AI-powered security analysis tool built by Theori, and a working RCE exploit was demonstrated at ZeroDay.Cloud 2025 (London, December 10-11, 2025). The MariaDB team shipped patches on February 4, 2026 across both supported release series (11.4.10, 11.8.6).
We'd like to thank the MariaDB security team for their prompt acknowledgment and resolution of this issue.
If you run MariaDB in production, take action now. Any user who can open a SQL session — whether through stolen credentials, SQL injection, or lateral movement — can reach this code path with a single function call.
Who is affected
The vulnerable function, JSON_SCHEMA_VALID(), is a built-in SQL function available to every authenticated user. The exploitable code path is reached with a single statement:
SELECT JSON_SCHEMA_VALID('{"enum":[0]}', '"AAAA…"');
The affected release series and versions are:
| Release series | Affected versions | Fixed version |
|---|---|---|
| MariaDB 11.4 | 11.4.1 – 11.4.9 | 11.4.10 |
| MariaDB 11.8 | 11.8.1 – 11.8.5 | 11.8.6 |
Risk assessment
Critical risk: internet-exposed MariaDB with any authenticated access. Because JSON_SCHEMA_VALID() requires no special privileges, any valid session — even one created through a low-privilege application account — is sufficient to trigger the overflow. Managed or multi-tenant environments where the database acts as a trust boundary face elevated risk: a tenant with valid credentials can exploit this bug to compromise the host.
High risk: internal instances reachable via lateral movement. MariaDB credentials are commonly present in application config files, CI/CD pipelines, and secrets managers. A compromised application server often yields database access. SQL injection provides another path: a single injectable parameter gives the attacker the authenticated SQL execution they need.
Remediation
Patch now
The fix was committed upstream on January 9, 2026 and shipped in MariaDB 11.4.10 and 11.8.6 on February 4, 2026.
Upgrade to the patched minor release for your series. MariaDB minor upgrades within a GA series are designed to be compatible; staying on an older minor carries more risk than upgrading.
Cloud managed MariaDB services may roll out patched versions on their own schedules. Check your provider's bulletin.
If you can't patch yet
Reduce exploitability and blast radius while you schedule patching:
- Tighten network access: ensure MariaDB is not directly internet-exposed; limit connectivity to known application subnets and trusted admin networks.
- Credential hygiene: rotate broadly-distributed database credentials (apps, CI/CD, secrets stores); prefer per-service identities and short-lived credentials.
- Audit grants: review which accounts exist and what privileges they hold; remove unnecessary accounts and restrict
CREATEorFILEprivileges where possible.
How Wiz can help
Wiz customers can identify affected MariaDB instances across their cloud environments:
- Vulnerability findings: The Wiz Threat Center includes a pre-built query for CVE-2026-32710. Use the Vulnerability Findings page to filter for affected MariaDB versions across your inventory.
- Dynamic Scanner: Wiz's agentless scanning automatically detects vulnerable MariaDB versions running in your environment, including instances in containers and managed services.
- Runtime Sensor: For customers using Wiz Runtime Sensor, real-time detection identifies exploitation attempts targeting
JSON_SCHEMA_VALID().
From SQL to shell
An attacker needs only authenticated SQL access on the target instance. From there, the exploit proceeds in three phases: privilege escalation, address leak, and code execution.
- Privilege escalation: The attacker uses the heap overflow to corrupt internal session metadata, granting their connection full superuser privileges. These elevated privileges are then persisted with
GRANT ALL. - Address leak: With superuser, the attacker reads
/proc/self/mapsviaLOAD DATA INFILEto determine the MariaDB binary's base address in memory, defeating ASLR. - Code execution: The attacker triggers the overflow a second time to overwrite the global
plugin_dirpointer, redirecting it to/tmp. A malicious shared library is loaded as a User-Defined Function, providing arbitrary OS command execution.

Technical deep dive
CVE-2026-32710 is a heap buffer overflow in json_get_normalized_string() (sql/json_schema_helper.cc).
The vulnerable code
When normalizing a JSON string during schema validation, the function allocates a DYNAMIC_STRING with a default capacity of 128 bytes via init_dynamic_string(), then copies je->value_len bytes into the buffer using strncpy, with no check that the value fits:
DYNAMIC_STRING a_res;
if (init_dynamic_string(&a_res, NULL, 0, 0))
goto error;
...
else if(je->value_type == JSON_VALUE_STRING)
{
strncpy((char*)a_res.str, val.ptr(), je->value_len);
a_res.length= je->value_len;
}
A JSON string longer than 128 bytes overflows the heap buffer. The fix replaces the strncpy with dynstr_set(), which dynamically resizes the buffer to accommodate the input.
Unlike many heap overflows, the attacker's overflow payload is constrained: the data written past the buffer boundary must consist of bytes that are valid within a JSON string. Arbitrary binary data (such as full 8-byte pointers) cannot be injected directly. This significantly limits the attacker's options — and makes the exploitation techniques described below all the more interesting.
Arbitrary write primitive
The exploit overcomes the character constraints through a combination of heap grooming and partial pointer overwrites. Rather than writing a full pointer value, the attacker corrupts only the lowest 2 bytes of an adjacent heap pointer, selecting byte values that happen to be valid JSON string characters. The key insight is that MariaDB's user-defined variables (SET @var = ...) store their values on the session's heap. Each variable has an internal user_var_entry structure that contains a value pointer to the variable's data. By carefully arranging these variables on the heap, the attacker can position the overflow buffer adjacent to a target variable's metadata, then use the 2-byte partial overwrite to redirect that variable's value pointer to a nearby controlled location.
However, the partial overwrite can only reach nearby heap addresses. It cannot directly target distant structures like thd->security_ctx or global variables. To bridge this gap, the exploit uses a two-hop write primitive built around a single SET statement:
SET @overflow_5 = CONCAT( -- resolves overflow_5 user_var_entry BEFORE overflow
X'...value...', -- write arbitrary value to *overflow_5.value
REPEAT(
JSON_SCHEMA_VALID( -- triggers heap overflow into overflow_5 user_var_entry
'{"enum":[0]}',
'"AAAA...AA\x28\x34"' -- 2-byte partial overwrite of overflow_5.value
),
0 -- REPEAT(..., 0) discards the return value
)
);
The overflow and the assignment must happen in the same statement. As the diagram below shows, the overflow corrupts not just the value pointer but all preceding fields in the adjacent user_var_entry (including m_type_handler, m_charset, name.str, and name.length). After the overflow, the variable's name and type metadata are destroyed. If the attacker tried to write to @overflow_5 in a separate statement, the corrupted name and type fields would cause a crash. By embedding the overflow inside the CONCAT expression of a SET on that same variable, MariaDB resolves the variable reference before query execution (before the overflow fires), and the assignment target is already bound. The CONCAT result (the full 8-byte target address) then flows through the now-corrupted value pointer, landing in the second variable's user_var_entry.value field. A subsequent SET on that second variable writes attacker-controlled data to the final target.

Exploit steps
Stage 1: Heap grooming. The attacker allocates 66 "pad" variables of 127 bytes each to fill the heap into a predictable state. Next, 16 pairs of variables are allocated: a "free" variable (127 bytes) and an "overflow" variable (16 bytes). The free variables are then released and the overflow variables shrunk, creating 127-byte holes in the heap. When JSON_SCHEMA_VALID is called, init_dynamic_string allocates its 128-byte internal buffer, which lands in one of these holes, directly adjacent to another variable's user_var_entry.
Stage 2: Privilege escalation. The attacker uses the arbitrary write primitive to corrupt thd->security_ctx->master_access, which is at a predictable offset from the heap base. The attacker executes SET @overflow_6 = X'FFFFFFFFFFFFFFFFFF', setting all permissions bits for the session. GRANT ALL PRIVILEGES persists the privileges for the authenticated user, and SELECT ... INTO DUMPFILE /tmp/pwn.so abuses the elevated privileges to write a malicious executable to the server's disk.
Stage 3: Address leak and code execution. The attacker opens a new connection (now with full privileges) and uses LOAD DATA INFILE '/proc/1/maps' to read the process memory map into a table. Parsing the output reveals the MariaDB binary's base address, defeating PIE. The attacker then repeats the arbitrary write primitive. This time, the attacker manipulates MariaDB's global configuration: writing '/tmp' into the plugin_dir variable in the .data section. This causes MariaDB to locate plugins in /tmp, exactly where Stage 2 planted the malicious object. Finally, CREATE FUNCTION shell RETURNS STRING SONAME 'pwn.so' loads the attacker's User-Defined Function, and calling the shell function executes arbitrary shell commands as the MariaDB process user.
Responsible disclosure timeline
- December 10-11, 2025: Vulnerability discovered and demonstrated at ZeroDay.Cloud 2025 by Team Xint Code.
- December 11, 2025: Reported to MariaDB security team.
- December 11, 2025: Acknowledged by MariaDB.
- January 9, 2026: Fix committed upstream.
- February 4, 2026: Fix shipped in MariaDB 11.4.10 and 11.8.6.
- March 20, 2026: CVE-2026-32710 published.
Final remarks
CVE-2026-32710 illustrates how even constrained memory corruption primitives — in this case, an overflow limited to valid JSON string bytes — can be chained into full remote code execution with careful heap manipulation. The exploitation required creative solutions at every stage: partial pointer overwrites to work within character constraints, single-statement write primitives to avoid crashing on corrupted metadata, and privilege escalation to bootstrap the read and write access needed for the final code execution payload.
The vulnerability sat in a built-in SQL function accessible to every authenticated session, with no privileges required beyond the ability to connect. For organizations running MariaDB, the takeaway is clear: treat every authenticated session as a potential attack surface, not just administrative connections.
This bug was found by Xint Code, an autonomous AI code analysis tool built by Theori and designed for deep vulnerability discovery across large codebases. Learn more at code.xint.io.
Stay in touch
For questions about this research, contact research@wiz.io.