Project

Profile

Help

Support #4234

Security assessment of SaxonEE 9.9

Added by Bhupender Rathee 3 months ago. Updated about 1 month ago.

Status:
New
Priority:
High
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2019-06-14
Due date:
% Done:

0%

Legacy ID:
Applies to branch:
9.9, trunk
Fix Committed on Branch:
9.9
Fixed in Maintenance Release:

Description

Hello Team,

We are using commercial Saxon library (Saxon-EE version 9.9). We are directly getting the instances of “EnterpriseTransformerFactory”, “SchemaFactoryImpl” and “SchemaValidator”. As part of security practices to prevent attacks (like DTD attack, XML Schema attacks, XPath injection etc) there are quite a few properties we need to set to some or many of these classes.

Our question is, does Saxonica internally set these properties? For example to prevent DTD attacks we set TransformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); Does these settings already considered in your APIs? Or consumers have to manage themselves? If Yes, can we get some report or info from the website of default settings?

Thanks Bhupender

History

#1 Updated by Michael Kay 3 months ago

Many of these properties relate to the XML parser rather than to the XSLT processor. Saxon runs with a variety of XML parsers, and selecting an XML parser and configuring it is in general a user responsibility. Generally speaking, we do not change the parser configuration properties from their defaults. (There are a few exceptions, for example if you set -xi on the command line then we enable XInclude processing, and if you use -catalog on the command line then we set an EntityResolver).

At the XSLT level, access to external resources (using functions such as doc() and unparsed-text()) is enabled by default, as is access to Java extension functions. We take the view that XSLT is a programming language, and programming languages need access to external resources. You can constrain this access (typically by using callbacks such as a URIResolver, an UnparsedTextResolver, a CollectionResolver, an OutputURIResolver, and so on) but this is a user responsibility.

Do be aware that because XSLT is a Turing-complete programming language, it is not possible to prevent untrusted stylesheet code from consuming unbounded CPU resources or memory. However, if you do choose to run untrusted XSLT code, we recommend setting the configuration property ALLOW_EXTERNAL_FUNCTIONS to false, as well as using appropriate xxResolver callbacks to limit access to filestore resources.

#2 Updated by Michael Kay 3 months ago

  • Tracker changed from Bug to Support

#3 Updated by Bhupender Rathee 3 months ago

Hi Michael,

Thanks for quick reply.

I have done the velow changes will it help; For EnterpriseTransformerFactory instance EnterpriseTransformerFactory enterpriseTransformerFactory = new EnterpriseTransformerFactory( getNewEnterpriseConfigurationInstance()); enterpriseTransformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); enterpriseTransformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

Will above mentioned attribute prevent XXE attacks?

For SchemaFactoryImpl instance SchemaFactoryImpl schemaFactoryImpl = new SchemaFactoryImpl(getNewEnterpriseConfigurationInstance()); schemaFactoryImpl.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); schemaFactoryImpl.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

Will above mentioned Properties prevent XXE attacks?

For SchemaValidator instance EnterpriseConfiguration enterpriseConfiguration = new EnterpriseConfiguration(); Processor saxonProcessor = new Processor(enterpriseConfiguration ); SchemaManager schemaMgr = saxonProcessor.getSchemaManager(); SchemaValidator newSchemaValidator = schemaMgr.newSchemaValidator();

How and which property or Attribute should i add to SchemaValidator?

Really appreciate youe support here

Thansk Bhupender

#4 Updated by Michael Kay 3 months ago

The property/attribute names that you can pass to Saxon's implementation of TransformerFactory are in general those listed as constants in the class net.sf.saxon.lib.FeatureKeys and documented at http://www.saxonica.com/documentation/index.html#!configuration/config-features

The Javadoc spec for the TransformerFactory interface say that

(a) setFeature() must recognise XMLConstants.FEATURE_SECURE_PROCESSING -- however the detailed effects of setting this option are stated to depend on the implementation. We comply with this requirement, interpreting it in a way that is appropriate for Saxon.

