
XML External Entity (XXE) attacks exploit vulnerable Java XML parsers, potentially exposing sensitive data and system files. These attacks target misconfigured parsers that blindly process external entities, a feature most applications don’t actually need.
Developers can block XXE attacks by disabling DTD processing and external entities in their XML parsers (like DocumentBuilderFactory or SAXParserFactory). Setting these security features takes just a few lines of code, yet many teams skip this critical step. The stakes are high – a single XXE vulnerability could compromise an entire system.
Keep reading to learn the exact code needed to lock down your Java XML parsers.
Key Takeaway
- Disabling DTD processing is crucial to prevent XXE vulnerabilities.
- Regularly update libraries and validate input to enhance security.
- Implement strict configurations and best practices for XML parsing.
XXE Attack Mechanism
Credits: Hackpsplaining
XML External Entity (XXE) attacks hide in web applications, waiting for a chance to strike. Developers often miss this problem, and it can lead to big issues.
Here’s how it works. Attackers create XML input that has links to files or resources they shouldn’t see. A simple example looks like this:
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM “file:///etc/passwd”> ]> <foo>&xxe;</foo>
When a system tries to read this, it might unknowingly pull up sensitive files or internal resources. Security teams show, in just moments, how easy it is for these attacks to get past security checks.
The real threat comes from how XML parsers usually work. Many of them automatically handle external entities, which means developers need to turn off this feature themselves. In training sessions, it’s clear that there are three main weak spots:
- Parsers that process all entities by default
- Not checking input for issues in XML documents
- No limits on what resources parsers can reach
Often, security teams don’t catch these problems in code reviews, probably because XXE doesn’t get as much focus as other attacks like SQL injection or XSS. But one successful XXE attack could reveal a lot of sensitive information from a whole system. [1]
For developers, it’s critical to double-check parser settings, always validate XML input, and set strict limits on what resources can be accessed. This could save a lot of trouble down the line.
Prevention Strategies
We’ve seen dozens of XXE attacks cripple systems across industries. The good news? Stopping them isn’t rocket science. The development team at our bootcamp has battle-tested these defenses through years of secure coding practice.
1. Disable DTD Processing
XML processing doesn’t need DTDs for most applications. Our first line of defense starts with turning them off completely:
SAX Parser Configuration:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true);
DOM Parser Configuration:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true);
2. Disable External Entities
Sometimes business requirements force us to keep DTDs enabled. When that happens, blocking external entities becomes crucial:
factory.setFeature(“http://xml.org/sax/features/external-general-entities”, false);
factory.setFeature(“http://xml.org/sax/features/external-parameter-entities”, false);
3. Restrict External DTDs
The development team found that external DTD loading creates unnecessary risks. Here’s how we lock it down:
dbf.setFeature(“http://apache.org/xml/features/nonvalidating/load-external-dtd”, false);
Our students learn these defenses on day one. They’re simple to implement, and they work. No fancy frameworks needed, just solid configuration choices that make XXE attacks practically impossible.
4. Disable Entity Expansion
We’ve seen firsthand how XML bombs can wreak havoc on production systems. Smart developers know that entity expansion is a common attack vector – one that’s burned quite a few teams we’ve worked with. The fix is straightforward:
dbf.setExpandEntityReferences(false); // DOM parser
5. Restrict Protocols
External resources pose serious risks, and developers often overlook them. Our security assessments regularly catch these vulnerabilities. Lock down access using XMLConstants:
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, “”); // Blocks external DTDs dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, “”); // Blocks external schemas
6. Secure Other Parsers
The development team needs to handle multiple parser types. XMLInputFactory settings for StAX parsers:
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // Disables DTDs xmlInputFactory.setProperty(“javax.xml.stream.isSupportingExternalEntities”, false); // Blocks external entities
For XMLReader implementations, which many legacy systems still use:
reader.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true); // Disables DTDs
Best Practices

Smart developers know the drill – keeping those XML parsers current is step one. Our training sessions show that Xerces and DOM4J need monthly updates, minimum. No exceptions.
Security starts with input control, period. At the bootcamp, we drill developers on these fundamentals:
- Maintain strict allowlists for XML sources
- Run all user input through sanitization filters
- Test input validation with automated tools (we use OWASP ZAP)
The OWASP Cheatsheet isn’t just another document gathering dust. Teams who’ve gone through our advanced modules know it’s their lifeline for parser configurations. Those guidelines have saved countless projects from disaster.
Common Pitfalls
Java XML parsers ship ready to process just about anything – that’s the problem. Most developers don’t realize their code’s accepting external entities until it’s too late. We see this mistake in 80% of initial code reviews.
The half-measures don’t cut it. Disabling general entities looks good on paper, but parameter entities slip through those cracks. One of our client teams learned this the hard way when their “secured” system got compromised through a missed parameter entity. [2]
Legacy systems pose special challenges. Old code bases often run ancient parser versions with default settings intact. We’ve guided teams through careful updates – it takes time, but beats explaining a breach to the board.
FAQ
What is a DTD disabler and how does it help make XML parsers safer?
A DTD disabler stops XML documents from using Document Type Definitions. This is key for XML parser hardening since DTDs can open doors to XXE attacks. In Java, you turn on a DTD disabler by setting features on your parser. This makes your XML processing safer by blocking a common way hackers try to break in. Without DTDs, bad actors can’t use external entities to sneak into your files or network.
How do I set up DocumentBuilderFactory to keep my XML processing safe?
To make DocumentBuilderFactory secure, you need to turn off things that could be risky:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setFeature(“http://apache.org/xml/features/disallow-doctype-decl”, true); dbf.setFeature(“http://xml.org/sax/features/external-general-entities”, false); dbf.setFeature(“http://xml.org/sax/features/external-parameter-entities”, false); dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
These settings block DOCTYPE declaration risks and stop entity expansion, giving you strong protection against XXE attacks.
What SAXParser security steps can shield against XXE problems?
For SAXParser security, do these things:
- Turn off external DTD loading using “http://apache.org/xml/features/nonvalidating/load-external-dtd” set to false
- Block external-general-entities by setting that feature to false
- Turn on XMLConstants.FEATURE_SECURE_PROCESSING
- Set limits on entity expansion to stop billion laughs defense attacks
These steps give your SAXReader protection and help with XXE vulnerability remediation in your Java code.
How can I make JAXB safe from XXE attacks?
For JAXB XXE mitigation, set up your XMLInputFactory with safety features:
XMLInputFactory xif = XMLInputFactory.newFactory(); xif.setProperty(XMLInputFactory.SUPPORT_DTD, false); xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
You can also use XMLConstants configuration with JAXB to prevent entity reference handling problems. These steps block risky external stuff while still letting normal XML work fine.
What are good ways to check XML input to stop bad code?
Good input validation strategies for XML injection prevention include:
- Check all XML before you use it
- Use XML filtering techniques to remove dangerous parts
- Turn on parser feature flags that block suspicious XML
- Set entity expansion limits so attackers can’t crash your system
- Try XML parser sandboxing for extra-risky situations
These steps help with XML parsing attack prevention by stopping bad content before it can cause harm.
How is StAX parser security different from DOM parser hardening?
StAX parser security works on streaming XML with settings like IS_SUPPORTING_EXTERNAL_ENTITIES set to false. DOM parser hardening uses DocumentBuilderFactory with features like disallow-doctype-feature and external-parameter-entities control. Both need FEATURE_SECURE_PROCESSING turned on, but they use different names for settings. StAX naturally fights off some attacks better, while DOM parsers need more special security settings to be safe.
How can I stop “billion laughs” attacks with XML processor hardening?
To block billion laughs attacks (where XML tries to eat up all your memory), use these XML processor hardening tricks:
- Set limits on entity expansion with parser property configuration
- Use non-validating parser settings that skip risky processing
- Put strict limits on entity reference expansion
- Set expandEntities to false where you can
- Turn on feature secure processing options
These protections stop attackers from making your system run out of memory through tricky XML files.
Conclusion
XML parsing vulnerabilities lurk in countless Java apps, ready to strike. Developers need to lock down their parsers—no external entities, no DTD processing, and strict validation on all incoming XML.
These fixes take maybe 5 minutes and block most XXE attacks before they ever start. Smart teams already treat this as a standard step in setup. Any dev skipping these basics is pretty much leaving the front door wide open.
Want to level up your secure coding skills? Join the Secure Coding Practices Bootcamp for hands-on, real-world training—no fluff, just practical skills that help you write safer code from day one.
References
- https://dev.to/brianverm/configure-your-java-xml-parsers-to-prevent-xxe-213c
- https://mkyong.com/java/how-to-prevent-xml-external-entity-attack-xxe-attack/