CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-32870

CVE-2026-32870: XML Injection via Unsafe CDATA Handling in Kirby CMS Toolkit

Amit Schendel
Amit Schendel
Senior Security Researcher

Apr 24, 2026·6 min read·20 visits

Executive Summary (TL;DR)

An input validation flaw in Kirby CMS allows attackers to bypass XML escaping by starting input with a CDATA tag. Attackers can terminate the CDATA block early and inject arbitrary XML tags, potentially altering data structures in RSS feeds, sitemaps, or API responses. Upgrading to versions 4.9.0 or 5.4.0 patches the vulnerability.

Kirby CMS versions prior to 4.9.0 and 5.0.0 through 5.3.x are vulnerable to XML Injection (CWE-91). An insecure heuristic within the Toolkit's XML handling methods permits an attacker to bypass entity encoding by prepending a CDATA identifier. This allows the injection of arbitrary XML elements into documents generated by the CMS or custom plugins.

Vulnerability Overview

Kirby CMS utilizes the Kirby\Toolkit\Xml class and the Kirby\Data\Data class to handle formatting and encoding of XML data. These components are frequently leveraged by site-specific templates and plugins to generate structured outputs such as RSS feeds, Sitemaps, SOAP responses, and REST API payloads. Untrusted input processed by these methods must be strictly encoded to prevent structural alteration of the resulting document.

This vulnerability, tracked as CVE-2026-32870 and GHSA-9wfj-c55w-j9qr, constitutes an XML Injection (CWE-91). The flaw originates from an insecure validation heuristic used to detect strings that are already safely encapsulated. By exploiting this flaw, an attacker can construct a payload that bypasses the escaping routines entirely.

The attack surface includes the Xml::value(), Xml::tag(), Xml::create(), and Data::encode($input, 'xml') methods. If an application routes attacker-controlled input through any of these functions, the attacker can manipulate the syntax of the generated XML document. The core rendering engine for Kirby pages is largely unaffected by default, restricting the primary impact to custom features or plugins explicitly using the toolkit for XML generation.

Root Cause Analysis

The root cause resides in the Xml::value() method within src/Toolkit/Xml.php. This method prepares strings for XML output by applying htmlspecialchars() to prevent characters like < and > from being parsed as structural tags. The method attempts to optimize processing by skipping this escaping process if the input is already encapsulated in a Character Data (CDATA) section.

Prior to the patch, the application used a superficial validation check to identify pre-escaped data. It relied exclusively on Str::startsWith($value, '<![CDATA['). If an untrusted input string began with this specific sequence, the method assumed the entire string was a single, valid CDATA block and returned it verbatim without applying any entity encoding.

Because the validation logic only inspected the prefix of the string, an attacker could supply a payload that opens a CDATA block, immediately terminates it using ]]>, and then appends raw XML syntax. The vulnerable code would identify the prefix, skip the htmlspecialchars() function, and inject the mixed payload directly into the XML document. Downstream parsers would correctly terminate the CDATA section and then interpret the attacker's appended tags as legitimate structural elements.

Code Analysis

The vulnerable implementation in src/Toolkit/Xml.php executed a simple string prefix match. The code lacked any verification regarding the termination of the CDATA block or the presence of malformed structural elements within the string payload.

// Vulnerable Implementation (Kirby < 4.9.0 / < 5.4.0)
public static function value(string $value): string
{
    // Flaw: Only validates the start of the string.
    // Attacker can terminate CDATA early and inject tags.
    if (Str::startsWith($value, '<![CDATA[') === true) {
        return $value;
    }
    
    return htmlspecialchars($value, ENT_QUOTES | ENT_XML1, 'UTF-8');
}

The remediation, applied in commits a88ef33e81ed286d9dddf5a2f2d239aa73cd0d31 and 9309d5242fbfddf6650dc6c5fd8212765ce49ee6, enforces a strict structural contract. To bypass escaping, the string must now satisfy three conditions: it must start with a CDATA opener, end with a CDATA closer, and contain no internal unescaped CDATA closures.

