This is an automated email from the ASF dual-hosted git repository. ppkarwasz pushed a commit to branch feat/use-commons-xml in repository https://gitbox.apache.org/repos/asf/commons-bsf.git
commit c2d880698f1dd7f0d11eee57853b8ae1901bcce4 Author: Piotr P. Karwasz <[email protected]> AuthorDate: Mon Aug 31 15:23:07 2026 +0200 Harden XSLT processing via commons-secure-xml Create the XSLT engine's transformer factory through org.apache.commons:commons-secure-xml. The secure factory enables FEATURE_SECURE_PROCESSING on every transformer it produces and bounds internal entity expansion, regardless of the JAXP implementation on the classpath. Changes: - Add the commons-secure-xml dependency (1.0.0-SNAPSHOT until its first release). - Route factory creation through SecureTransformerFactory in XSLTEngine. - Keep the documented "xslt:styleBaseURI" contract working: stylesheets may import, include and reference documents relative to the user-supplied base URI, so the engine installs a URI resolver that performs the standard resolution. Without it, the secure factory would resolve those lookups to empty content. - Run the CI and CodeQL builds with -Puse-apache-snapshots (inherited from the org.apache:apache parent POM) so the commons-secure-xml SNAPSHOT resolves; CodeQL's autobuild receives the profile through MAVEN_ARGS. Assisted-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MHgnMnGWHQoH2zD2jFdoMT --- .github/workflows/codeql-analysis.yml | 2 ++ .github/workflows/maven.yml | 2 +- pom.xml | 5 +++++ src/changes/changes.xml | 1 + .../org/apache/bsf/engines/xslt/XSLTEngine.java | 22 +++++++++++++++++++++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 38e6424..8874b24 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -70,6 +70,8 @@ jobs: # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@5595ccaf912efad79be6eef63a5619ff05969be3 # 4.37.6 + env: + MAVEN_ARGS: -Puse-apache-snapshots # âšī¸ Command-line programs to run using the OS shell. # đ https://git.io/JvXDl diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 77b2e88..b0b51bb 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -54,4 +54,4 @@ jobs: distribution: 'temurin' java-version: ${{ matrix.java }} - name: Build with Maven - run: mvn -V -Ddoclint=all --file pom.xml --no-transfer-progress -Ddoclint=none + run: mvn -V -Ddoclint=all --file pom.xml --no-transfer-progress -Ddoclint=none -Puse-apache-snapshots diff --git a/pom.xml b/pom.xml index 263832a..a46b75d 100644 --- a/pom.xml +++ b/pom.xml @@ -168,6 +168,11 @@ </plugins> </reporting> <dependencies> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-secure-xml</artifactId> + <version>1.0.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e871e0b..e1b546c 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -27,6 +27,7 @@ <body> <release version="2.5.0" date="YYY-MM-DD" description="TBD."> <!-- FIX --> + <action type="fix" dev="pkarwasz">Create XSLT transformer factories through org.apache.commons:commons-secure-xml, so transformations run with XML secure processing enabled.</action> <action type="fix" dev="ggregory" due-to="Gary Gregory">Replace internal StringBuffer with StringBuilder.</action> <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix malformed Javadoc comments.</action> <!-- ADD --> diff --git a/src/main/java/org/apache/bsf/engines/xslt/XSLTEngine.java b/src/main/java/org/apache/bsf/engines/xslt/XSLTEngine.java index cea4b45..2d12884 100644 --- a/src/main/java/org/apache/bsf/engines/xslt/XSLTEngine.java +++ b/src/main/java/org/apache/bsf/engines/xslt/XSLTEngine.java @@ -20,11 +20,15 @@ package org.apache.bsf.engines.xslt; import java.io.File; import java.io.Reader; import java.io.StringReader; +import java.net.MalformedURLException; import java.net.URL; import java.util.Vector; +import javax.xml.transform.Source; import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; +import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamSource; @@ -36,6 +40,7 @@ import org.apache.bsf.BSF_Log; import org.apache.bsf.BSF_LogFactory; import org.apache.bsf.util.BSFEngineImpl; import org.apache.bsf.util.BSFFunctions; +import org.apache.commons.xml.secure.SecureTransformerFactory; import org.apache.xpath.objects.XObject; import org.w3c.dom.Node; @@ -167,7 +172,22 @@ public class XSLTEngine extends BSFEngineImpl { public void initialize(final BSFManager mgr, final String lang, final Vector declaredBeans) throws BSFException { super.initialize(mgr, lang, declaredBeans); - tFactory = TransformerFactory.newInstance(); + tFactory = SecureTransformerFactory.newInstance(); + // The secure factory resolves URIs that no resolver handles to empty content; imported and + // referenced documents are part of the script here, so restore the default resolution for them. + tFactory.setURIResolver(new URIResolver() { + public Source resolve(final String href, final String base) throws TransformerException { + try { + URL baseUrl = new File("").toURI().toURL(); + if (base != null && !base.isEmpty()) { + baseUrl = new URL(baseUrl, base); + } + return new StreamSource(new URL(baseUrl, href).toExternalForm()); + } catch (final MalformedURLException e) { + throw new TransformerException(e); + } + } + }); } /**
