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?

Ankit Rustagi
  • 5,539
  • 12
  • 39
  • 70
  • So as to not throw out the quality for security. You can use [**XML catalogs**](https://en.wikipedia.org/wiki/XML_Catalog) for local (checked) copies of DTD files – Joop Eggen Aug 08 '16 at 15:44

2 Answers2

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.

coastalhacking
  • 307
  • 2
  • 13
  • 1
    This is not working currently. We get this exception Property 'http://javax.xml.XMLConstants/property/accessExternalDTD' is not recognized. – Ganesh Bhat Nov 04 '16 at 09:23
  • @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. – coastalhacking Nov 21 '16 at 17:43
  • 1
    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 resources – usr-local-ΕΨΗΕΛΩΝ Mar 01 '17 at 15:32
  • @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? – coastalhacking Mar 03 '17 at 15:04
  • 2
    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. – usr-local-ΕΨΗΕΛΩΝ Mar 03 '17 at 15:23
-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)));
ani
  • 1
  • 2