Medium severityGHSA Advisory· Published May 7, 2026· Updated May 7, 2026
CVE-2026-41891
CVE-2026-41891
Description
CI4MS is a CodeIgniter 4-based CMS skeleton that delivers a production-ready, modular architecture with RBAC authorization and theme support. From version 0.26.0 to before version 0.31.8.0, the auth filter has the deactivated/banned user check commented out. This issue has been patched in version 0.31.8.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ci4-cms-erp/ci4msPackagist | >= 0.26.0, < 0.31.8.0 | 0.31.8.0 |
Affected products
1- Range: >= 0.26.0, <= 0.31.7.0
Patches
12f38284281cesecurity:resolve arbitrary table drop and session bypass vulnerabilities
9 files changed · +67 −38
CHANGELOG.md+8 −0 modified@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) conventions adapted to the existing four-component version numbers. +## [0.31.8.0] - 2026-04-19 + +### Fixed + +- **Security (Session Management):** Re-activated user account status verification in `Ci4MsAuthFilter`. Deactivated or banned users now have their sessions immediately terminated upon their next request, remediating a session bypass flaw. +- **Security (Arbitrary Table Drop):** Implemented migration-based whitelist validation in `Theme::deleteProcess`. This ensures that selectively dropping database tables during theme deletion is restricted exclusively to tables declared within the specific theme's migration files, preventing arbitrary database table deletion. + ## [0.31.7.0] - 2026-04-17 ### Added @@ -286,6 +293,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) - Expanded database migrations and introduced new supporting libraries. +[0.31.8.0]: https://github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.8.0 [0.31.7.0]: https://github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.7.0 [0.31.6.0]: https://github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.6.0 [0.31.5.0]: https://github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.5.0
composer.json+1 −1 modified@@ -23,7 +23,7 @@ "codeigniter4/translations": "4.7.0", "ezyang/htmlpurifier": "4.19", "gregwar/captcha": "1.3.0", - "studio-42/elfinder": "2.1.66" + "studio-42/elfinder": "2.1.67" }, "require-dev": { "fakerphp/faker": "^1.9",
composer.lock+7 −7 modified@@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d086c1578c2121d3653c4bb8d056ff9a", + "content-hash": "eb2830c2098f60123c81540a89c34295", "packages": [ { "name": "bertugfahriozer/ci4commonmodel", @@ -840,16 +840,16 @@ }, { "name": "studio-42/elfinder", - "version": "2.1.66", + "version": "2.1.67", "source": { "type": "git", "url": "https://github.com/Studio-42/elFinder.git", - "reference": "78488951e44d69e8b9e4e849f8268df408632a6c" + "reference": "5e463d1384972dffcb736ad3c94f35af10656ca2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Studio-42/elFinder/zipball/78488951e44d69e8b9e4e849f8268df408632a6c", - "reference": "78488951e44d69e8b9e4e849f8268df408632a6c", + "url": "https://api.github.com/repos/Studio-42/elFinder/zipball/5e463d1384972dffcb736ad3c94f35af10656ca2", + "reference": "5e463d1384972dffcb736ad3c94f35af10656ca2", "shasum": "" }, "require": { @@ -896,15 +896,15 @@ "homepage": "http://elfinder.org", "support": { "issues": "https://github.com/Studio-42/elFinder/issues", - "source": "https://github.com/Studio-42/elFinder/tree/2.1.66" + "source": "https://github.com/Studio-42/elFinder/tree/2.1.67" }, "funding": [ { "url": "https://github.com/nao-pon", "type": "github" } ], - "time": "2025-08-28T11:51:22+00:00" + "time": "2026-04-17T03:02:32+00:00" }, { "name": "symfony/finder",
.gitignore+0 −15 modified@@ -135,31 +135,16 @@ template app/Config/Routes.php *.zip .history -.devilbox -htdocs public/uploads/.tmb/ public/uploads/.trash/ public/media/.tmb/ writable/tmp/* bertug_s_docs -modules/Grapes -modules/ActivityLog -modules/Crm -modules/Cronjobs -modules/DocumentManager -modules/EmailManagement -modules/FormBuilder -modules/TaskManager -modules/LicenseServer -modules/LicenseClient -modules/TaskManager -public/be-assets/plugins/grapesjs .agent build/ dist/ composer.lock.json .antigravityignore .claude -modules/Notifications tests/* phpunit.xml.dist
modules/Auth/Filters/Ci4MsAuthFilter.php+4 −4 modified@@ -13,12 +13,12 @@ public function before(RequestInterface $request, $arguments = null) if (! auth()->loggedIn()) { return redirect()->route('login'); } - /* $user = auth()->user(); - if ($user && ($user->isBanned() || !$user->active)) { - auth('session')->logout(); + $user = auth()->user(); + if ($user && ($user->isBanned() || (isset($user->active) && (int)$user->active === 0))) { + auth('session')->logout(); return redirect()->route('login')->with('error', lang('Auth.bannedUser')); - } */ + } $router = service('router'); $controllerName = $router->controllerName();
modules/Backend/Commands/Ci4msSetup.php+1 −1 modified@@ -218,7 +218,7 @@ public function run(array $params) 'app.supportedLocales' => '["ar","de","en","es","fr","hi","ja","pt","ru","tr","zh"]', 'app.negotiateLocale' => 'true', 'app.appTimezone' => '\'Europe/Istanbul\'', - 'app.version' => '0.31.7.0', + 'app.version' => '0.31.8.0', ]; if (!$this->updateEnvSettings($updates)) {
modules/Install/Controllers/Install.php+1 −1 modified@@ -66,7 +66,7 @@ public function index() 'app.supportedLocales' => '["ar","de","en","es","fr","hi","ja","pt","ru","tr","zh"]', 'app.negotiateLocale' => 'true', 'app.appTimezone' => '\'Europe/Istanbul\'', - 'app.version' => '0.31.7.0' + 'app.version' => '0.31.8.0' ]; if ($this->copyEnvFile() && $this->updateEnvSettings($updates)) $this->generateEncryptionKey();
modules/Theme/Controllers/Theme.php+44 −8 modified@@ -24,11 +24,32 @@ public function upload() // Allowed static file extensions for the public/ directory. // PHP files MUST NOT be written under public/ (RCE prevention). $allowedPublicExtensions = [ - 'css', 'js', 'map', - 'png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'ico', 'bmp', 'avif', - 'woff', 'woff2', 'ttf', 'eot', 'otf', - 'xml', 'json', 'txt', 'md', - 'mp4', 'webm', 'ogg', 'mp3', 'wav', + 'css', + 'js', + 'map', + 'png', + 'jpg', + 'jpeg', + 'gif', + 'svg', + 'webp', + 'ico', + 'bmp', + 'avif', + 'woff', + 'woff2', + 'ttf', + 'eot', + 'otf', + 'xml', + 'json', + 'txt', + 'md', + 'mp4', + 'webm', + 'ogg', + 'mp3', + 'wav', 'pdf', ]; @@ -142,16 +163,31 @@ public function deleteProcess(string $slug) return redirect()->route('templateSettings')->with('errors', [lang('Theme.themeActiveCannotDelete')]); } + $allowedTables = []; + $migrationPath = APPPATH . 'Database/Migrations/templates/' . $themeName; + if (is_dir($migrationPath)) { + $files = glob($migrationPath . '/*.php'); + foreach ($files as $file) { + $content = file_get_contents($file); + preg_match_all("/\\\$this->forge->createTable\s*\(\s*['\"]([^'\"]+)['\"]/i", $content, $matches); + if (!empty($matches[1])) { + foreach ($matches[1] as $tName) { + $allowedTables[] = $tName; + } + } + } + } + $allowedTables = array_unique($allowedTables); $log = []; - // Delete tables (selected ones) $tablesToDrop = $this->request->getPost('tables'); if (!empty($tablesToDrop) && is_array($tablesToDrop)) { $forge = \Config\Database::forge(); $db = \Config\Database::connect(); foreach ($tablesToDrop as $table) { - if ($db->tableExists($table)) { + // Sadece izin verilen (temaya ait) tabloları sil + if (in_array($table, $allowedTables) && $db->tableExists($table)) { $forge->dropTable($table, true); - $log[] = "🗑️ Table deleted: $table"; + $log[] = "🗑️ " . lang('Theme.tableDeleted', [$table]); } } }
README.md+1 −1 modified@@ -201,6 +201,6 @@ A huge thank you to the security researchers who have helped make **ci4ms** more | **[offset](https://github.com/offset)** | Identified Critical vulnerabilities including multiple Stored XSS, Authorization Bypass in Fileeditor, Install Guard Bypass, and CRLF Injection. | Apr 2026 | | **[fg0x0](https://github.com/fg0x0)** | Identified Critical Arbitrary File Write (Zip Slip RCE) vulnerabilities in Theme::upload and Backup::restore modules. | Apr 2026 | | **[0xAlchemist](https://github.com/bugmithlegend)** , **[peeefour](https://github.com/peeefour)** and **[DexterHK](https://github.com/DexterHK)** | Identified Critical Full Account Takeover and Privilege Escalation via Stored DOM Blind XSS in Backup Management (v2). | Apr 2026 | -| **[dapickle](https://github.com/dapickle)** | Identified Critical Authenticated Remote Code Execution (RCE) via unrestricted PHP file upload in Theme installation | Apr 2026 | +| **[dapickle](https://github.com/dapickle)** | Identified Critical Authenticated RCE in Theme installation, Arbitrary Database Table Drop in Theme module, and a Session Management Bypass. | Apr 2026 | > If you find a security vulnerability, please report it via [Security Policy](SECURITY.md).
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-5hfv-c864-qcq9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-41891ghsaADVISORY
- github.com/ci4-cms-erp/ci4ms/commit/2f38284281ce6b435ea42003951f14109ac2cea7ghsaWEB
- github.com/ci4-cms-erp/ci4ms/releases/tag/0.31.8.0nvdWEB
- github.com/ci4-cms-erp/ci4ms/security/advisories/GHSA-5hfv-c864-qcq9nvdWEB
News mentions
0No linked articles in our index yet.