Back to scan results
Check 30 of 45

XML External Entity (XXE) Injection

We look for public same-origin XML, SOAP, WSDL, ASMX, SVC, and XML-RPC processors. Only after an endpoint is positively identified do we send one small XML document whose external entity references a controlled public PCIScan canary.

What this check probes

The discovery stage inspects same-origin links and form actions, then checks a small set of common public paths such as /xmlrpc.php, /soap, /service.asmx?WSDL, and /api?wsdl.

A generic XML POST is sent only when the endpoint's content type, WSDL/SOAP response, XML-RPC message, or HTTP method behavior indicates an actual XML processor. The document defines one external entity pointing to https://pciscan.org/robots.txt.

The check fails only if known canary-file content appears in the XML endpoint's response and was absent from its discovery response. Parser errors explicitly rejecting DTD or entity processing are recorded as protection.

This check never requests local files, loopback or private networks, cloud metadata, alternate protocols, parameter entities, expansion bombs, SVG uploads, or authenticated endpoints. It cannot detect blind XXE when the parser resolves an entity without returning content.

Why this matters for PCI DSS

An XML parser that resolves attacker-controlled external entities can disclose application files, make server-side requests, expose credentials, or consume excessive resources. The impact is amplified when the parser runs inside a trusted network or cardholder-data environment.

PCI DSS secure-development requirements expect untrusted structured data to be parsed with hardened settings and unnecessary features disabled. A pass covers only discovered public XML endpoints, not file imports, uploads, message queues, office-document processing, or authenticated APIs.

How to fix it

Disable DTD processing and external resolution. For .NET Framework, create the reader explicitly and pass that reader to the XML API:

var settings = new XmlReaderSettings
{
    DtdProcessing = DtdProcessing.Prohibit,
    XmlResolver = null,
    MaxCharactersInDocument = 1_000_000
};

using (var reader = XmlReader.Create(inputStream, settings))
{
    var document = XDocument.Load(reader, LoadOptions.None);
}

Do not replace Prohibit with Parse unless DTD support is unavoidable. If it is unavoidable, use a tightly restricted custom resolver and an explicit allowlist; never use a general network-capable resolver for untrusted input.

Apply equivalent secure settings to every parser used by SOAP, SAML, SVG, office documents, imports, and third-party libraries. Enforce request-size, nesting, and processing-time limits, and use outbound network controls so parser configuration is not the only barrier.

Fixed it? Re-run the scan to confirm.

Run scan again