Tip #59: Parse XML Safely with Trusted Domains
Parsing XML documents can expose your application to vulnerabilities like XML External Entity (XXE) injection when external entities point to untrusted domains. To safeguard against this, you can implement an EntityResolver
to allow only safe domains during parsing. I learned this studying for a test in my job, but I thought it was a good tip for today!
Situation:
Imagine your application processes XML files uploaded by external users. An attacker could include an external entity pointing to an untrusted domain, potentially leading to data leaks or a denial-of-service attack. How can you prevent this?
Solution: Use an EntityResolver
An EntityResolver
allows you to implement an allowlist of safe domains. Here’s an example:
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class SafeEntityResolver implements EntityResolver {
@Override
public InputSource resolveEntity(String publicId, String systemId) {
if (systemId != null && systemId.startsWith("http://safe-domain.com/")) {
System.out.println("Safe domain detected");
return new InputSource(new StringReader("")); // Allow safe domain
}
throw new SecurityException("Unsafe domain detected: " + systemId);
}
}
// Usage
import javax.xml.parsers.DocumentBuilderFactory;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new SafeEntityResolver());
Document document = builder.parse(new File("input.xml"));
In this example:
Only external entities from http://safe-domain.com/ are resolved.
An exception is thrown if an unsafe domain is detected, ensuring no malicious resources are processed.
Extra Tip: If You Don’t Need External Entities
For most cases, you can disable external entities entirely for maximum security. Here's how:
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setFeature("http://javax.xml.XMLConstants/feature/secure-processing", true);
By doing this, you eliminate the risk associated with external entities while keeping your XML parsing simple and secure.
Have you ever encountered XML-related security issues? Let’s discuss your experiences!
Happy coding!