A DOM parser builds an in-memory document tree. Its factory must state whether external DTD and schema references may be opened before parsing untrusted XML.
Java DOM parsing: deny external XML access at the factory
Operational contract
This method accepts at most 47,000 input bytes, enables secure processing, and denies external DTD and schema access at the factory. It makes namespace processing explicit. These settings block external resource access through those JAXP properties; they are not a universal bound on every internal expansion or document shape. Set processing limits suited to the deployed JDK and validate the resulting structure before using values. A DOM tree retains nodes for the document, so use a streaming parser when input size cannot be tightly bounded. The caller owns the input bytes; this method owns its parser.
Failure case
A supplier sends a manifest containing an external entity reference. The parser must not fetch a local file or remote resource as a side effect of reading that manifest. The same intake rejects a 47,001-byte payload before building a tree. A valid but deeply nested 47,000-byte document still needs a depth policy at the service boundary.
Java code
import java.io.ByteArrayInputStream;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class BoundedManifestDom {
public static Document parse(byte[] xml) throws Exception {
if (xml.length > 47_000) throw new IllegalArgumentException("Manifest XML exceeds cap");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
return factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml));
}
}Performance and ownership cost
Parsing B input bytes is at least O(B) work and retains a tree whose memory can substantially exceed B. The byte cap limits source size, not the exact number of nodes or expanded text. Reject unsupported security settings rather than silently falling back to an unsafe parser.
Common Mistakes
- Do not let the parser use default external-access policy for untrusted input.
- Do not treat secure processing as a complete document-size or depth limit.
- Do not build a DOM for an unbounded stream.
Connected lessons
- Java file I/O: UTF-8, streaming reads, and path ownership
- Java CharsetDecoder: reject malformed UTF-8 instead of replacing bytes
- Java ZIP entry extraction: cap expanded bytes while reading
- Java StAX: pull XML events under a count and entity policy
- Java XPath: compile a fixed selection, not user-supplied code
- Java XML Schema validation: use a trusted schema without external fetches
- Java XML Transformer: bound serialized output and external access
- Java XML namespaces: select by URI and local name
- Java XML and archive boundaries quiz
- Advanced Java
