| Description: | XML external entity (XXE) vulnerability in the SqlXmlUtil code in Apache Derby, when a Java Security Manager is not in place, allows context-dependent attackers to read arbitrary files or cause a denial of service (resource consumption) via vectors involving XmlVTI and the XML datatype |
| Code with Misuse: |
class SqlXmlUtil {
/**
* Constructor: Initializes objects required for parsing
* and serializing XML values. Since most XML operations
* that require XML-specific classes perform both parsing
* and serialization at some point, we just initialize the
* objects up front.
*/
public SqlXmlUtil() throws StandardException
{
try {
/* Note: Use of DocumentBuilderFactory means that we get
* whatever XML parser is the "default" for the JVM in
* use--and thus, we don't have to hard-code the parser
* name, nor do we have to require that the user have a
* specific parser in his/her classpath.
*
* This DocumentBuilder is currently used for parsing
* (esp. XMLPARSE), and the SQL/XML spec says that XMLPARSE
* should NOT perform validation (SQL/XML[2006], 6.15:
* "Perform a non-validating parse of a string to produce
* an XML value."). So we disable validation here, and
* we also make the parser namespace aware.
*
* At some point in the future we will probably want to add
* support for the XMLVALIDATE function--but until then, user
* is unable to validate the XML values s/he inserts.
*
* Note that, even with validation turned off, XMLPARSE
* _will_ still check the well-formedness of the values,
* and it _will_ still process DTDs to get default values,
* etc--but that's it; no validation errors will be thrown.
*/
DocumentBuilderFactory dBF = null;
try {
dBF = DocumentBuilderFactory.newInstance();
} catch (Throwable e) {
/* We assume that if we get an error creating the
* DocumentBuilderFactory, it's because there's no
* JAXP implementation. This can happen in the
* (admittedly unlikely) case where the classpath
* contains the JAXP _interfaces_
* and the Xalan classes but does not actually
* contain a JAXP _implementation_. In that case the
* check in XML.checkXMLRequirements() will pass
* and this class (SqlXmlUtil) will be instantiated
* successfully--which is how we get to this constructor.
* But then attempts to create a DocumentBuilderFactory
* will fail, bringing us here. Note that we can't
* check for a valid JAXP implementation in the
* XML.checkXMLRequirements() method because we
* always want to allow the XML.java class to be
* instantiated, even if the required XML classes
* are not present--and that means that it (the
* XML class) cannot reference DocumentBuilder nor
* any of the JAXP classes directly.
*/
throw StandardException.newException(
SQLState.LANG_MISSING_XML_CLASSES, "JAXP");
}
dBF.setValidating(false);
dBF.setNamespaceAware(true);
// Load document builder that can be used for parsing XML.
dBuilder = dBF.newDocumentBuilder();
dBuilder.setErrorHandler(new XMLErrorHandler());
// Load serializer for serializing XML into string according
// XML serialization rules.
loadSerializer();
} catch (StandardException se) {
// Just rethrow it.
throw se;
} catch (Throwable t) {
/* Must be something caused by JAXP or Xalan; wrap it in a
* StandardException and rethrow it. Note: we catch "Throwable"
* here to catch as many external errors as possible in order
* to minimize the chance of an uncaught JAXP/Xalan error (such
* as a NullPointerException) causing Derby to fail in a more
* serious way. In particular, an uncaught Java exception
* like NPE can result in Derby throwing "ERROR 40XT0: An
* internal error was identified by RawStore module" for all
* statements on the connection after the failure--which we
* clearly don't want. If we catch the error and wrap it,
* though, the statement will fail but Derby will continue to
* run as normal.
*/
throw StandardException.newException(
SQLState.LANG_UNEXPECTED_XML_EXCEPTION, t, t.getMessage());
}
// At construction time we don't have an XML query expression
// to compile. If one is required, we'll load/compile it later.
query = null;
}
}
|