CVE-2026-40187: Egroupware/egroupware Remote Code Execution Vulnerability

HIGH
Advisory Identifier: GHSA-8737-2x9g-xjj7
CWE-78 CWE-95
Published
Advisory Summary

CVE-2026-40187 is a HIGH remote code execution vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting Egroupware/egroupware libraries in the Packagist ecosystem. The issue involves egroupware has authenticated rce via malicious etemplate upload. Remediation is available by upgrading affected packages to version 26.4.20260413, 23.1.20260601.

CVE-2026-40187 at a Glance

CVE Identifier CVE-2026-40187
GHSA Identifier GHSA-8737-2x9g-xjj7
Severity HIGH
CVSS v3.1 Base Score N/A
CWE Classification CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Affected Product Egroupware/egroupware
Package Ecosystem Packagist
Published Date
Last Updated

How to Fix CVE-2026-40187

To remediate this vulnerability, upgrade all affected Egroupware/egroupware dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

egroupware/egroupware fixed: 26.4.20260413
Upgrade egroupware/egroupware to 26.4.20260413
egroupware/egroupware fixed: 23.1.20260601
Upgrade egroupware/egroupware to 23.1.20260601
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for egroupware/egroupware

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-40187, inspect your project dependencies for Egroupware/egroupware:

inspect dependencies for egroupware/egroupware

Analyze the terminal output to locate any version of Egroupware/egroupware in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 26.4.20260413), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where the product constructs all or part of an os command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended os command when it is sent to a downstream component. In Egroupware/egroupware, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary An authenticated administrator can achieve OS-level Remote Code Execution (RCE) by uploading a malicious eTemplate XML file (`.xet`) to the VFS `/etemplates` mount. The `Widget::expand_name()` method passes template widget attribute values directly into a PHP `eval()` call with only double-quote escaping applied - **backtick characters are not escaped**. In PHP, backticks inside a double-quoted `eval()` string execute shell commands. This allows an admin-level user to escalate from web application access to arbitrary OS command execution on the server. ------------------------------------------------------------------------ ## Details The vulnerability is located in `api/src/Etemplate/Widget.php`, `Widget::expand_name()`: (lines 703–728) The method is designed to expand PHP variables (e.g., `$row`, `$col`,`$cont[id]`) in widget attribute values for auto-repeat grids. The `eval()` is triggered whenever `$name` contains a `$` character (line 706). The only sanitization applied before the eval is: ``` php str_replace('"', '\\"', $name) ``` This escapes double quotes only. **Backtick characters are not escaped**. In PHP, backticks inside a double-quoted string in `eval()` are treated as shell execution operators — equivalent to `shell_exec()`. A widget `id` of `$row\`id`` produces: ``` eval('$name = "$row`id`";'); // executes shell command: id ``` `expand_name()` is called from: - `form_name()` - `expand_widget()` - `set_attrs()` - `Template::run()` The `/etemplates` VFS path is created exclusively for admin users — it is `chgrp`'d to `Admins` and `chmod`'d to `075` (Admins group has full rwx): class.filemanager_admin.inc.php:95-106 Custom templates in `/etemplates` take precedence over built-in filesystem templates, meaning a malicious template can silently override any existing application template. **Mitigating factor**: The official Docker deployment sets `disable_functions = exec,passthru,shell_exec,system,proc_open,popen` in `php.ini`, which also blocks PHP backtick execution (backticks internally call shell_exec). Non-Docker or non-hardened deployments without this `php.ini` setting are fully vulnerable. Dockerfile:47 The current master branch in api/setup/setup.inc.php, confirming the vulnerability is present in the latest code as of today. setup.inc.php:14-17 ------------------------------------------------------------------------ ## Proof of Concept (PoC) ### Prerequisites - Admin account - Non-Docker deployment, or Docker deployment where disable_functions has been removed/modified in php.ini ### Step 1 — Mount /etemplates: Log in as admin, navigate to Admin → Filemanager → VFS Mounts, and click "Install custom templates". This executes the code in `filemanager_admin.inc.php` that mounts `/etemplates` with Admins-group write access. ### Step 2 — Upload malicious template: Create a file named `index.xet` with the following content: ``` xml <?xml version="1.0" encoding="UTF-8"?> <overlay> <template id="admin.index"> <grid> <columns><column/></columns> <rows> <row> <textbox id="$row`touch /tmp/pwned_egw 2>/dev/null`"/> </row> </rows> </grid> </template> </overlay> ``` Upload this file to `/etemplates/admin/templates/default/index.xet` via the VFS filemanager. ### Step 3 — Trigger execution: Navigate to the EGroupware admin panel: ``` https://<target>/egroupware/index.php?menuaction=admin.admin_ui.index ``` When the template is loaded and beforeSendToClient() runs, form_name() calls expand_name() with $name = '$row\touch /tmp/pwned_egw 2>/dev/null`'and$row = 0`. The eval becomes: ``` eval('$name = "$row`touch /tmp/pwned_egw 2>/dev/null`";'); ``` PHP executes the backtick expression as a shell command. ### Step 4 — Verify: Check that `/tmp/pwned_egw` was created on the server. For a more impactful demonstration, replace `touch /tmp/pwned_egw` with `id > /tmp/pwned_egw` to capture the web server's OS user identity. ------------------------------------------------------------------------ ## Impact Authenticated Remote Code Execution (RCE) via eval() with unsanitized shell metacharacters. Who is impacted: Any EGroupware installation where: 1. An admin account is compromised or a malicious admin exists, AND 2. The server is not running with disable_functions blocking shell_exec (i.e., non-Docker or misconfigured deployments) ------------------------------------------------------------------------ ## Severity The vulnerability allows escalation from EGroupware admin-level web access to arbitrary OS command execution as the web server user (typically www-data). From there, an attacker can read configuration files (including database credentials), pivot to other services, or establish persistence. This is not exploitable by regular (non-admin) users. The official Docker deployment is not affected due to disable_functions, but bare-metal, VM, or custom container deployments without this hardening are fully vulnerable.

