Description
Parsing untrusted XML while allowing DTDs or external entity references can expose local files, send requests to internal or external addresses, or exhaust resources through entity expansion.
Explicitly setting JAXP XMLConstants.FEATURE_SECURE_PROCESSING to false disables implementation security limits. Setting it to true through the JDK API enables processing limits and restricts external access. However, behavior varies across implementations and runtimes, so this feature alone is not a universal XXE defense. Control DTD use and external DTD/schema access separately.
XMLReaderFactory has been deprecated since Java 9; use SAXParserFactory for new code. The old API's presence alone does not establish a vulnerability: examine its actual security configuration and trust boundary.
Potential impact
- Sensitive file disclosure: Local files readable by the application may be exposed.
- Server-side request forgery (SSRF): The application may contact internal services or an attacker-controlled server.
- Denial of service: Entity expansion and XML processing can exhaust CPU and memory.
Remediation
- Reject DTDs when they are unnecessary. On JDK 25, prefer
jdk.xml.dtd.support=denyin JAXP configuration or a JVM system property. For parser-local settings, sethttp://apache.org/xml/features/disallow-doctype-decltotrue. - Enable secure processing and restrict external access explicitly. Set
XMLConstants.FEATURE_SECURE_PROCESSINGtotrue, and setXMLConstants.ACCESS_EXTERNAL_DTDandXMLConstants.ACCESS_EXTERNAL_SCHEMAto empty strings to reject external protocols. - If DTDs are required, narrow their permitted use. Disable external general entities, external parameter entities, and external DTD loading. Resolve only approved resources through a local XML catalog or reviewed resolver, and retain finite processing limits.
Examples
Before
import java.io.InputStream;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
public final class UnsafeXXE {
static void parse(InputStream xml) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
SAXParser parser = factory.newSAXParser();
parser.parse(xml, new DefaultHandler());
}
}
This code explicitly disables secure-processing limits and parses input without restricting DTDs or external access.
Also review inline parsing that omits local security settings.
import jakarta.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilderFactory;
public final class InlineServletXXE {
static void parse(HttpServletRequest request) throws Exception {
DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(request.getInputStream());
}
}
Factory creation and parsing occur in one expression, leaving no point to configure the factory or parser locally. Deployment-wide JAXP settings may still protect the runtime by denying DTDs and external access.
After
import java.io.InputStream;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
public final class SafeXXE {
static void parse(InputStream xml) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setFeature(
"http://apache.org/xml/features/disallow-doctype-decl",
true
);
SAXParser parser = factory.newSAXParser();
parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
parser.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
parser.parse(xml, new DefaultHandler());
}
}
This example assumes that DTDs are unnecessary. It rejects DOCTYPE and explicitly blocks external DTD/schema access in addition to enabling secure processing.
References
- Oracle Java 25 JAXP Security Guide
- Oracle Java 25
XMLConstants - Oracle Java 25
DocumentBuilderFactory - Oracle Java 25
SAXParserFactory - Oracle Java 25
XMLReaderFactory - OWASP XML External Entity Prevention Cheat Sheet
- OWASP ASVS 5.0.0 V1.5.1
- CWE-611: Improper Restriction of XML External Entity Reference