XMLParserConfiguration
There are a number of settings that control how the IdP parses XML and are used to protect against a variety of attacks using malicious content. This is to some degree a constantly shifting landscape as novel attacks (or admittedly many that aren’t so novel) are identified and miitigated against. As such, these defaults and settings change over time, and on occasion it is necessary to actively intervene in the configuration if upgrades cannot be applied promptly.
Parsing Scenarios
At a high level it’s helpful to understand how XML is parsed in various cases and what degree of control is offered.
Configuration Files
This case provides us the least control, as Spring does not expose an actual API to fully control the parsing of XML configuration files. Rather, they have a variety of inconsistent, duplicative, and often incomplete control points for addressing how “entities” get resolved. We leverage these to prevent, for example, remote resolution of any content by Spring.
In other regards, the only controls possible are those that can be set globally to affect all parsing done by the JAXP API built into Java, which is implemented using a fork of the now-moribund (if not dead) Apache Xerces XML parser.
General XML Parsing
Most XML parsing done by our libraries is handled using an interface we created called ParserPool (reflecting the fact that we implementing pooling of parser objects for efficiency, as creating them is relatively expensive).
An instance of this interface is defined internally in a bean named shibboleth.DefaultParserPool. A number of settings, features, and attributes are defined on this bean to implement a number of secure processing defaults (which again change over time).
The principal purpose of this bean is to provide a secure parser for “untrusted” content such as SAML and SOAP messages.
SAML Metadata Parsing
Prior to V5.2.2, the General parser configuration is used to parse SAML Metadata. Due to the need for stricter defaults than we can safely apply right now to SAML metadata, we have now separated this use case out by defining an bean named shibboleth.MetadataParserPool for that specific case. It is mostly similar to the other bean except for a more relaxed limit on XML Attribute count.
Decrypted XML
A special case exists in the OpenSAML library when parsing decrypted XML.
Prior to V5.2.2, the General parser configuration was cloned and modified internally to OpenSAML with one additional feature flag for this use case. We have now updated this by defining a dedicated ParserPool instance with the necessary settings and independently controlled limits within the IdP.
Customization Features
Parser Definition Override
Prior to V5.2.2, the primary source of control was the ability to override the instance ParserPool used across most of the system, with the notable exception of configuration parsing.
To override the object used, applying whatever settings are desired, you must define an instance of this interface in conf/global.xml and then reference it via the idp.xml.parserPool property. Typically you would define a bean with parent set to shibboleth.DefaultParserPool to inherit most of the settings.
As an example, to retroactively define the Java 17+ JAXP settings added to the V5.2.2 parser configuration on an older version of the IdP, this bean defintion can be combined with setting the idp.xml.parserPool property to custom.ParserPool:
<bean id="custom.ParserPool" parent="shibboleth.DefaultParserPool">
<property name="builderAttributes">
<map>
<entry key="jdk.xml.elementAttributeLimit" value="30" />
<entry key="jdk.xml.maxElementDepth" value="25" />
</map>
</property>
</bean>Starting with V5.2.2, this will not override the behavior of SAML Metadata or decrypted XML parsing, and separate objects and properties are used for that purpose, as noted in the Reference section below.
Parser Limits
The main change in V5.2.2 is the explicit adoption of JAXP Attributes to constrain the parser’s acceptance of deeply nested XML or large numbers of XML namespace declarations. Java has gradually been applying default values for these Attributes but the defaults are still too high, so we have tightened the defaults, and defined our own properties to control their values in our ParserPool beans.
The properties controlling these for various parsing cases are noted in the Reference section below.
Neither the IdP nor OpenSAML set the underlying JAXP system properties (on most newer Java versions, they share the name of the builder Attributes above). The reason for this is that our “other” JAXP parsing scenario is essentially parsing local, trusted XML configurations with Spring, and some of the beans we define actually contain a significant number of XML Attributes. Since we cannot directly control the parser used by Spring, applying the system properties globally would affect this.
Of course you are free to set these system properties directly if desired by adjusting the startup command of your Java container.
Size Limiting
As an additional defense-in-depth measure, V5.2.2 also introduces the ability to directly limit the sizes of different kinds of messages parsed by the OpenSAML library on behalf of the IdP. We have not enabled these limits at this time as we believe the other adjustments are currently sufficient to protect the system, but these can be turned on by deployers or by us as a future default if it becomes necessary.
There are number of properties used, which are defined by OpenSAML but can be added to conf/idp.properties (or any other properties file) to override them. Refer to the Reference section for complete details.