# XML external entity (XXE) prevention

- **Pattern:** `ab-002396` (`security-hardening.input-validation.xxe-prevention`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002396
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002396)

## Why it matters

XML External Entity injection (CWE-611, OWASP A05 Security Misconfiguration) enables attackers to read arbitrary files from the server filesystem, perform SSRF, and in some parsers execute server-side code — all via a crafted XML payload. NIST 800-53 SI-10 requires input validation. Any XML parser that processes DTDs and external entities by default is vulnerable to a trivially constructed payload: `<!DOCTYPE foo [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]>`. This affects SAML authentication flows, SOAP integrations, SVG uploads, and any endpoint that parses XML from external sources.

## Severity rationale

Medium because XXE requires an XML-consuming endpoint, but when present it can read any file the process has access to, including private keys and environment files.

## Remediation

Configure every XML parser to disable external entity resolution and DTD processing. For `fast-xml-parser`:

```ts
import { XMLParser } from 'fast-xml-parser'

const parser = new XMLParser({
  processEntities: false,  // Disable all entity processing
  ignoreAttributes: false,
})
const result = parser.parse(xmlString)
```

For SAML flows, use a hardened library (e.g., `samlify` with schema validation enabled) rather than a general-purpose XML parser. Audit every dependency that lists `xmldom`, `libxmljs`, or `sax` — these libraries have different defaults and may need explicit configuration in `lib/xml-parser.ts`.

## Detection

- **ID:** `xxe-prevention`
- **Severity:** `medium`
- **What to look for:** List all XML parsing locations in the codebase. For each parser, search for XML parsing in the codebase. Look for `xml2js`, `fast-xml-parser`, `xmldom`, `libxmljs`, `sax`, `expat` dependencies. When found, check their configuration for `resolveEntities: false`, external entity handling, and DTD processing settings.
- **Pass criteria:** XML parsing is configured with external entity resolution disabled and DTD processing disabled. If the library used does not support disabling these (old `libxml`), it has been replaced or the parsing is sandboxed — 100% of XML parsers must disable external entities. Report: "X XML parsing locations found, all Y have external entity processing disabled."
- **Fail criteria:** XML is parsed with a library that has external entity resolution enabled by default and the configuration does not explicitly disable it.
- **Skip (N/A) when:** The application does not parse XML input (including SOAP, SVG uploads, SAML responses — check for each explicitly).
- **Detail on fail:** `"xml2js configured without disableExternalEntities — may be vulnerable to XXE attacks if parsing user-supplied XML"` or `"fast-xml-parser used without processEntities: false in lib/xml-parser.ts"`
- **Remediation:** Configure XML parsers to disable dangerous features:

  ```ts
  import { XMLParser } from 'fast-xml-parser'

  // Safe configuration for fast-xml-parser
  const parser = new XMLParser({
    processEntities: false,   // Disable entity processing
    ignoreAttributes: false,
  })
  const result = parser.parse(xmlString)

  // For xml2js:
  import { parseString } from 'xml2js'
  parseString(xmlString, {
    explicitArray: false,
    // xml2js does not natively parse external entities, but validate input anyway
  }, (err, result) => { /* ... */ })
  ```

  For SAML parsing, use libraries specifically designed for SAML security (saml2-js with current versions, or use a managed auth provider).

## External references

- cwe CWE-611
- owasp A05
- nist SI-10

Taxons: injection-and-input-trust

HTML version: https://auditbuffet.com/patterns/ab-002396
