XXE is a bug hiding in a place that looks purely mechanical: parsing XML. The XML format lets a document define entities, and some of those entities can point at external things, a file path, a URL. If your parser resolves them and the document came from a user, the parser can be made to read files off your server and hand them back. The parser is doing exactly what the format allows, which is what makes it easy to miss.
How it works
The default parser in several languages resolves external entities, so a crafted document can reference a local file:
# the vulnerable pattern: default parser resolves external entities import xml.etree.ElementTree as ET tree = ET.parse(user_uploaded_file) # a crafted doc reads /etc/passwd
A payload that defines an entity pointing at /etc/passwd or your config file gets that file's contents included in the parsed result. The same technique can reach internal services the server can talk to.
Want to see exactly what Prbl flags? Watch it scan a demo app, no repo or account needed.
See a live scan →The fix: use a parser that refuses external entities
Disable external entity processing, or use a hardened parser. In Python, defusedxml is a drop-in replacement:
import defusedxml.ElementTree as ET tree = ET.parse(user_uploaded_file) # external entities are blocked
In other languages, set the parser options that disable DTDs and external entities. And if you do not actually need XML, accepting JSON avoids the whole class. The full walkthrough is in the fix for XXE in XML parsing. Like insecure deserialization, the fix is to use a parser that cannot be told to do more than read data.
Frequently asked questions
What is XXE?
XXE stands for XML external entity injection. XML lets a document define entities, including ones that pull in external content like a file path or a URL. If your parser resolves those external entities and the XML comes from a user, a crafted document can make the parser read files off your server or fetch internal resources, and include the result in the parsed output.
What can an attacker read?
Whatever the server process can access. A classic payload points an entity at a local file like the system password file or your configuration, and the parser dutifully includes its contents. XXE can also be used to reach internal services the server can talk to, similar to server-side request forgery, and in some cases to cause denial of service.
Why does it happen in AI-built apps?
Because the default XML parser in several languages resolves external entities unless you turn that off, and the assistant uses the default parser to handle an upload or an API that accepts XML. It works fine on normal documents, so nothing signals the risk. The danger appears only when someone submits a document crafted to abuse external entities.
What is the fix?
Disable external entity and DTD processing in your XML parser, or use a hardened parser that does so by default. In Python, defusedxml is a drop-in replacement that blocks these attacks. In other languages, set the parser features that disable external entities. If you do not need XML at all, accepting JSON instead avoids the class entirely.
Check where your app parses XML
Any endpoint that parses user-supplied XML with a default parser is worth a look, and a scan flags the pattern. Run a free scan and see whether your XML parsing is safe.