// Patched Implementation (Kirby 4.9.0 / 5.4.0)
public static function value(string $value): string
{
    // Fix: Validates complete encapsulation and prevents internal breaks
    if (
        Str::startsWith($value, '<![CDATA[') === true &&
        Str::endsWith($value, ']]>') === true &&
        Str::matches($value, '/\]\]>(?!<!\[CDATA\[|$)/') === false
    ) {
        return $value;
    }
    
    // Any malformed or injected data falls through to htmlspecialchars
    return htmlspecialchars($value, ENT_QUOTES | ENT_XML1, 'UTF-8');
}

Exploitation Mechanics

Exploitation requires an attacker to inject controlled input into a field processed by the Xml toolkit or the Data::encode() wrapper. Common injection points include blog post titles, user profile fields, or custom metadata that a site administrator later exports to an RSS feed or third-party integration.

The core exploitation technique leverages early termination of the CDATA block. An attacker supplies a payload formatted as <![CDATA[test]]><malicious_tag>payload</malicious_tag>. When the vulnerable application calls Xml::value() on this string, the prefix matches, and the raw payload is written to the output file.

When an external system parses the resulting document, the XML parser interprets <![CDATA[test]]> as a valid character block containing the word 'test'. The parser then encounters <malicious_tag> and evaluates it as an active document node. Attackers can also utilize comment smuggling techniques, such as <![CDATA[test]]><!-- comment -->, to hide injected logic or bypass WAF signatures looking for standard tags.

The proof-of-concept payloads from the patch test suite confirm that inputs like <![CDATA[ ]]> <juhu>haha</juhu> successfully bypass the escaping mechanism. In a patched environment, this same payload is safely encoded as <![CDATA[<![CDATA[ ]]]]><![CDATA[><juhu>haha</juhu>]]>, neutralizing the injection.

Impact Assessment

This vulnerability carries a CVSS 4.0 base score of 6.9, described by the vector CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:H/SA:N. The score reflects a high impact on system integrity, specifically the integrity of the generated XML documents, with no required privileges or user interaction.

The concrete impact depends heavily on the downstream consumer of the generated XML. If the XML is an RSS feed, an attacker can modify the feed's structure to inject unauthorized links or content. If the generated XML is a configuration file or a SOAP request used in a backend integration, the attacker may bypass business logic or trigger unexpected application behavior in the consumer system.

While the vulnerability permits arbitrary tag injection, it does not directly enable Remote Code Execution (RCE) on the Kirby server itself. Furthermore, if the generated XML is rendered directly in a web browser without proper content-type headers, the injected tags may result in Cross-Site Scripting (XSS).

Remediation and Mitigation

The definitive remediation for CVE-2026-32870 is upgrading Kirby CMS to a patched release. Administrators must update installations to either version 4.9.0 or version 5.4.0. These releases contain the necessary regular expression fixes to enforce proper CDATA encapsulation.

For environments where immediate patching is unfeasible, developers should audit site-specific templates and plugins. Any calls to Kirby\Toolkit\Xml methods or Kirby\Data\Data::encode($val, 'xml') that process untrusted data must be identified. Developers can implement an interim manual sanitization layer by pre-processing user input with htmlspecialchars() before passing it to the Kirby toolkit.

Security teams can monitor for exploitation attempts by applying Web Application Firewall (WAF) rules or Intrusion Detection System (IDS) signatures. Rules should inspect incoming HTTP request bodies and URL parameters for the sequence <![CDATA[ immediately followed by ]]> within the same field payload, as this strongly indicates an attempt to exploit the parsing heuristic.

Official Patches

KirbyKirby CMS 4.9.0 Release Notes and Patch
KirbyKirby CMS 5.4.0 Release Notes and Patch

Fix Analysis (2)

Technical Appendix

CVSS Score
6.9/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:N/SC:N/SI:H/SA:N

Affected Systems

Kirby CMS ToolkitKirby CMS Data handlers

Affected Versions Detail

Product
Affected Versions
Fixed Version
Kirby CMS
Kirby
< 4.9.04.9.0
Kirby CMS
Kirby
>= 5.0.0, < 5.4.05.4.0
AttributeDetail
CWE IDCWE-91
Attack VectorNetwork
CVSS Base Score6.9
ImpactHigh System Integrity
Exploit StatusProof of Concept
Affected ComponentKirby\Toolkit\Xml

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1566Phishing
Initial Access
CWE-91
XML Injection

