...
This compliant solution defines a CustomResolver
class that implements the interface org.xml.sax.EntityResolver
. This interface enables a SAX application to customize handling of external entities. The setEntityResolver()
method registers the instance with the corresponding SAX driver. The customized handler uses a simple whitelist for external entities. The resolveEntity()
method returns an empty InputSource
when an input fails to resolve to any of the specified, safe entity source paths. Consequently, when parsing malicious input, the empty InputSource
returned by the custom resolver causes a java.net.MalformedURLException
to be thrown. Note that you must create an XMLReader
object on which to set the custom entity resolver.
Following is an example of component-based sanitization:
Code Block | ||
---|---|---|
| ||
import java.io.IOException; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; class CustomResolver implements EntityResolver { public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { // Check for known good entities String entityPath = "/home/username/java/xxe/file"; if (systemId.equals(entityPath)) { System.out.println("Resolving entity: " + publicId + " " + systemId); return new InputSource(entityPath); } else { return new InputSource(); // Disallow unknown entities by returning a blank path return // by returning a blank pathnew InputSource(); } } } |
The setEntityResolver()
method registers the instance with the corresponding SAX driver. When parsing malicious input, the empty InputSource
returned by the custom resolver causes a java.net.MalformedURLException
to be thrown. Note that you must create an XMLReader
object on which to set the custom entity resolver.
Code Block | ||
---|---|---|
| ||
class XXE { private static void receiveXMLStream(InputStream inStream, DefaultHandler defaultHandler) throws ParserConfigurationException, SAXException, IOException { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); // To set the entity resolver, Create an XML reader to needsset tothe beentity createdresolver. XMLReader reader = saxParser.getXMLReader(); reader.setEntityResolver(new CustomResolver()); reader.setContentHandler(defaultHandler); InputSource is = new InputSource(inStream); reader.parse(is); } public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException { receiveXMLStream(new FileInputStream("evil.xml"), new DefaultHandler()); } } |
...