XXE Through RSS: Exposing Files with CVE‑2023‑38490 in Kirby CMS

When parsing goes wrong… bad things happen.

XML was built to organize data, but when poorly handled, it can organize a disaster. That’s what happened with Kirby CMS and CVE‑2023‑38490, where a simple RSS feed parser became an entry point for an XML External Entity (XXE) attack.

In this article, we’ll break down how XXE works, the risks it brings to your business, and finish with a hands-on PoC showing how a crafted XML can turn your server into an open book.

So… get your parser ready. Let’s inject some external knowledge.

What is XML and External Entities?

Before diving into the vulnerability, let’s quickly revisit what XML is.

XML (eXtensible Markup Language) is a popular format for storing and exchanging structured data. It shows up everywhere—from web services to config files and RSS feeds.

XML files are built with elements (tags), attributes, and occasionally, entities. Entities act like shortcuts or references inside the document, allowing parts of the data to be reused or pulled from external sources. For example:

<!DOCTYPE example [
  <!ENTITY company "VSec Security">
]>
<message>
  Hello from &company;!
</message>

In this example, every time &company; appears, the XML parser will replace it with “VSec Security” during processing.

What Are External Entities?

Now comes the interesting part. XML also supports something called external entities. Instead of defining a simple string inside the XML, you can tell the parser to fetch the content from an external file or even a remote URL.

Example:

<!DOCTYPE example [
  <!ENTITY secret SYSTEM "file:///etc/passwd">
]>
<data>
  &secret;
</data>

If the parser doesn’t have proper restrictions, it will happily load the contents of /etc/passwd (or any other file the web server can access) and inject it directly into the parsed output.

This is the foundation of an XXE attack.

What is an XXE Attack?

XXE (XML External Entity) is a vulnerability that happens when an application processes XML input and allows external entities to be resolved.

By sending a crafted XML payload, an attacker can trick the server into reading local files, making internal HTTP requests, or even causing a Denial of Service (DoS).

Here’s a simple XXE example:

<?xml version="1.0"?>
<!DOCTYPE data [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<info>&xxe;</info>

If the server processes this, it may leak the contents of /etc/passwd back in the response.

Real-World Impact: Why XXE Matters

An XXE vulnerability isn’t just a coding flaw—it’s a real business risk.

For attackers, it opens the door to:

  • Reading sensitive files (like config files or credentials)
  • Triggering SSRF attacks, reaching internal services
  • Causing DoS, crashing the app with malicious payloads

For the business, the fallout can mean:

  • Data leaks and compliance violations
  • Reputation damage
  • Financial loss from extended breaches

A small mistake in XML parsing can easily snowball into a serious incident.

Proof of Concept (PoC)

For this PoC, we’ll explore CVE‑2023‑38490, a vulnerability in Kirby CMS that allows XML External Entity (XXE) injection during feed parsing. The goal is to demonstrate how an attacker can craft a malicious XML payload to read sensitive files from the server, exploiting the way Kirby processes external XML feeds.

So here’s the part of the payload that will return the contents of the /etc/passwd file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
[. . .]

The full payload is quite large, but I used this repository as inspiration:

https://github.com/Acceis/exploit-CVE-2023-38490

And here’s the final result:

Under the hood:

  • The XML parser, with LIBXML_NOENT enabled, expands declared entities pointing to external files.
  • As Kirby processes each feed item (in your foreach loop), the parser includes file contents directly in the link, description, or other fields.
  • The application then reads and handles that data, effectively leaking sensitive server files.

Conclusion

XXE vulnerabilities might look minor at first, but CVE‑2023‑38490 in Kirby CMS proves otherwise. One poorly configured XML parser can turn a simple feed import into a serious data leak.

Always sanitize inputs, disable external entity resolution, and keep your software up to date.

In security, trusting external feeds without checks is like leaving your front door wide open for the wrong visitor. Sometimes, it’s not just news coming in—it’s your sensitive data going out.


Comentários

Leave a Reply

Discover more from VSec

Subscribe now to keep reading and get access to the full archive.

Continue reading