XML external entity injection (XXE)

XXE

XXE occurs when an XML parser processes attacker-controlled external entities or document type definitions. It can expose local files, trigger server-side requests, or exhaust application resources.

Also known as
XML external entity attack · External entity injection · Blind XXE
Typical severity · Medium to Critical
Last updated
On this page: What it is
  1. 1 · What it is
  2. 2 · Why it matters
  3. 3 · Examples
  4. 4 · How to fix it
  5. 5 · How to test for it
  6. References
  7. Related

What it is#

XML supports document type definitions (DTDs) and entities. Some parsers can resolve an entity by reading a local file or contacting a remote URL. If untrusted XML reaches a parser with those features enabled, the document can cause the server to access resources outside the intended XML data.

XXE may be visible in the response, blind with only an outbound request as evidence, or hidden inside another format. Office documents, SVG images, SAML messages, SOAP requests, and XML-based imports can all reach XML parsers even when an endpoint does not advertise raw XML.

Entity expansion is a related resource-exhaustion risk: a compact document can expand into a much larger in-memory value and consume CPU or memory.

Why it matters#

  • Read local configuration files, application secrets, or service-account material.
  • Make server-side requests to internal services or cloud metadata endpoints.
  • Expose data through error messages or controlled outbound callbacks.
  • Cause denial of service through recursive or excessive entity expansion.
  • Turn trusted XML workflows, including SAML or document conversion, into an internal network access path.
Typical severity

Medium when parsing is isolated and outbound access is blocked. High to critical when local secrets, cloud credentials, identity assertions, or sensitive internal services are reachable. Actual severity depends on context: who is affected, what data or actions are reachable, and existing controls.

Examples#

✕ Vulnerablejava
// Vulnerable: default parser behavior can vary by provider and version.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(uploadedStream);
✓ Fixedjava
// Fixed: disallow DTDs and external entity resolution explicitly.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
factory.setXIncludeAware(false);
factory.setExpandEntityReferences(false);

DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(uploadedStream);

The exact secure settings depend on the parser and runtime version. Treat failure to apply a required security feature as a startup or request error, not as permission to parse insecurely.

How to fix it#

1. Prefer simpler formats. Use JSON or a purpose-built schema when XML features are unnecessary.

2. Disable DTDs completely. This is the strongest general defense. Also disable external general entities, external parameter entities, external DTD loading, XInclude, and automatic entity expansion.

3. Use maintained parser versions and secure factory APIs. Parser defaults have changed over time. Configure every parser instance, including those created by libraries, message frameworks, document converters, and test utilities.

4. Enforce resource limits. Set maximum document size, nesting depth, attributes, entity count, parse time, and memory usage. Reject compressed archives whose expanded size exceeds a defined limit.

5. Restrict network and file access. Run parsers in a low-privilege worker with no access to application secrets and no unnecessary outbound network path. Network controls reduce the impact of configuration mistakes.

6. Validate expected content. Use a local, trusted schema after external resolution is disabled. Do not allow the document to choose a remote schema or stylesheet.

7. Cover indirect XML. Harden SVG, Office, SAML, SOAP, RSS, and document-processing libraries, not only endpoints with an XML content type.

How to test for it#

  • Inventory direct and indirect XML parsers through dependency review, code search, content-type routing, file-upload handling, and background jobs.
  • In an isolated test environment, submit a harmless DTD declaration and confirm that parsing is rejected before entity resolution.
  • Use a controlled callback endpoint to verify that external entities, schemas, stylesheets, and XInclude cannot trigger outbound requests.
  • Reference a dedicated, non-sensitive canary file in a test container; never use operating-system or production secret files as test targets.
  • Exercise recursive and oversized documents within agreed resource limits and confirm the parser terminates safely without affecting neighboring workloads.
  • Test every supported XML-adjacent file type, including SVG and document archives, because different processing paths may use different parsers.
  • Add unit tests that assert the parser's security features are enabled and fail when a runtime upgrade changes their behavior.

References#

Permalinklibrary.infinity8labs.com/xml-external-entity-injection/JSON
Found this in Breachvane? Your finding links here for background. Evidence, affected assets and retest status are in your Breachvane ↗ (opens in a new tab) workspace. Need help fixing it? Talk to us.