Research
Critical vulnerability in EGroupware product leads to remote code execution - CVE-2026-27823
A critical authorization bypass in EGroupware allows attackers to achieve remote code execution through arbitrary file upload and file read primitives. We break down the vulnerability, exploitation chain, responsible disclosure process, and how it was fixed by the EGroupware team.

During a recent vulnerability assessment, we identified a critical security issue affecting EGroupware - CVE-2026-27823. The vulnerability allows an attacker to execute arbitrary commands on an EGroupware instance using any valid account. Furthermore, if user registration is enabled on the server, this could be exploited without authentication.
The vulnerability has been fixed in version 23.1.20260224, 26.2.20260224 or higher. Users are strongly recommended to upgrade the EGroupware instances
The Vulnerability
Within EGroupware\SmallParT\Widgets\SmallPartMediaRecorder::ajax_upload() the application attempts to verify whether the current user is the teacher of the specified course ID.

Then it politely uploads the given file into the controllable file path.

Even though we asked Claude if the isTeacher check is bypassable, it said no; we decided to take a look by ourselves and then discovered the way to leverage it.
The authorization check is either insufficient or improperly enforced, allowing an attacker to bypass the intended access control mechanism. The most important check is that the course access list for the given course ID must contain $required_acl(self::ROLE_TEACHER) i.e., 3.

The key realization: $data['video']['course_id'] comes from attacker-controlled JSON. Nothing forces it to be an integer. If the attacker sends it as an array, every is_array($course) branch in isParticipant activates in the attacker's favor.
The course_acl for this course ID is taken from the request. It is quite a complex flow, but in short, if the request is like:
data={ "video": { "course_id": { "participants": [ { "account_id": "7", "name": "Test", "joined_at": "2026-01-10","participant_role":3 } ], "account_id": "7","course_id":"1" }, "video_hash": ".", "video_type": "/../../../../../../../../../usr/share/egroupware/header.inc.php" } }
Then the course access list is taken from the value participant_role. By simply setting it to 3, we can bypass the isTeacher check.

And the file path is taken from the video_path value.

One important thing is that, since the server is running as the www-data user, we can only edit the header.inc.php file.

Writing a PHP webshell directly into header.inc.php is not sufficient. In practice, OPcache prevents modifications to the file from taking effect immediately, so the injected code may never be executed. Moreover, an invalid header.inc.php would prevent EGroupware from starting, effectively taking the application offline.
Fortunately, gaining control over header.inc.php still provides multiple paths to code execution. One of the most interesting is the $GLOBALS['egw_info']['flags']['autoload']
During initialization, autoload.php checks whether this value is defined and callable. If so, it invokes it via call_user_func(), allowing an attacker to execute arbitrary PHP code.

For demonstration purposes, simply appending phpinfo(); to the file is enough to prove code execution. However, this introduces another challenge: the modified header.inc.php must remain syntactically valid and preserve its original functionality. Otherwise, the application will fail to start before the injected code can ever be reached.
Then we found another vulnerability that allows arbitrary file read:
This vulnerability lies in importexport_export_ui::download
where the server accepts _filename and uses it to read the file.

And we can read the file content

Finally, with that file content, we can obtain a valid header.inc.php file using the request.

After the server restarts or the cache expires, the server will execute the function. Also, another effective way is to change the admin setup password to fully control the server.

As an example, we ran a test on https://demo.egroupware.net/ to verify that it works.

We decided not to modify that content because it would break the system. We stopped there and reported it to the EGroupware team.
Timeline
Date | Event |
|---|---|
February 24, 2026 | Cenobe reported the vulnerability to EGroupware |
February 24, 2026 | EGroupware team fixed the vulnerability |
July 06, 2026 | The vulnerability was published on GitHub Advisories |
July 08, 2026 | We published this article |
Our track record
We also maintain undisclosed zero-day research. Vulnerability research is core to what we do at Cenobe. It's not a side project. It's part of how we stay sharp, how we understand real-world attack surfaces, and how we deliver better results for our clients across penetration testing, red teaming, and attack surface management. If you'd like to talk about what we do, we're at cenobe.com.