CVE-2026-40187 Affected Egroupware/egroupware Versions

2 component(s)
Fixed Versions:
26.4.2026041323.1.20260601
Product / Package Ecosystem Affected Versions Fixed Version
egroupware/egroupware
Packagist
≥ 26.0.20251208
< 26.4.20260413
26.4.20260413
egroupware/egroupware
Packagist
< 23.1.20260601
23.1.20260601

References

Frequently Asked Questions

What is CVE-2026-40187?
CVE-2026-40187 is a security vulnerability in Egroupware/egroupware involving EGroupware has Authenticated RCE via Malicious eTemplate Upload under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
Which Egroupware/egroupware versions are affected?
Affected versions include releases prior to 26.4.20260413, 23.1.20260601 across affected packages: egroupware/egroupware.
What version fixes CVE-2026-40187?
Upgrading to 26.4.20260413, 23.1.20260601 (or the latest patched release for your respective branch) resolves the vulnerability.
Is egroupware/egroupware affected?
Yes, egroupware/egroupware is affected in releases prior to 26.4.20260413, 23.1.20260601. Upgrade your dependency to 26.4.20260413, 23.1.20260601 or later.
What CWE is associated with CVE-2026-40187?
CVE-2026-40187 is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.).
How can I check Packagist dependencies for CVE-2026-40187?
Run the dependency tree command: 'inspect dependencies for egroupware/egroupware'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-8737-2x9g-xjj7",
  "modified" : "2026-07-07T13:01:31Z",
  "published" : "2026-07-07T13:01:31Z",
  "aliases" : [ "CVE-2026-40187" ],
  "summary" : "EGroupware has Authenticated RCE via Malicious eTemplate Upload",
  "details" : "## Summary\n\nAn authenticated administrator can achieve OS-level Remote Code Execution (RCE) by uploading a malicious eTemplate XML file (`.xet`) to the VFS `/etemplates` mount.\n\nThe `Widget::expand_name()` method passes template widget attribute values directly into a PHP `eval()` call with only double-quote escaping applied - **backtick characters are not escaped**.\n\nIn PHP, backticks inside a double-quoted `eval()` string execute shell commands. This allows an admin-level user to escalate from web\napplication access to arbitrary OS command execution on the server.\n\n------------------------------------------------------------------------\n\n## Details\n\nThe vulnerability is located in `api/src/Etemplate/Widget.php`, `Widget::expand_name()`:  (lines 703–728)\n\nThe method is designed to expand PHP variables (e.g., `$row`, `$col`,`$cont[id]`) in widget attribute values for auto-repeat grids. The `eval()` is triggered whenever `$name` contains a `$` character (line 706). The only sanitization applied before the eval is:\n\n``` php\nstr_replace('\"', '\\\\\"', $name)\n```\n\nThis escapes double quotes only. **Backtick characters are not escaped**. In PHP, backticks inside a double-quoted string in `eval()` are treated as shell execution operators — equivalent to  `shell_exec()`. A widget `id` of `$row\\`id`` produces:\n\n```\neval('$name = \"$row`id`\";');  // executes shell command: id\n```\n\n`expand_name()` is called from:\n\n-   `form_name()`\n-   `expand_widget()`\n-   `set_attrs()`\n-   `Template::run()`\n\nThe `/etemplates` VFS path is created exclusively for admin users — it is `chgrp`'d to `Admins` and `chmod`'d to `075` (Admins group has full rwx): class.filemanager_admin.inc.php:95-106\n\nCustom templates in `/etemplates` take precedence over built-in filesystem templates, meaning a malicious template can silently override any existing application template.\n\n\n**Mitigating factor**: The official Docker deployment sets `disable_functions = exec,passthru,shell_exec,system,proc_open,popen` in `php.ini`, which also blocks PHP backtick execution (backticks internally call shell_exec). Non-Docker or non-hardened deployments without this `php.ini` setting are fully vulnerable. Dockerfile:47\n\nThe current master branch in api/setup/setup.inc.php, confirming the vulnerability is present in the latest code as of today. setup.inc.php:14-17\n\n\n------------------------------------------------------------------------\n\n## Proof of Concept (PoC)\n\n### Prerequisites\n\n-   Admin account\n-   Non-Docker deployment, or Docker deployment where disable_functions has been removed/modified in php.ini\n\n\n### Step 1 — Mount /etemplates:\nLog in as admin, navigate to Admin → Filemanager → VFS Mounts, and click \"Install custom templates\". This executes the code in `filemanager_admin.inc.php` that mounts `/etemplates` with Admins-group write access.\n\n### Step 2 — Upload malicious template:\n\nCreate a file named `index.xet` with the following content:\n\n``` xml\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<overlay>\n  <template id=\"admin.index\">\n    <grid>\n      <columns><column/></columns>\n      <rows>\n        <row>\n          <textbox id=\"$row`touch /tmp/pwned_egw 2>/dev/null`\"/>\n        </row>\n      </rows>\n    </grid>\n  </template>\n</overlay>\n```\nUpload this file to `/etemplates/admin/templates/default/index.xet` via the VFS filemanager.\n\n\n### Step 3 — Trigger execution:\nNavigate to the EGroupware admin panel:\n```\nhttps://<target>/egroupware/index.php?menuaction=admin.admin_ui.index  \n```\nWhen the template is loaded and beforeSendToClient() runs, form_name() calls expand_name() with $name = '$row\\touch /tmp/pwned_egw 2>/dev/null`'and$row = 0`. The eval becomes:\n```\neval('$name = \"$row`touch /tmp/pwned_egw 2>/dev/null`\";');\n\n```\n\nPHP executes the backtick expression as a shell command.\n\n### Step 4 — Verify:\nCheck that `/tmp/pwned_egw` was created on the server. For a more impactful demonstration, replace `touch /tmp/pwned_egw` with `id > /tmp/pwned_egw` to capture the web server's OS user identity.\n\n\n\n------------------------------------------------------------------------\n\n## Impact\n\nAuthenticated Remote Code Execution (RCE) via eval() with unsanitized shell metacharacters.\n\nWho is impacted: Any EGroupware installation where:\n\n1. An admin account is compromised or a malicious admin exists, AND\n2. The server is not running with disable_functions blocking shell_exec (i.e., non-Docker or misconfigured deployments)\n\n------------------------------------------------------------------------\n\n## Severity\n\nThe vulnerability allows escalation from EGroupware admin-level web access to arbitrary OS command execution as the web server user (typically www-data). From there, an attacker can read configuration files (including database credentials), pivot to other services, or establish persistence. This is not exploitable by regular (non-admin) users. The official Docker deployment is not affected due to disable_functions, but bare-metal, VM, or custom container deployments without this hardening are fully vulnerable.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "egroupware/egroupware"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "26.0.20251208"
      }, {
        "fixed" : "26.4.20260413"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "< 26.0.20260113"
    }
  }, {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "egroupware/egroupware"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "23.1.20260601"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/EGroupware/egroupware/security/advisories/GHSA-8737-2x9g-xjj7"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/EGroupware/egroupware"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-78", "CWE-95" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-07-07T13:01:31Z",
    "nvd_published_at" : null
  }
}