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·26 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

•about 1 hour ago•CVE-2026-64849
9.3

CVE-2026-64849: Server-Side Request Forgery (SSRF) in MLflow Webhooks via DNS Rebinding

CVE-2026-64849 is a critical Server-Side Request Forgery (SSRF) vulnerability affecting MLflow tracking servers prior to version 3.15.0. It allows unauthenticated remote attackers to bypass outbound request destination filters using DNS rebinding or HTTP redirects. This exposure risks compromising sensitive cloud infrastructure metadata and internal microservices.

Alon Barad
Alon Barad
2 views•5 min read
•about 2 hours ago•CVE-2026-69146
6.5

CVE-2026-69146: Missing Authorization Bypass in MLflow Basic Authentication Middleware

This technical report details a missing authorization vulnerability (CVE-2026-69146 / GHSA-3p64-6gvh-82v5) affecting the MLflow platform from version 3.13.0 to 3.15.0. When MLflow is configured with the built-in basic-auth plugin, authenticated users can bypass run-level UPDATE authorization checks, enabling unauthorized dataset and model lineage metadata injection.

Alon Barad
Alon Barad
1 views•7 min read
•about 3 hours ago•CVE-2026-69148
7.1

CVE-2026-69148: Broken Object Level Authorization (BOLA) in MLflow Model Registry

MLflow prior to version 3.15.0 fails to perform proper authorization checks when registering model versions, allowing authenticated users with access to a registered model to link and access artifacts from runs and models belonging to other users without authorization.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 4 hours ago•CVE-2026-59893
7.5

CVE-2026-59893: Regular Expression Denial of Service in sqlparse Lexer

A high-severity Regular Expression Denial of Service (ReDoS) vulnerability in the sqlparse Python library prior to version 0.6.0 allows unauthenticated remote attackers to trigger CPU exhaustion and application denial of service via crafted SQL inputs containing unmatched dollar-quoted literals or unclosed multiline comments.

Alon Barad
Alon Barad
4 views•6 min read
•about 5 hours ago•GHSA-FHGH-WQ4Q-R37X
7.8

GHSA-FHGH-WQ4Q-R37X: Remote Code Execution via Sigstore Signature Verification Bypass in uniget CLI

A high-severity logic inversion flaw in the uniget CLI completely bypasses Sigstore cryptographic signature verification on metadata files by default. If an attacker can poison the package metadata cache or repository, they can execute arbitrary OS commands under the privileges of the active user.

Alon Barad
Alon Barad
5 views•5 min read
•about 6 hours ago•CVE-2026-59903
6.5

CVE-2026-59903: Cache Poisoning and Information Disclosure via CorsHandler Vary Header Overwrite

A technical analysis of CVE-2026-59903 in Netty's HTTP CORS handler, where the CorsHandler overwrites existing application Vary headers with Origin, leading to unauthorized caching of sensitive information.

Alon Barad
Alon Barad
5 views•5 min read