Improper Neutralization of Special Elements used in an XML Document

Known Exploits & Detection

Patch Unit TestsProof of concept payloads present within the patch unit test suite.

Vulnerability Timeline

Initial fix commit for Kirby 4.x (a88ef33)
2026-03-16
Merge of fix into release branch 5.3.4 (later 5.4.0)
2026-03-30
CVE and GHSA officially published
2026-04-24

References & Sources

  • [1]GitHub Security Advisory: GHSA-9wfj-c55w-j9qr

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•3 minutes ago•GHSA-8FPG-XM3F-6CX3
7.4

GHSA-8FPG-XM3F-6CX3: Authentication Fail-Open via Unvalidated Server Responses in Auth.js

In Auth.js (specifically next-auth version 5), server-side configuration errors or backend exceptions can cause existence-based authentication and authorization checks to fail open. When the underlying core engine (@auth/core) encounters a configuration error or runtime exception, it returns an HTTP 500 Internal Server Error response containing a JSON-formatted error description payload. Prior to the fix, the next-auth wrappers read this response body using response.json() without validating the HTTP status code. Because any parsed JavaScript object evaluates to truthy, common existence-based checks incorrectly evaluated to true, letting unauthenticated requests pass.

Alon Barad
Alon Barad
0 views•7 min read
•about 2 hours ago•CVE-2026-6790
5.3

CVE-2026-6790: Host/Authority Header Desynchronization in Eclipse Jetty

A host/authority desynchronization vulnerability exists in Eclipse Jetty's handling of HTTP/2 and HTTP/3 requests. When both an ':authority' pseudo-header and a standard 'Host' header are present in a request, Jetty fails to validate that they represent the same target host. This desynchronization creates a host-confusion or 'split-brain' state, enabling attackers to bypass access control lists, escape virtual host isolation, poison web caches, or manipulate redirect targets in backend applications.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 3 hours ago•CVE-2026-8384
5.3

CVE-2026-8384: URI Path Parameter Parser State-Desynchronization Path Traversal in Eclipse Jetty

A path traversal vulnerability exists in Eclipse Jetty due to a state-desynchronization defect in the URI parsing state machine inside URIUtil.java. This defect allows unauthenticated remote attackers to bypass path-based security constraints enforced by downstream filters, application gateways, or authorization modules by crafting URIs with path parameter delimiters and parent directory traversal sequences.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•GHSA-WHVH-WF3X-G77J
0.0

GHSA-WHVH-WF3X-G77J: Improper Access Control and Listing Bypass in JupyterLab Extension Manager

An improper access control vulnerability in JupyterLab allows programmatic installation of blocked or non-allowed extensions. The vulnerability is caused by a missing await keyword when invoking the asynchronous checking method, leading Python to evaluate the returned coroutine object as truthy. Furthermore, the check lacks proper canonicalization of package names, enabling an attacker to bypass blocklists using casing or character variants.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 4 hours ago•CVE-2026-42980
7.8

CVE-2026-42980: Windows Kernel Local Privilege Escalation via WMI Integer Underflow

An unsigned 32-bit integer underflow vulnerability in the Windows Management Instrumentation (WMI) serialization subsystem of ntoskrnl.exe allows local authenticated users with low privileges to corrupt adjacent kernel pool allocations, execute arbitrary kernel-mode read and write operations, and perform a Token Swap attack to escalate their privileges to NT AUTHORITY\SYSTEM.

Amit Schendel
Amit Schendel
7 views•7 min read
•about 5 hours ago•GHSA-H5V5-8746-G7MM
6.0

GHSA-H5V5-8746-G7MM: JupyterLab PluginManager Lock-Rule Enforcement Bypass

JupyterLab's PluginManager contains an authorization bypass vulnerability allowing authenticated users to modify the state of locked extensions or plugins. Although the frontend user interface visually locks and disables toggle components for administrative configurations, the backend API fails to perform robust validation. Standard users can craft direct HTTP API requests to modify plugin states, completely bypassing administrative restrictions.

Amit Schendel
Amit Schendel
8 views•5 min read