(b) if the implementation supports JAXP 1.5 or later, then setAttribute() is "required to support the XMLConstants.ACCESS_EXTERNAL_DTD and XMLConstants.ACCESS_EXTERNAL_STYLESHEET properties."

Saxon only claims to support JAXP 1.3, and we have difficulty supporting later versions completely because the terminology of JAXP is still focussed around XSLT 1.0 concepts: though that perhaps isn't entirely relevant here. However, we have difficulty with this particular provision because it's not at all clear what "supporting" these constants is supposed to entail. These constants relate to the behaviour of the XML parser, not the XSLT processor, and we have only limited control over the behaviour of the XML parser. We make a policy decision that when a SAXSource is supplied to provide the input, and the SAXSource contains an XMLReader, then we should not tamper with the configuration properties of that XMLReader as supplied. I think that decision is correct.

However, when input is provided in the form of a StreamSource, and we instantiate the XMLReader ourselves from within Saxon, then we should arguably take account of these properties supplied to the TransformerFactory by setting corresponding properties on the XMLReader that we instantiate. I will look at making that change.

The situation with SchemaFactory is very similar.

I personally have considerable doubts about the effectiveness of these properties; I think they give a false sense of security. For example, setting these properties might prevent an XXE attack (external entity expansion), but it cannot do what the SchemaFactory claims for FEATURE_SECURE_PROCESSING, namely to prevent use of "XML Schema constructs that would consume large amounts of resources". The easiest way to write a schema that consumes large amounts of resource is with a pattern facet whose evaluation requires significant back-tracking, and I don't believe that any implementations protect against that risk. XSD 1.1 is a lot more powerful than 1.0, and I think the suggestion that if you set the right properties then it becomes safe to validate against an untrusted schema is unwise and perhaps irresponsible.

#5 Updated by Bhupender Rathee about 2 months ago

Hi Michael,

Thanks for your support.

We would like to set below two properties of our validator object:- validator.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); validator.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");

We got validator object through below lines of code:- EnterpriseConfiguration config = SaxonicaFactory.getNewEnterpriseConfigurationInstance(); Processor saxonProcessor = new Processor(config);
SchemaManager schemaMgr = saxonProcessor.getSchemaManager(); SchemaValidator newSchemaValidator = schemaMgr.newSchemaValidator();

Can you please help us to know how we can set above mentioned properties to our object?

Also we came accross configuration file https://www.saxonica.com/documentation9.5/configuration/configuration-file/ Is this files already set in saxon-EE?

Thanks Bhupender

#6 Updated by Michael Kay about 2 months ago

Sorry for the delay in responding.

First, JAXP interfaces.

I propose to patch 9.9 and the development branch so that Saxon's implementation of the JAXP Validator recognises the three properties

  • XMLConstants#FEATURE_SECURE_PROCESSING
  • XMLConstants#ACCESS_EXTERNAL_DTD
  • XMLConstants#ACCESS_EXTERNAL_SCHEMA

The first two are passed directly to the code that instantiates the XML parser. The third property needs to be handled by Saxon itself, since it is Saxon that is fetching the external schema. Implementation and testing of this feature is non-trivial so this work will have to be scheduled.

Secondly, s9api interfaces.

I think the right thing to do here is to implement a global configuration option (at the Processor/Configuration level) that restricts the protocols used by all the external resource resolvers, including URIResolver, EntityResolver, SchemaURIResolver, UnparsedTextResolver, etc. The standard resolvers will all enforce these global constraints; user-written resolvers will have the option to bypass the constraints if they wish.

In the meantime, you can:

(a) for the first two properties, instantiate the XMLReader yourself and set its properties directly, then supply a SAXSource to Saxon in which the XMLReader is already initialized

(b) for the ACCESS_EXTERNAL_SCHEMA property, define an LSResourceResolver (using Validator.setResourceResolver()) that implements the required constraints.

