Headline
CVE-2022-46751: Java API for XML Processing (JAXP) Security Guide
Improper Restriction of XML External Entity Reference, XML Injection (aka Blind XPath Injection) vulnerability in Apache Software Foundation Apache Ivy.This issue affects any version of Apache Ivy prior to 2.5.2.
When Apache Ivy prior to 2.5.2 parses XML files - either its own configuration, Ivy files or Apache Maven POMs - it will allow downloading external document type definitions and expand any entity references contained therein when used.
This can be used to exfiltrate data, access resources only the machine running Ivy has access to or disturb the execution of Ivy in different ways.
Starting with Ivy 2.5.2 DTD processing is disabled by default except when parsing Maven POMs where the default is to allow DTD processing but only to include a DTD snippet shipping with Ivy that is needed to deal with existing Maven POMs that are not valid XML files but are nevertheless accepted by Maven. Access can be be made more lenient via newly introduced system properties where needed.
Users of Ivy prior to version 2.5.2 can use Java system properties to restrict processing of external DTDs, see the section about “JAXP Properties for External Access restrictions” inside Oracle’s "Java API for XML Processing (JAXP) Security Guide".
The JDK and Java XML APIs have been improved over the years with various measures and tools that can help prevent applications from being exploited by XML-related attacks. This guide shows you how to use the secure processing features of Java API for XML Processing (JAXP) to safeguard your applications and systems.
Potential Attacks During XML Processing
XML processing can expose applications to certain vulnerabilities. Among the most prominent and well-known attacks are the XML External Entity (XXE) injection attack and the exponential entity expansion attack, also know as the XML bomb or billion laughs attack. These attacks can potentially cause serious damage to a system by denying its services or worse, lead to the loss of sensitive data.
You should evaluate your applications’ requirements and operating environment to assess the level of potential threat, for example, whether or to what extent the applications are exposed to untrusted XML sources.
XML External Entity Injection Attack
The XML, XML Schema, and XSLT standards define a number of structures that enable the embedding of external content in XML documents through system identifiers that reference external resources. In general, XML processors resolve and retrieve almost all of these external resources; see External Resources Supported by XML, Schema, and XSLT Standards for a list of constructs that support the inclusion of external resources. In addition, some constructs enable the execution of applications through external functions. XML External Entity (XXE) injection attacks exploit XML processors that have not been secured by restricting the external resources that it may resolve, retrieve, or execute. This can result in disclosing sensitive data such as passwords or enabling arbitrary execution of code.
External Resources Supported by XML, Schema, and XSLT Standards
XML, Schema, and XSLT standards support the following constructs that require external resources. The default behavior of the JDK XML processors is to make a connection and fetch the external resources as specified.
External DTD: references an external Document Type Definition (DTD), for example:
<!DOCTYPE root_element SYSTEM "url">
External Entity Reference: Refers to external data, the following is the syntax:
<!ENTITY name SYSTEM "url">
General entity reference, for example:
<?xml version="1.0" standalone="no" ?> <!DOCTYPE doc [<!ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <a> <b>&otherFile;</b> </a> </doc>
External Parameter Entities: The following is the syntax:
<!ENTITY % name SYSTEM uri>
The following is an example:
<?xml version="1.0" standalone="no"?> <!DOCTYPE doc [ <!ENTITY % ent1 SYSTEM "http://www.example.com/student.dtd"> %ent1; ]>
XInclude: Includes an external infoset in an XML document, for example:
<Book xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href=toc.xml"/> <xi:include href=part1.xml"/> <xi:include href=part2.xml"/> <xi:include href=index.xml"/> </Book>
References to XML Schema components using the schemaLocation attribute and import and include elements, for example:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:include schemaLocation="http://www.example.com/schema/schema1.xsd"/> <!-- ... --> </xs:schema>
Combining style sheets using import or include elements, the following is the syntax:
<xsl:include href="include.xsl"/>
xml-stylesheet processing instruction: Used to include a stylesheet in an XML document, for example:
<?xml-stylesheet href="include.xsl" type="text/xsl"?>
XSLT document() function: Used to access nodes in an external XML document, for example:
<xsl:variable name="dummy" select="document('DocumentFunc2.xml')"/>
Exponential Entity Expansion Attack
The exponential entity expansion attack, also know as the XML bomb or billion laughs attack, is a denial-of-service attack that involves XML parsers. The basic exploit is to have several layers of nested entities, each referring to a number of entities of the next layer. The following is a sample SOAP document that contains deeply nested entity references:
<?xml version="1.0" encoding ="UTF-8"?>
<!DOCTYPE bbb[
<!ENTITY x100 "bbb">
<!ENTITY x99 "&x100;&x100;">
<!ENTITY x98 "&x99;&x99;">
...
<!ENTITY x2 "&x3;&x3;">
<!ENTITY x1 "&x2;&x2;">
]>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=...>
<SOAP-ENV:Body>
<ns1:aaa xmlns:ns1="urn:aaa" SOAP-ENV:encodingStyle="...">
<foobar xsi:type="xsd:string">&x1;</foobar>
</ns1:aaa>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
When an XML parser encounters such a document, it will attempt to resolve the entity declaration by expanding the references. Because the references are nested, the expansion becomes exponential by the number of entities each refers to. Such a process can lead the XML parser to consume 100% of CPU time and a large amount of memory, and eventually the system runs out of memory.
Feature for Secure Processing (FSP)
Feature for Secure Processing (FSP), which is defined as javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, is the central mechanism to help safeguard XML processing. It instructs XML processors, such as parsers, validators, and transformers, to try and process XML securely.
By default, the JDK turns on FSP for DOM and SAX parsers and XML schema validators, which sets a number of processing limits on the processors. Conversely, by default, the JDK turns off FSP for transformers and XPath, which enables extension functions for XSLT and XPath.
Turn on and off FSP by calling the setFeature method on factories and setting XMLConstants.FEATURE_SECURE_PROCESSING to either true or false. For example, the following code snippet turns on FSP for SAX parsers that are created by the factory spf by setting XMLConstants.FEATURE_SECURE_PROCESSING to true:
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
While FSP can be turned on and off through factories, it is always on when a Java Security Manager is present and cannot be turned off. The Java XML processors therefore will enforce limits and restrictions when a Java Security Manager is present. You can however adjust individual properties depending on the specific needs of your applications. There are two types of JAXP properties:
- Processing limits: Helps guard against excessive memory consumption from XML processing.
- External access restrictions: Controls the fetching of external resources.
The following sections describe these two types of JAXP properties.
JAXP Properties for Processing Limits
XML processing can sometimes be a memory intensive operation. Applications, especially those that accept XML, XSD and XSL from untrusted sources, should take steps to guard against excessive memory consumption by using JAXP properties for processing limits.
Evaluate your application’s requirements and operating environment to determine the acceptable processing limits for your system configurations and set these limits accordingly. For example, use size-related limits to prevent malformed XML sources from consuming large amounts of memory. Use EntityExpansionLimit to enable an application to control memory consumption under an acceptable level.
The JDK XML parsers observe processing limits by default. Both DOM and SAX parsers have Feature for Secure Processing (FSP) turned on by default and therefore turn on the limits. The StAX parser also observes processing limits by default even though it doesn’t support FSP.
The JDK XML processors enable you to adjust processing limits individually in three ways:
- Through standard XML APIs
- By using System properties
- In the jaxp.properties file
See Using JAXP Properties and Scope and Order.
The following tables describe the JAXP properties for processing limits supported in the JDK.
Table 13-1 elementAttributeLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/elementAttributeLimit
Definition
Limits the number of attributes an element can have.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
10000
System property
jdk.xml.elementAttributeLimit
Since
7u45, 8
Table 13-2 entityExpansionLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/entityExpansionLimit
Definition
Limits the number of entity expansions.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
64000
System property
jdk.xml.entityExpansionLimit
Since
7u45, 8
Table 13-3 entityReplacementLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/entityReplacementLimit
Definition
Limits the total number of nodes in all entity references.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
3000000
System property
jdk.xml.entityReplacementLimit
Since
7u111, 8u101
Table 13-4 maxElementDepth
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/maxElementDepth
Definition
Limits the maximum element depth.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
0
System property
jdk.xml.maxElementDepth
Since
7u65, 8u11
Table 13-5 maxGeneralEntitySizeLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/maxGeneralEntitySizeLimit
Definition
Limits the maximum size of any general entities.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
0
System property
jdk.xml.maxGeneralEntitySizeLimit
Since
7u45, 8
Table 13-6 maxOccurLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/maxOccurLimit
Definition
Limits the number of content model nodes that may be created when building a grammar for a W3C XML Schema that contains maxOccurs attributes with values other than "unbounded".
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
5000
System property
jdk.xml.maxOccurLimit
Since
7u45, 8
Table 13-7 maxParameterEntitySizeLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/maxParameterEntitySizeLimit
Definition
Limits the maximum size of any parameter entities, including the result of nesting multiple parameter entities.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
1000000
System property
jdk.xml.maxParameterEntitySizeLimit
Since
7u45, 8
Table 13-8 maxXMLNameLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/maxXMLNameLimit
Definition
Limits the maximum size of XML names, including element name, attribute name and namespace prefix and URI.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
1000
System property
jdk.xml.maxXMLNameLimit
Since
7u91, 8u65
Table 13-9 totalEntitySizeLimit
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/totalEntitySizeLimit
Definition
Limits the total size of all entities that include general and parameter entities. The size is calculated as an aggregation of all entities.
Value
A positive integer. A value less than or equal to 0 indicates no limit. If the value is not an integer, a NumericFormatException is thrown.
Default value
5x10^7
System property
jdk.xml.totalEntitySizeLimit
Since
7u45, 8
Legacy System Properties
These properties, which were introduced in JDK 5.0 and 6, continue to be supported for backward compatibility.
Table 13-10 Legacy System Properties Related to Processing Limits
System Property
Since
New System Property
entityExpansionLimit
1.5
jdk.xml.entityExpansionLimit
elementAttributeLimit
1.5
jdk.xml.elementAttributeLimit
maxOccurLimit
1.6
jdk.xml.maxOccur
JAXP Properties for External Access Restrictions
The JAXP Properties for external access restrictions, along with their corresponding System properties, enable you to regulate external connections.
External access restrictions enable you to specify the type of external connections that can or cannot be permitted. The property values are a list of protocols. The JAXP processors check if a given external connection is permitted by matching the protocol with those in the list. Processors will attempt to establish the connection if it is on the list, or reject it if not. Use these JAXP properties along with custom resolvers and the Catalog API (see Using Resolvers and Catalogs) to reduce the risk of external connections by rejecting and resolving them with local resources.
Note:
Explicitly turning on Feature for Secure Processing (FSP) through the API, for example, factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true), disables all external connections.
The external access restrictions JAXP properties are defined in javax.xml.XMLConstants as follows:
- javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD
- javax.xml.XMLConstants.ACCESS_EXTERNAL_SCHEMA
- javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET
Table 13-11 ACCESS_EXTERNAL_DTD
Attribute
Description
Name
http://javax.xml.XMLConstants/property/accessExternalDTD
Definition
Restricts access to external DTDs and external entity references to the protocols specified.
Value
See Values of External Access Restrictions JAXP Properties
Default value
all, connection permitted to all protocols
System property
javax.xml.accessExternalDTD
Table 13-12 ACCESS_EXTERNAL_SCHEMA
Attribute
Description
Name
http://javax.xml.XMLConstants/property/accessExternalSchema
Definition
Restricts access to the protocols specified for external references set by the schemaLocation attribute, import element, and include element.
Value
See Values of External Access Restrictions JAXP Properties
Default value
all, connection permitted to all protocols.
System property
javax.xml.accessExternalSchema
Table 13-13 ACCESS_EXTERNAL_STYLESHEET
Attribute
Description
Name
http://javax.xml.XMLConstants/property/accessExternalStylesheet
Definition
Restricts access to the protocols specified for external references set by the stylesheet processing instruction, document function, and import and include elements.
Value
See Values of External Access Restrictions JAXP Properties
Default value
all, connection permitted to all protocols.
System property
javax.xml.accessExternalStylesheet
Values of External Access Restrictions JAXP Properties
All JAXP properties for external access restrictions have values of the same format:
Value: A list of protocols separated by comma. A protocol is the scheme portion of an URI, or in the case of the JAR protocol, jar plus the scheme portion separated by colon. A scheme is defined as:
scheme = alpha *( alpha | digit | “+” | "-" | “.” )
where alpha = a-z and A-Z.
The JAR protocol is defined as: jar[:scheme]
Protocols are case-insensitive. Any whitespace characters as defined by Character.isSpaceChar in the value are ignored. Examples of protocols are file, http, and jar:file.
Default value: The default value is implementation specific. For the JDK, the default value is all, which grants permissions to all protocols.
Granting all access: The keyword all grants permission to all protocols. For example, specifying javax.xml.accessExternalDTD=all in the jaxp.properties file enables a system to work as before with no restrictions on accessing external DTDs and entity references.
Denying any access: An empty string (“”) means that no permission is granted to any protocol. For example, specifying javax.xml.accessExternalDTD="" in the jaxp.properties file instructs JAXP processors to deny any external connections.
Scope and Order
Scope of Setting Feature for Secure Processing
Feature for Secure Processing (FSP) is required for XML processors including DOM, SAX, schema validation, XSLT, and XPath.
When FSP is turned on, then default processing limits (see JAXP Properties for Processing Limits) are enforced. Turning off FSP does not change the limits.
When FSP is “explicitly” turned on through the API, for example, factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true), then external access restrictions (see JAXP Properties for External Access Restrictions) are set to the empty string, which means that no permission is granted to any protocol. Although FSP is turned on by default for DOM, SAX and schema validation, it is not treated as if “explicitly” turned on; therefore, the default value for external access restrictions is all, which means that permission is granted to all protocols.
When a Java Security Manager is present, FSP is turned on and cannot be turned off.
Scope and Order of Setting JAXP Properties
In general, JAXP properties set in a smaller scope override those in a larger one:
- JAXP properties specified through JAXP factories or processors take preference over System properties, the jaxp.properties file, and FSP.
- System properties, when set, affect one JDK invocation only and override processing limit and external access restriction values set by default, set in the jaxp.properties file, or set by FSP.
- Properties specified in the jaxp.properties file affect the entire JDK and override processing limit and external access restriction values set by default or set by FSP.
Scope of Setting External Access Restrictions
External access restrictions have no effect on the relevant constructs that they attempt to restrict in the following situations:
When there is a resolver and the source returned by the resolver is not null: This applies to entity resolvers that may be set on SAX and DOM parsers, XML resolvers on StAX parsers, LSResourceResolver on SchemaFactory, a Validator or ValidatorHandler, or URIResolver on a transformer.
When a schema is created explicitly by calling the newSchema method from SchemaFactory.
When external resources are not required: For example, the following features and properties are supported by the JDK and may be used to instruct the processor to not load the external DTD or resolve external entities:
http://apache.org/xml/features/disallow-doctype-decl true http://apache.org/xml/features/nonvalidating/load-external-dtd false http://xml.org/sax/features/external-general-entities false http://xml.org/sax/features/external-parameter-entities false
Relationship with Security Manager
JAXP properties are checked first before a connection is attempted, whether or not a SecurityManager is present. This means that a connection may be blocked even if it is granted permission by the SecurityManager. For example, if the JAXP properties are set to disallow the HTTP protocol, then they will effectively block any connection attempt even when an application has a SocketPermission.
For the purpose of restricting connections, the SecurityManager can be viewed as being at a lower level. Permissions are checked after JAXP properties are evaluated. For example, if an application does not have a SocketPermission, then a SecurityException will be thrown even if JAXP properties are set to allow HTTP connections.
When a SecurityManager is present, Feature for Secure Processing (FSP) is set to true. This behavior does not turn on any external access restrictions.
When to Use Processing Limits
When determining which processing limits to apply and what values to use, at the system level, consider the amount of memory available for applications and whether XML, XSD, or XSL sources from untrusted sources are accepted and processed. At the application level, consider whether certain constructs such as DTDs are used.
Memory Setting and Limits
XML processing can be very memory intensive. The amount of memory that should be allowed to be consumed depends on the requirements of the applications in a specific environment. Processing of malformed XML data must be prevented from consuming excessive memory.
The default limits are generally set to allow legitimate XML inputs for most applications with memory usage allowed for a small hardware system, such as a PC. It is recommended that the limits are set to the smallest possible values, so that any malformed input can be caught before it consumes large amounts of memory.
The limits are correlated, but not entirely redundant. You should set appropriate values for all of the limits: usually the limits should be set to a much smaller value than the default.
For example, ENTITY_EXPANSION_LIMIT and GENERAL_ENTITY_SIZE_LIMIT can be set to prevent excessive entity references. But when the exact combination of the expansion and entity sizes are unknown, TOTAL_ENTITY_SIZE_LIMIT can serve as a overall control. Similarly, while TOTAL_ENTITY_SIZE_LIMIT controls the total size of a replacement text, if the text is a very large chunk of XML, ENTITY_REPLACEMENT_LIMIT sets a restriction on the total number of nodes that can appear in the text and prevents overloading the system.
Estimating the Limits Using the getEntityCountInfo Property
To help you analyze what values you should set for the limits, a special property called http://www.oracle.com/xml/jaxp/properties/getEntityCountInfo is available. The following code snippet, from Processing Limit Samples in The Java Tutorials, shows an example of using the property:
public static final String ORACLE_JAXP_PROPERTY_PREFIX =
"http://www.oracle.com/xml/jaxp/properties/";
// ...
public static final String JDK_ENTITY_COUNT_INFO =
ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo";
// ...
parser.setProperty(JDK_ENTITY_COUNT_INFO, "yes");
When you run the processing limit sample with the DTD in W3C MathML 3.0, it prints out the following table:
Table 13-14 Running JAXP Processing Limits Sample with DTD in W3C MatchML 3.0
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
GENERAL_ENTITY_SIZE_LIMIT
0
0
0
null
PARAMETER_ENTITY_SIZE_LIMIT
1000000
0
7303
%MultiScriptExpression
MAX_ELEMENT_DEPTH_LIMIT
0
2
0
null
MAX_NAME_LIMIT
1000
13
13
null
ENTITY_REPLACEMENT_LIMIT
3000000
0
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 10000 for PARAMETER_ENTITY_SIZE_LIMIT.
When to Use External Access Restrictions
The XML processors, by default, attempt to connect and read external resources that are referenced in XML sources. Note that this may potentially expose applications and systems to risks posed by external connections. It’s therefore recommended that applications consider limiting external connections with external access restriction properties.
Internal applications and systems that handle only trusted XML documents may not need these restrictions. Applications and systems that rely on the Java Security Manager to regulate external connections may also have no need for them. However, keep in mind that external access restrictions are specific to the XML processors and are at the top layer of the process, which means that the processors check these restrictions before any connections are made. They may therefore serve as an additional and more direct protection against external connection risks.
You can use external access restriction properties along with custom resolvers and catalogs (see Using Resolvers and Catalogs) to effectively manage external connections and reduce risks.
Even in a trusted environment with trusted sources, it’s recommended that you use both external access restrictions and resolvers to minimize dependencies on external sources.
Using JAXP Properties
Setting Properties Through JAXP Factories
If you can modify your application’s code, or you’re creating a new application, then setting JAXP properties through JAXP factories or a parser is the preferred method. Set these properties through the following interfaces:
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 is an example of setting processing limits:
dbf.setAttribute(JDK_ENTITY_EXPANSION_LIMIT, "2000");
dbf.setAttribute(TOTAL_ENTITY_SIZE_LIMIT, "100000");
dbf.setAttribute(PARAMETER_ENTITY_SIZE_LIMIT, "10000");
dbf.setAttribute(JDK_MAX_ELEMENT_DEPTH, "100");
The following is an example of limiting a DOM parser to only local connections for external DTDs:
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "file, jar:file");
If a parser module within the application handles untrusted sources, it may further restrict access. The following code overrides those in the jaxp.properties file and those specified by System properties and enables the XML processor to read local files only:
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "file");
// ...
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "file");
schemaFactory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "file");
As described in Scope and Order of Setting JAXP Properties, JAXP properties specified through JAXP factories have the narrowest scope, affecting only the processors created by the factories, and therefore override any default settings, System properties, and those in the jaxp.properties file. By setting JAXP properties through JAXP factories, you can ensure that your applications behave the same way regardless of which JDK release you’re using or whether JAXP properties are set through other means.
Using System Properties
System properties may be useful if you can’t modify your application’s code.
To set JAXP properties for an entire JDK invocation, set their corresponding System properties on the command line.
To set JAXP properties for only a portion of the application, set their corresponding System properties before the portion, and then clear them afterward. For example, if your application requires access to external DTDs and schemas, then add these lines to your application’s initialization code block:
System.setProperty("javax.xml.accessExternalDTD", "file, http");
System.setProperty("javax.xml.accessExternalSchema", "file, http");
Then, once your application is done processing XML documents or before it exits, clear out the properties as follows:
System.clearProperty("javax.xml.accessExternalDTD");
System.clearProperty("javax.xml.accessExternalSchema");
The following code, from Processing Limit Samples in The Java Tutorials, is another example that shows how to do this for the processing limit maxGeneralEntitySizeLimit:
public static final String SP_GENERAL_ENTITY_SIZE_LIMIT =
"jdk.xml.maxGeneralEntitySizeLimit";
// Set limits using System property;
// this setting will affect all processing after it's set
System.setProperty(SP_GENERAL_ENTITY_SIZE_LIMIT, "2000");
// Perform some processing here
// After it is done, clear the property
System.clearProperty(SP_GENERAL_ENTITY_SIZE_LIMIT);
Note that processing limit values are integers. A NumberFormatException is thrown if a processing limit’s value is not a parsable integer; see the method java.lang.Integer.parseInt(String).
The following example allows the resolution of external schemas for a portion of an application:
// Allow resolution of external schemas
// This setting will affect all processing after it's set
System.setProperty("javax.xml.accessExternalSchema", "file, http");
// Perform some processing here
// After it's done, clear the property
System.clearProperty("javax.xml.accessExternalSchema");
Using the jaxp.properties File
If you want to specify a JAXP property that affects every JDK invocation, then create a configuration file named <java-home>/conf/jaxp.properties and specify names and values of JAXP properties in it, one name-value pair on each line. For example, the following jaxp.properties file sets the maxGeneralEntitySizeLimit processing limit property to 2000 and restricts access to the file and HTTP protocols for external references set by the stylesheet processing instruction, document function, and the import and include elements.
jdk.xml.maxGeneralEntitySizeLimit=2000
javax.xml.accessExternalStylesheet=file, http
If you don’t want to allow any external connection by XML processors, you can set all access external restrictions to file only:
javax.xml.accessExternalDTD=file
javax.xml.accessExternalSchema=file
javax.xml.accessExternalStylesheet=file
If you want to prevent applications from accidentally reading external files through an XML processor, set the external access restrictions as follows in the jaxp.properties file as follows:
javax.xml.accessExternalDTD=""
javax.xml.accessExternalSchema=""
javax.xml.accessExternalStylesheet=""
Note:
- Use the corresponding System property in the jaxp.properties file. Processing limit System properties have the prefix jdk.xml. External access restriction System properties have the prefix javax.xml.
- Processing limit values are integers. A NumberFormatException is thrown if a processing limit’s value is not a parsable integer; see the method java.lang.Integer.parseInt(String).
Handling Errors from JAXP Properties
It is recommended that applications catch org.xml.sax.SAXNotRecognizedException when setting JAXP properties so that the applications will work properly on older releases that don’t support them.
For example, the following method, isNewPropertySupported, from Processing Limit Samples in The Java Tutorials, detects if the sample is run with a version of the JDK that supports the JDK_GENERAL_ENTITY_SIZE_LIMIT property:
public boolean isNewPropertySupported() {
try {
SAXParser parser = getSAXParser(false, false, false);
parser.setProperty(JDK_GENERAL_ENTITY_SIZE_LIMIT, "10000");
} catch (ParserConfigurationException ex) {
fail(ex.getMessage());
} catch (SAXException ex) {
String err = ex.getMessage();
if (err.indexOf("Property '" + JDK_GENERAL_ENTITY_SIZE_LIMIT +
"' is not recognized.") > -1) {
// expected before this patch
debugPrint("New limit properties not supported. Samples not run.");
return false;
}
}
return true;
}
When input files contain constructs that cause an over-the-limit exception, applications may check the error code to determine the nature of the failure. The following error codes are defined for processing limits:
- EntityExpansionLimit: JAXP00010001
- ElementAttributeLimit: JAXP00010002
- MaxEntitySizeLimit: JAXP00010003
- TotalEntitySizeLimit: JAXP00010004
- MaxXMLNameLimit: JAXP00010005
- maxElementDepth: JAXP00010006
- EntityReplacementLimit: JAXP00010007
The error code has the following format:
"JAXP" + components (two digits) + error category (two digits) + sequence number
The code JAXP00010001, therefore, represents the JAXP base parser security limit EntityExpansionLimit.
If access to external resources is denied due to the restrictions set by external access restrictions, then an exception will be thrown with an error in the following format:
[type of construct]: Failed to read [type of construct]
"[name of the external resource]", because "[type of restriction]"
access is not allowed due to restriction set by the
[property name] property.
For example, suppose the following:
The ACCESS_EXTERNAL_DTD JAXP property is set as follows:
parser.setProperty( "http://javax.xml.XMLConstants/property/accessExternalDTD", "file");
Your application tries to fetch an external DTD with the HTTP protocol.
The parser parsed an XML file that contains an external reference to http://www.example.com/dtd/properties.dtd.
The error message would look like the following:
External DTD: Failed to read external DTD
"http://www.example.com/dtd/properties.dtd", because "http"
access is not allowed due to restriction set by the
accessExternalDTD property.
Streaming API for XML and JAXP Properties
Streaming API for XML (StAX), JSR 173, does not support FSP nor does it support external access restrictions. However, JDK’s StAX implementation supports processing limits, and StAX in the context of JAXP supports external access restrictions.
StAX and Processing Limits
JDK’s StAX implementation supports processing limits and their corresponding System properties. However, because FSP is not supported, you can’t turn on or off processing limits for StAX by turning on or off FSP. Processing limits continue to behave as described in JAXP Properties for Processing Limits.
StAX and External Access Restrictions
JDK’s StAX implementation supports the JAXP properties related to external access restrictions. Setting them is similar to SAX or DOM, but through the XMLInputFactory class, for example:
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(
"http://javax.xml.XMLConstants/property/accessExternalDTD",
"file");
For compatibility, StAX properties and features take precedence over the processing limit and external access restriction properties. For example, the SupportDTD property, when set to false, causes a program to throw an exception when an input file contains a DTD before it can be parsed. Therefore, processing limits and external access restrictions on DTDs will have no effect on applications that have disabled by setting SupportDTD property to false.
Extension Functions
Because Feature for Secure Processing (FSP) is off by default for Transformer and XPath, extension functions are allowed. For applications processing documents from untrusted sources, it is recommended to turn off the extension functions feature. There are two ways to do so:
By setting FSP to true, for example:
TransformerFactory tf = TransformerFactory.newInstance(); tf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
By setting the enableExtensionFunctions property to false:
final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions"; // ... TransformerFactory tf = TransformerFactory.newInstance(); tf.setFeature(ENABLE_EXTENSION_FUNCTIONS, false);
In cases where extension functions are disabled as a result of installing a Java Security Manager, applications may also choose to re-enable the extension functions feature by setting the property enableExtensionFunctions to true. The following table defines this property:
Table 13-15 enableExtensionFunctions
Attribute
Description
Name
http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions
Definition
Determines whether XSLT and XPath extension functions are allowed.
Value
A boolean. True indicates that extension functions are allowed; False otherwise.
Default value
true
System property
jdk.xml.enableExtensionFunctions
Since
7u60
Disabling DTD Processing
If your applications don’t require DTDs, then consider disabling DTD processing to safeguard against many common DTD-related attacks, including denial-of-service, XML external entity (XXE), and server-side request forgery (SSRF).
Disabling DTD Processing for SAX and DOM Parsers
To disable DTD processing for SAX and DOM parsers, set the feature http://apache.org/xml/features/disallow-doctype-decl to true through a factory. The following code snippet disables DTDs for SAX parsers. A fatal error is thrown if the incoming XML document contains a DOCTYPE declaration.
final static String DISALLOW_DTD =
"http://apache.org/xml/features/disallow-doctype-decl";
// ...
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature(DISALLOW_DTD, true);
Disabling DTD processing for StAX Parsers
To disable DTD processing for StAX parsers, set the property SupportDTD with the the XMLInputFactory.setProperty method:
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
Using Resolvers and Catalogs
You can register custom resolvers and catalogs on a JDK XML processor to intercept any references to external resources and resolve them with local ones. This feature eliminates the need to read and access external resources, thus helping to remove a source of potential risk.
Java XML Resolvers
The Java XML API supports various resolvers that you can register on JDK XML processors to resolve external resources. These resolvers includes entity resolvers for SAX and DOM parsers, XML resolvers for StAX parsers, LSResourceResolver for validation, and URIResolver for transformation.
Entity Resolvers for SAX and DOM
SAX defines an interface that DOM also supports, org.xml.sax.EntityResolver. It enables applications to step into the entity resolution process and perform entity resolution on their own terms. The following is the interface’s definition:
package org.xml.sax;
public interface EntityResolver {
public InputSource resolveEntity(String publicID, String systemID)
throws SAXException;
}
You can then register an implementation of the interface on a SAX driver:
EntityResolver resolver = ...;
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(resolver);
Alternatively, you can register it on a DOM builder:
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
docBuilder.setEntityResolver(resolver);
XMLResolver for StAX
StAX defines a javax.xml.stream.XMLResolver interface:
package javax.xml.stream;
public interface XMLResolver {
public Object resolveEntity(
String publicID, String systemID,
String baseURI, String namespace)
throws XMLStreamException;
}
You can register it on a StAX factory:
XMLResolver resolver = ...;
XMLInputFactory xif = XMLInputFactory.newInstance();
xif.setProperty(XMLInputFactory.RESOLVER, resolver);
URIResolver for javax.xml.transform
The javax.xml.transform API supports custom resolution of external resources through the URIResolver interface:
package javax.xml.transform;
public interface URIResolver {
public Source resolve(String href, String base)
throws TransformerException;
}
You can register an implementation of URIResolver on a Transformer as follows:
URIResolver resolver = ...;
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t =
tf.newTransformer(new StreamSource(
new StringReader("xsl source")));
t.setURIResolver(resolver);
LSResourceResolver for javax.xml.validation
The javax.xml.validation API supports Document Object Model Level 3 Load and Save (DOM LS) DOM through the LSResourceResolver interface:
package org.w3c.dom.ls;
public interface LSResourceResolver {
public LSInput resolveResource(
String type, String namespaceURI, String publicId,
String systemId, String baseURI);
}
You can register an implementation of LSResourceResolver on a SchemaFactory as follows:
SchemaFactory schemaFactory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
LSResourceResolver resolver = ...;
schemaFactory.setResourceResolver(resolver);
The Catalog API
The XML Catalog API supports the Organization for the Advancement of Structured Information Standards (OASIS) XML Catalogs, OASIS Standard V1.1. This API is fully implemented by the JDK XML processors and easy to use. See XML Catalog API in Java Platform, Standard Edition Core Libraries.
Use the XML Catalog API to resolve external resources with the CatalogResolver interface and to enable catalogs on JDK XML processors.
Catalog Resolver
You can use a CatalogResolver as a custom resolver that substitutes external references with local resources configured as Catalog objects. You can register a CatalogResolver on factories or processors in place of EntityResolver, XMLResolver, URIResolver or LSResourceResolver as described in Java XML Resolvers. In the following code snippet, a CatalogResolver is registered as an EntityResolver on a SAXParserFactory:
URI catalogUri = URI.create("file:///users/auser/catalog/catalog.xml")
CatalogResolver cr =
CatalogManager.catalogResolver(CatalogFeatures.defaults(), catalogUri);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader reader = factory.newSAXParser().getXMLReader();
reader.setEntityResolver(cr);
Enable Catalogs on JDK XML Processors
The JDK XML processors implement the Catalog API as a native function. Therefore, there is no need to instantiate a CatalogResolver outside the processors. All you need to do is register the catalog files on the XML processors through the setProperty or setAttribute methods, through System properties, or in the jaxp.properties file. The XML processors then perform the mappings through the catalogs automatically. The following code snippet demonstrates how to register catalogs on StAX parsers through XMLInputFactory:
String catalog = "file:///users/auser/catalog/catalog.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(CatalogFeatures.Feature.FILES.getPropertyName(), catalog);
For more examples, see XML Catalog API in Java Platform, Standard Edition Core Libraries.
Third-Party Parsers
The JDK will always use its system-default parser even when there’s a third-party parser on the classpath. To override the JDK system-default parser, set the jdk.xml.overrideDefaultParser property to true.
Table 13-16 overrideDefaultParser
Attribute
Description
Name
jdk.xml.overrideDefaultParser
Definition
Enables the use of a third-party’s parser implementation to override the system-default parser for the JDK’s Transformer, Validator, and XPath implementations. The property can be set through JAXP factories, System properties, or the jaxp.properties file.
Value
A boolean. Setting it to true enables third-party parser implementations to override the system-default implementation during XML transformation, XML validation, or XPath operations. Setting it to false disables the use of third-party parser implementations. When the value is specified as a String, the returning value will be that of Boolean.parseBoolean.
Default value
false
System property
jdk.xml.overrideDefaultParser
Since
6u181, 7u171, 8u161, 9.0.4
The following code snippets instruct the factories to use a third-party parser, if found on the classpath, by setting the jdk.xml.overrideDefaultParser property with the setFeature method:
static final String JDK_OVERRIDE_PARSER = "jdk.xml.overrideDefaultParser";
...
TransformerFactory tFactory = TransformerFactory.newInstance();
tFactory.setFeature(JDK_OVERRIDE_PARSER, true);
...
XPathFactory xf = XPathFactory.newInstance();
xf.setFeature(JDK_OVERRIDE_PARSER, true);
...
SchemaFactory schemaFactory =
SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
schemaFactory.setFeature(JDK_OVERRIDE_PARSER, true);
...
Schema schema = schemaFactory.newSchema(new File("mySchema.xsd"));
Validator validator = schema.newValidator();
validator.setFeature(JDK_OVERRIDE_PARSER, true);
The following code snippet sets jdk.xml.overrideDefaultParser as a System property:
System.setProperty("jdk.xml.overrideDefaultParser", "true"));
You can add the following line to the jaxp.properties file to enable third-party parsers:
jdk.xml.overrideDefaultParser=true
General Recommendations for JAXP Security
The following are general recommendations for configuring JAXP properties and features to help secure your applications and systems:
- Turn on Feature for Secure Processing (FSP), then adjust individual features and properties in accordance with your specific requirements.
- For processing limits, adjust them so that they are just large enough to accommodate the maximum amount your applications require.
- For external access restrictions, reduce or eliminate your applications’ reliance on external resources, including the use of resolvers, then tighten these restrictions.
- Set up a local catalog and enable the Catalog API on all XML processors to further reduce your applications’ reliance on external resources.
Appendix A: Glossary of Java API for XML Processing Terms and Definitions
Table 13-17 JAXP Glossary
Term
Definition
JAXP
Java API for XML Processing
Java SE XML API
APIs defined in the JAXP JSR and integrated into Java SE
Java XML API
Equivalent term for Java SE XML API
Java XML Features and Properties
XML-related features and properties defined by the Java SE specification
java.xml
The java.xml module
JDK XML
The JDK implementation of the Java XML API
JDK XML Parsers
The JDK implementation of the XML parsers
JDK XML Properties
The JDK Implementation-only properties
FSP
FEATURE_SECURE_PROCESSING
Appendix B: Java and JDK XML Features and Properties Naming Convention
Java and JDK XML features and properties are defined in the javax.xml.XMLConstants class. The features have a prefix http://javax.xml.XMLConstants/feature; the properties, http://javax.xml.XMLConstants/property. If there is a corresponding System property, its prefix is javax.xml.
The JDK XML properties are JDK implementation-only properties. The prefix of the properties is http://www.oracle.com for JDK 8 and earlier and jdk.xml for JDK 9 and later. The following table summarizes this naming convention:
Table 13-18 Java and JDK XML Features and Properties Naming Convention
Scope
API Property Prefix
System Property Prefix
Java SE and JDK Version
Java SE
http://javax.xml.XMLConstants/feature
http://javax.xml.XMLConstants/property
javax.xml
Since 1.4
JDK
http://www.oracle.com/xml/jaxp/properties
jdk.xml
Since 7
JDK
jdk.xml
jdk.xml
Since 9
Related news
Red Hat Security Advisory 2024-1027-03 - An update is now available for MTA-6.2-RHEL-8 and MTA-6.2-RHEL-9. Issues addressed include XML injection and denial of service vulnerabilities.
Red Hat Security Advisory 2024-0720-03 - Migration Toolkit for Runtimes 1.2.4 release. Issues addressed include an XML injection vulnerability.
Red Hat Integration Camel for Spring Boot 4.0.0 release and security update is now available. Red Hat Product Security has rated this update as having an impact of Moderate. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.This content is licensed under the Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). If you distribute this content, or a modified version of it, you must provide attribution to Red Hat Inc. and provide a link to the original. Related CVEs: * CVE-2022-44729: A flaw was found in Apache Batik 1.0 - 1.16. This issue occurs due to a malicious SVG triggering external resources loading by default, causing resource consumption or in some cases information disclosure. * CVE-2022-44730: A flaw was found in Apache Batik, where a malicious SVG can probe user profile data and send it directly as ...
A cross-site request forgery (CSRF) vulnerability in Jenkins Ivy Plugin 2.5 and earlier allows attackers to delete disabled modules.
Jenkins AWS CodeCommit Trigger Plugin 3.0.12 and earlier does not perform a permission check in an HTTP endpoint, allowing attackers with Overall/Read permission to clear the SQS queue.
A missing permission check in Jenkins AWS CodeCommit Trigger Plugin 3.0.12 and earlier allows attackers with Overall/Read permission to enumerate credentials IDs of AWS credentials stored in Jenkins.
Jenkins TAP Plugin 2.3 and earlier does not escape TAP file contents, resulting in a stored cross-site scripting (XSS) vulnerability exploitable by attackers able to control TAP file contents.
Jenkins SSH2 Easy Plugin 1.4 and earlier does not verify that permissions configured to be granted are enabled, potentially allowing users formerly granted (typically optional permissions, like Overall/Manage) to access functionality they're no longer entitled to.
Jenkins AWS CodeCommit Trigger Plugin 3.0.12 and earlier does not escape the queue name parameter passed to a form validation URL, when rendering an error message, resulting in an HTML injection vulnerability.
Jenkins Bitbucket Push and Pull Request Plugin 2.4.0 through 2.8.3 (both inclusive) trusts values provided in the webhook payload, including certain URLs, and uses configured Bitbucket credentials to connect to those URLs, allowing attackers to capture Bitbucket credentials stored in Jenkins by sending a crafted webhook payload.
Jenkins Google Login Plugin 1.7 and earlier uses a non-constant time comparison function when checking whether the provided and expected token are equal, potentially allowing attackers to use statistical methods to obtain a valid token.
Jenkins Azure AD Plugin 396.v86ce29279947 and earlier, except 378.380.v545b_1154b_3fb_, uses a non-constant time comparison function when checking whether the provided and expected CSRF protection nonce are equal, potentially allowing attackers to use statistical methods to obtain a valid nonce.
Jenkins Pipeline Maven Integration Plugin 1330.v18e473854496 and earlier does not properly mask (i.e., replace with asterisks) usernames of credentials specified in custom Maven settings in Pipeline build logs if "Treat username as secret" is checked.
Jenkins Assembla Auth Plugin 1.14 and earlier does not verify that the permissions it grants are enabled, resulting in users with EDIT permissions to be granted Overall/Manage and Overall/SystemRead permissions, even if those permissions are disabled and should not be granted.
A missing permission check in Jenkins Frugal Testing Plugin 1.1 and earlier allows attackers with Overall/Read permission to connect to Frugal Testing using attacker-specified credentials.
Improper Restriction of XML External Entity Reference, XML Injection (aka Blind XPath Injection) vulnerability in Apache Software Foundation Apache Ivy.This issue affects any version of Apache Ivy prior to 2.5.2. When Apache Ivy prior to 2.5.2 parses XML files - either its own configuration, Ivy files or Apache Maven POMs - it will allow downloading external document type definitions and expand any entity references contained therein when used. This can be used to exfiltrate data, access resources only the machine running Ivy has access to or disturb the execution of Ivy in different ways. Starting with Ivy 2.5.2 DTD processing is disabled by default except when parsing Maven POMs where the default is to allow DTD processing but only to include a DTD snippet shipping with Ivy that is needed to deal with existing Maven POMs that are not valid XML files but are nevertheless accepted by Maven. Access can be be made more lenient via newly introduced system properties where needed. User...