Exploits to the limitations of the JAXP implementation can happen only when applications process untrusted XML, XSD, or XSL files. Internal systems and applications generally do not need to worry about such threats. Even applications that have external exposure may not be subject to these threats so long as they do not take untrusted XML, XSD, or XSL files as input.
The limits are closely related to the default memory size settings in a Java Virtual Machine (JVM). That is, they are designed so that excessive DTD constructs are caught by the limits when the JVM is started with the default memory setting, and especially the memory size, for the client VM. They can be increased when running with an increased memory setting or on a server VM, if needed.
In general, the default limits have been set to relatively large numbers that are enough for most applications. It is recommended that users evaluate the usages and set the limits to the smallest possible value so that, in the event of encountering malformed inputs, the problem can be caught earlier without wasting too many resources.
To help users analyze what are proper limits, a special property called http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo is available. The following code snippet shows an example of using the property:
parser.setProperty("http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo", "yes");
See Samples for more information on downloading the example code.
When the program is run with the DTD in W3C MathML 3.0, it prints out the following table:
Property | Limit | Total Size | Size | Entity Name |
---|---|---|---|---|
ENTITY_EXPANSION_LIMIT | 64000 | 1417 | 0 | null |
MAX_OCCUR_NODE_LIMIT | 5000 | 0 | 0 | null |
ELEMENT_ATTRIBUTE_LIMIT | 10000 | 0 | 0 | null |
TOTAL_ENTITY_SIZE_LIMIT | 50000000 | 55425 | 0 | null |
GENEAL_ENTITY_SIZE_LIMIT | 0 | 0 | 0 | null |
PARAMETER_ENTITY_SIZE_LIMIT | 1000000 | 0 | 7303 | %MultiScriptExpression |
MAX_ELEMENT_DEPTH_LIMIT | 0 | 2 | 0 | null |
In this example, the total number of entity references, or the entity expansion, is 1417; the default limit is 64000. The total size of all entities is 55425; the default limit is 50000000. The biggest parameter entity is %MultiScriptExpression with a length of 7303 after all references are resolved; the default limit is 1000000.
If this is the largest file that the application is expected to process, it is recommended that the limits be set to smaller numbers. For example, 2000 for ENTITY_EXPANSION_LIMIT, 100000 for TOTAL_ENTITY_SIZE_LIMIT, and 20000 for PARAMETER_ENTITY_SIZE_LIMIT.
Limits can be set in the same way as other JAXP properties. They can be set through factory methods, or through the parser:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setAttribute(name, value); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); parser.setProperty(name, value); XMLInputFactory xif = XMLInputFactory.newInstance(); xif.setProperty(name, value); SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage); schemaFactory.setProperty(name, value); TransformerFactory factory = TransformerFactory.newInstance(); factory.setAttribute(name, value);
The following example shows how to set limits using DocumentBuilderFactory:
dbf.setAttribute(JDK_ENTITY_EXPANSION_LIMIT, "2000"); dbf.setAttribute(TOTAL_ENTITY_SIZE_LIMIT, "100000"); dbf.setAttribute(PARAMETER_ENTITY_SIZE_LIMIT, "20000"); dbf.setAttribute(JDK_MAX_ELEMENT_DEPTH, "100");
System properties may be useful if changing code is not feasible.
To set limits for an entire invocation of the JDK or JRE, set the system properties on the command line. To set the limits for only a portion of the application, the system properties may be set before the section and cleared afterwards. The following code shows how system properties may be used:
public static final String SP_GENEAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit"; //set limits using system property System.setProperty(SP_GENEAL_ENTITY_SIZE_LIMIT, "2000"); //this setting will affect all processing after it's set ... //after it is done, clear the property System.clearProperty(SP_GENEAL_ENTITY_SIZE_LIMIT);
See Samples for more information on downloading the example code.
The jaxp.properties file is a plain configuration file. It is located at ${java.home}/lib/jaxp.properties where java.home is the JRE install directory, e.g., [path to installation directory]/jdk7/jre.
A limit can be set by adding the following line to the jaxp.properties file:
jdk.xml.maxGeneralEntitySizeLimit=2000
Note that the property name is the same as that of the system property and has the prefix jdk.xml.
When the property is set via the file, all invocations of the JDK and JRE will observe the limit.