package testcode.xxe; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class SaxParserSafeEntityResolver { public static class CustomResolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { return new InputSource(); // Do not allow unknown entities, by returning blank path } } private static void receiveXMLStream(final InputStream inStream, final DefaultHandler defHandler) throws ParserConfigurationException, SAXException, IOException { // ... SAXParserFactory spf = SAXParserFactory.newInstance(); final SAXParser saxParser = spf.newSAXParser(); XMLReader reader = saxParser.getXMLReader(); reader.setEntityResolver(new CustomResolver()); //Custom resolver InputSource is = new InputSource(inStream); reader.parse(is); } public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { String xmlString = "<?xml version=\"1.0\"?>" + "<!DOCTYPE foo SYSTEM \"C:/test\"><test>&foo;</test>"; // Tainted input InputStream is = new ByteArrayInputStream(xmlString.getBytes()); receiveXMLStream(is, new DefaultHandler()); } }