Your original question was about XXE and I would reiterate that if you are using an XSD schema, you need to trust it; there are many more ways a DOS attacker can hit you with an untrusted schema that have nothing to do with XXE or external resources. A lot of the talk found on the internet about XXE is grossly simplistic.

#7 Updated by Bhupender Rathee about 1 month ago

Hi Michael,

Thanks for response. Can you please answer for below questions 1) As there is no direct way to set value of these three properties. Can you please tell what is the default value set for these XMLConstants#FEATURE_SECURE_PROCESSING XMLConstants#ACCESS_EXTERNAL_DTD XMLConstants#ACCESS_EXTERNAL_SCHEMA 2) As you have mentioned about you can provide a patch to 9.9. Can you please provide us time line when can we expect the patch? 3) Can you please provide us sample code for the work around you have sugguested for these properties. (a) for the first two properties, instantiate the XMLReader yourself and set its properties directly, then supply a SAXSource to Saxon in which the XMLReader is already initialized (b) for the ACCESS_EXTERNAL_SCHEMA property, define an LSResourceResolver (using Validator.setResourceResolver()) that implements the required constraints. I am facing difficulty to set these properties in configue object.

Thanks Bhupender

#8 Updated by Michael Kay about 1 month ago

(1) There isn't a simple default (and there never will be).

(1a) The handling of an external DTD (and other external entities) depends entirely on the XML parser. The choice of XML parser and the way it is configured are under user control. You can supply an explicit parser (XMLReader) as part of a SAXSource supplied to the validate() method, or you can nominate a parser for Saxon to use as a Saxon configuration property. While the JAXP interface for Validator requires the ACCESS_EXTERNAL_DTD property to be supported, there is no requirement for an implementation of XMLReader to support the underlying functionality, except indirectly by creating your own EntityResolver. If you don't take action to create your own EntityResolver, then Saxon does whatever the chosen XML parser does, which in the case of commonly-used parsers is to allow any URI to be used. Note also that entity references can use a public identifier rather than a system identifier, and in this case the documentation of ACCESS_EXTERNAL_DTD seems to have nothing to say about how they are dereferenced.

(1b) The handling of references to schema documents depends on the supplied ResourceResolver. Saxon's default resource resolver imposes no restrictions.

(2) We never promise dates for deliverables, we prefer to be quality-driven rather than date-driven. But maintenance releases are usually shipped every 6-8 weeks.

(3) I would have to do some research, and it almost certainly depends on which XML parser you are using. For example, the most commonly used parser is Apache Xerces, and while the JAXP interface specification says that a Validator supporting JAXP 1.5 or later must support the ACCESS_EXTERNAL_DTD property, I can't find anything in the Apache Xerces documentation that says whether or not it does so. I think your best bet is probably to set an EntityResolver something like this:

XMLReader reader = ... create an XMLReader ...;
reader.setEntityResolver(new EntityResolver {
   public InputSource resolveEntity (String publicId, String systemId)
   {
     if !(systemId.startsWith("file:") {
        throw new SAXException("URI scheme not allowed");
     } else {
              // use the default behaviour
       return null;
     }
   }
 }
SAXSource source = new SAXSource(reader, new InputSource(new File(...)));
validator.validate(source);

For the ResourceResolver you would similarly do

validator.setResourceResolver(new LSResourceResolver() {
   public LSInput resolveResource(String type,
                                   String namespaceURI,
                                   String publicId,
                                   String systemId,
                                   String baseURI) {
     if (systemId.startsWith(.....) {
       throw new Exception();
     } else {
       return null;
     }
 } ;


#9 Updated by Michael Kay about 1 month ago

  • Applies to branch 9.9, trunk added
  • Fix Committed on Branch 9.9 added

I have committed the first phase of changes for 9.9, recognizing the three JAXP-defined security properties in Saxon's implementation of the JAXP Validator interface.

Please register to edit this issue

Also available in: Atom PDF