Federico Mariani created CAMEL-24108:
----------------------------------------
Summary: camel-xslt-saxon: secureProcessing=true (documented
default) is never applied unless saxonExtensionFunctions is configured;
transformerFactoryConfigurationStrategy silently ignored
Key: CAMEL-24108
URL: https://issues.apache.org/jira/browse/CAMEL-24108
Project: Camel
Issue Type: Bug
Components: camel-xslt
Affects Versions: 4.21.0
Reporter: Federico Mariani
h3. Problem 1: secureProcessing is a no-op in the default configuration
The only place {{XMLConstants.FEATURE_SECURE_PROCESSING}} is set on the Saxon
factory is inside {{XsltSaxonHelper.registerSaxonExtensionFunctions()}}:
{code:java}
public static void registerSaxonExtensionFunctions(TransformerFactoryImpl
factory,
List<Object> saxonExtensionFunctions, boolean secureProcessing) throws
Exception {
if (saxonExtensionFunctions != null && !saxonExtensionFunctions.isEmpty()) {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
secureProcessing);
...
{code}
When {{saxonExtensionFunctions}} is null/empty - the default - the feature is
*never set*, even though the {{secureProcessing}} option defaults to {{true}}
and its documentation says "This is enabled by default". It is backwards twice
over: the user who configures extension functions gets secure processing forced
on, while everyone else silently gets Saxon's insecure defaults.
Compounding it, {{XsltSaxonEndpoint.createXsltBuilder()}} instantiates {{new
TransformerFactoryImpl()}} directly, bypassing
{{XMLConverterHelper.createTransformerFactory()}} - which is where the plain
xslt component gets {{FEATURE_SECURE_PROCESSING=true}},
{{ACCESS_EXTERNAL_DTD=""}} and {{ACCESS_EXTERNAL_STYLESHEET=""}}. So xslt-saxon
ships with no external-access restrictions, and on Saxon-PE/EE classpaths
reflexive Java extension functions stay enabled despite
{{secureProcessing=true}}.
*Exposure, honestly assessed:* untrusted-input XXE is NOT open - message bodies
reach the transformer via Camel's hardened StAX/SAX converters
({{SUPPORT_DTD=false}}, external entities off; pinned by {{SaxonXsltDTDTest}}),
and the stylesheet is route-author trusted per the security model. The real
gaps: a documented security default that does nothing (insecure-default class),
stylesheet-driven external fetches unrestricted where plain {{xslt}} restricts
them, and Saxon-PE/EE Java extension calls not blocked.
h3. Problem 2: transformerFactoryConfigurationStrategy silently ignored
* On {{xslt-saxon}}: {{XsltSaxonEndpoint.createXsltBuilder()}} never references
the (inherited) {{transformerFactoryConfigurationStrategy}} option at all - it
is dead in every configuration, including the {{new TransformerFactoryImpl()}}
case where a configuration hook is most plausibly wanted.
* On plain {{xslt}}: {{XsltEndpoint.createXsltBuilder()}} only invokes the
strategy inside the {{if (trFactoryClass != null)}} block, so with the default
factory the option also does nothing - contradicting its doc "a configuration
strategy to apply on freshly created instances of TransformerFactory".
h3. Fix direction
Apply {{FEATURE_SECURE_PROCESSING}} (and external-access restrictions where
Saxon supports them) unconditionally from the option value in
{{createXsltBuilder()}}, independent of extension-function registration; honor
{{transformerFactoryConfigurationStrategy}} on both endpoints for every factory
the endpoint ends up using. Behavior change for Saxon-PE/EE users relying on
the accidental insecure default needs an upgrade-guide entry.
----
_This issue was researched and filed by Claude Code on behalf of [~fmariani]
(GitHub: Croway), as part of a code review of camel-xslt and camel-xslt-saxon._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)