Disable DTD in javax XML Validator
Asked Answered
A

2

7

I am using javax.xml.validation.Validator to validate my xml as below -

        Validator validator = myschema.newValidator();
        validator.validate(new StreamSource(new StringReader(xmlString)));

I would like to prevent XML External Entity attacks by disabling DTDs (Document Type Definitions) completely, so I'd like for the validator to throw an exception in case of a DTD in my xml if possible. I have read about doing this using DocumentBuilderFactory. How do i do configure this in Validator?

Agathy answered 2/8, 2016 at 12:53 Comment(1)
So as to not throw out the quality for security. You can use XML catalogs for local (checked) copies of DTD filesMichealmicheil
C
4

According to the OWASP XXE prevention spreadsheet for Java, the following should work:

SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema myschema = factory.newSchema();
Validator validator = myschema.newValidator();
try {
  validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
  validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
  validator.validate(new StreamSource(new StringReader(xmlString)));
} catch ...

Refer to the XMLConstants JavaDocs for more details.

Captive answered 8/8, 2016 at 14:55 Comment(5)
This is not working currently. We get this exception Property 'javax.xml.XMLConstants/property/accessExternalDTD' is not recognized.Gargoyle
@GaneshBhat - you might want to open a new SA question, posting details of your setup including Java version, XML provider vendor and version, etc. Feel free to link here if you do.Captive
This is not working for me as now I get a SAXParseException because the validator is unable to access the external because of that option. Actually the question title suggests about completely disabling the dtd, while the text on the contrary refers explicitly to the remote retrieval of xml resourcesAvent
@usr-local-ΕΨΗΕΛΩΝ, well the text also specifies "disabling DTDs [...] completely" too. In your case, did you provide a scheme that matched where your DTDs are, e.g. jar:file if they were in a local JAR, for the ACCESS_EXTERNAL_DTD option?Captive
Well, I did not. I just wanted to disable DTD validation completely. You may ask what is the purpose of that... Well, I have an official XSD that is equivalent to the DTD and I provided it to my validator. But the validator, once detecting the presence of the DTD declaration in the body of the XML, requires the DTD to be loaded. Terrific. Maybe I just wanted to validate the document against the correct XML integrity at this stage and perform additional checks later. That is the point of my comment. Yes, I see that "completely" is part of the question text and I do apologize now for that.Avent
P
-1

This would also work-

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

Schema myschema = factory.newSchema();

Validator validator = myschema.newValidator();

validator.validate(new StreamSource(new StringReader(xmlString)));
Poitiers answered 15/7, 2020 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.