From 20dcb4f4f7f5f4af382ec06ee37b15a41a94c720 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Fri, 6 Jun 2025 15:06:29 +0200 Subject: [PATCH] added DCL pattern implementation for TransformerUtil Closes #40030 Signed-off-by: Anchels Signed-off-by: Alexander Schwartz Co-authored-by: Anchels <42744001+Anchels@users.noreply.github.com> --- .../saml/common/util/TransformerUtil.java | 59 ++++++++++--------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/TransformerUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/TransformerUtil.java index b0d61d8491c..1e7a85ca8d0 100755 --- a/saml-core/src/main/java/org/keycloak/saml/common/util/TransformerUtil.java +++ b/saml-core/src/main/java/org/keycloak/saml/common/util/TransformerUtil.java @@ -37,7 +37,6 @@ import javax.xml.stream.XMLEventReader; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.Comment; -import javax.xml.stream.events.EndElement; import javax.xml.stream.events.Namespace; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; @@ -67,7 +66,7 @@ public class TransformerUtil { private static final PicketLinkLogger logger = PicketLinkLoggerFactory.getLogger(); - private static TransformerFactory transformerFactory; + private static volatile TransformerFactory transformerFactory; /** * Get the Default Transformer @@ -102,32 +101,38 @@ public class TransformerUtil { */ public static TransformerFactory getTransformerFactory() throws TransformerFactoryConfigurationError { if (transformerFactory == null) { - boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false") - .equalsIgnoreCase("true"); - ClassLoader prevTCCL = SecurityActions.getTCCL(); - try { - if (tccl_jaxp) { - SecurityActions.setTCCL(TransformerUtil.class.getClassLoader()); - } - transformerFactory = TransformerFactory.newInstance(); - try { - transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - } catch (TransformerConfigurationException ignored) { - // some platforms don't support this. For example our testsuite pulls Selenium which requires Xalan 2.7.1 - logger.warn("XML External Entity switches are not supported. You may get XML injection vulnerabilities."); - } - try { - transformerFactory.setAttribute(FixXMLConstants.ACCESS_EXTERNAL_DTD, ""); + synchronized (TransformerUtil.class) { + if (transformerFactory == null) { + boolean tccl_jaxp = SystemPropertiesUtil.getSystemProperty(GeneralConstants.TCCL_JAXP, "false") + .equalsIgnoreCase("true"); + ClassLoader prevTCCL = SecurityActions.getTCCL(); + TransformerFactory localTransformerFactory; + try { + if (tccl_jaxp) { + SecurityActions.setTCCL(TransformerUtil.class.getClassLoader()); + } + localTransformerFactory = TransformerFactory.newInstance(); + try { + localTransformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + } catch (TransformerConfigurationException ignored) { + // some platforms don't support this. For example our testsuite pulls Selenium which requires Xalan 2.7.1 + logger.warn("XML External Entity switches are not supported. You may get XML injection vulnerabilities."); + } + try { + localTransformerFactory.setAttribute(FixXMLConstants.ACCESS_EXTERNAL_DTD, ""); - transformerFactory.setAttribute(FixXMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); - } catch (Exception ignored) { - // some platforms don't support this. For example our testsuite pulls Selenium which requires Xalan 2.7.1 - logger.warn("XML External Entity switches are not supported. You may get XML injection vulnerabilities."); - } + localTransformerFactory.setAttribute(FixXMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); + } catch (Exception ignored) { + // some platforms don't support this. For example our testsuite pulls Selenium which requires Xalan 2.7.1 + logger.warn("XML External Entity switches are not supported. You may get XML injection vulnerabilities."); + } - } finally { - if (tccl_jaxp) { - SecurityActions.setTCCL(prevTCCL); + } finally { + if (tccl_jaxp) { + SecurityActions.setTCCL(prevTCCL); + } + } + transformerFactory = localTransformerFactory; } } } @@ -447,4 +452,4 @@ public class TransformerUtil { } } } -} \ No newline at end of file +}