XML parser created without XXE hardening
ID |
java.insecure_xml_parser_configuration |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Misconfiguration |
Language |
Java |
Tags |
ASVS50:v1.5.1, CWE:611, CWE:776, OWASP:2025:A02 |
Description
An XML parser or parser factory is created and no setting hardening it against XML External Entity (XXE) processing is applied to it. Left at its defaults, a JAXP, StAX or TrAX parser resolves the DTDs and external entities declared in the documents it parses.
Rationale
java.xml_entity_injection reports XXE when a data path can be followed from an external input to
the parser. That is the right answer for application code, but it needs the input to be visible: a
parser built in a codec, a utility class or a shared library, where the caller lives in another
project, has no source to follow and is reported by nothing.
The parser setup is unsafe on its own terms, independent of who calls it. This detector reports the
setup, so a library that hands an unhardened parser to its callers is visible without having to guess
at reachability. Its severity is low because the finding says nothing about whether attacker-controlled
XML actually reaches the parser — when that can be shown, java.xml_entity_injection reports it as
critical.
What counts as hardening
A parser is considered hardened when setFeature, setAttribute or setProperty applies any
XXE-relevant setting to it — disallow-doctype-decl, external-general-entities,
external-parameter-entities, load-external-dtd, secure processing, accessExternalDTD,
accessExternalSchema, accessExternalStylesheet, supportDTD or
isSupportingExternalEntities — written either as the literal feature URI or as the corresponding
XMLConstants / XMLInputFactory constant.
The value passed is deliberately not inspected. The question this detector answers is whether the parser was hardened at all; a setting deliberately pushed to the unsafe value is a different defect.
setExpandEntityReferences, setValidating, setNamespaceAware and setXIncludeAware do not
count. expandEntityReferences is true by default in JAXP, so writing it explicitly changes
nothing, and setting it to false does not stop the parser from resolving external entities — it
only stops them being expanded into the tree. Accepting it as hardening would hide the defect it
looks like it fixes.
Examples
Reported — no hardening anywhere on the factory:
public Object decode(File file) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // reported
return dbf.newDocumentBuilder().parse(file);
}
Not reported — the factory carries a hardening setting:
public Object decode(File file) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
return dbf.newDocumentBuilder().parse(file);
}
Remediation
Disable DTD processing entirely where the documents parsed do not need it:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
When a DTD must be accepted, turn off external entity resolution instead:
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);
For TransformerFactory and SchemaFactory, deny external access:
TransformerFactory tf = TransformerFactory.newInstance();
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
tf.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
For StAX:
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);