Saxon 11.7 and 12.8

By Norm Tovey-Walsh on July 03, 2025 at 05:40p.m.

The accompanying release announcements for Saxon 11.7 and Saxon 12.8 describe those releases in detail. This post summarizes why we decided that we needed to release them both this week.

Some applications are known to use Saxon to run untrusted, user-submitted stylesheets or queries. Running untrusted code always entails some risk. Saxon provides two features designed to help mitigate this risk: ALLOWED_PROTOCOLS and ALLOW_EXTERNAL_FUNCTIONS. Setting ALLOWED_PROTOCOLS can limit what resources a stylesheet or query can access; it can for example, forbid access to file: URIs. The ALLOW_EXTERNAL_FUNCTIONS feature can disable access to reflexive Java extension functions, some system properties, and some other extension functions. (The remit of the ALLOW_EXTERNAL_FUNCTIONS feature is a little wider than you might expect.)

Unfortunately, we discovered a function in Saxon 11 and 12 that was not adequately controlled by these features. In principle, a stylesheet or query running in Saxon-PE or Saxon-EE could access the local filesystem even if the ALLOWED_PROTOCOLS feature was set to forbid such access. The risk is small: it only applies to untrusted code running in Saxon-PE or Saxon-EE (it does not apply to Saxon-HE) on a system where reading from the local filesystem would be deemed a risk. (We would encourage anyone running untrusted code to use a sandboxed environment where there is no data on the filesystem that needs to be protected from read access.)

Although we judge the risk to be small, At Saxonica, we take security seriously and we are publishing maintenance releases of Saxon 11 and Saxon 12 to close this gap. We urge anyone running untrusted stylesheets or queries under Saxon-PE or Saxon-EE to move to version 11.7 or 12.8 immediately.

This bug is present in the Java, C#, C, C++, Python and PHP products. It is not present in Saxon 10 (including the Saxon.NET 10) or in earlier releases. It is not present in SaxonJS.