I am given an XML document that must be allowed to have a Document Type Declaration (DTD), but we prohibit any ENTITY declarations.
The XML document is parsed with SAXParser.parse()
, as follows:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
The XML is then passed into the parser as an InputSource
:
InputSource inputSource= ... ;
parser.parse(inputSource, handler);
And the handler
has a resolveEntity
method, which SAXParser.parse()
calls:
public InputSource resolveEntity(String pubID, String sysID) throws SAXException {
InputSource inputSource = null;
try {
inputSource = entityResolver.resolveEntity(publicId, systemId);
}
catch (IOException e) {
throw new SAXException(e);
}
return inputSource;
}
When I pass in an XML file with an ENTITY reference, it seems that nothing is being done - no exceptions are thrown and nothing is stripped - to or about the prohibited ENTITY reference.
Here is an example of the bad XML I am using. The DTD should be allowed, but the !ENTITY line should be disallowed:
<!DOCTYPE foo SYSTEM "foo.dtd" [
<!ENTITY gotcha SYSTEM "file:///gotcha.txt"> <!-- This is disallowed-->
]>
<label>&gotcha;</label>
What do I need to do to make sure that ENTITY references are disallowed in the XML, but that DTDs are still allowed?
Set a org.xml.sax.ext.DeclHandler
on the SaxParser.
parser.setProperty("http://xml.org/sax/properties/declaration-handler", myDeclHandler);
The DeclHandler gets notified when a internal entity declaration is parsed. To disallow entity decls you can simple throw a SAXException:
public class MyDeclHandler extends org.xml.sax.ext.DefaultHandler2 {
public void internalEntityDecl(String name, String value) throws SAXException {
throw new SAXException("not allowed");
}
}