This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch 3.6.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit dccc58167df9f2db1a186412ad6dec61fc7ff69e Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Tue Jun 2 13:50:24 2026 +0100 Harden JNDI for integration/jca (#3169) (cherry picked from commit 18978872d5bb80ebae3e3d65a0859d8549490408) (cherry picked from commit fb4557ac66fde79ca0c067994b84d3385e4a17a0) # Conflicts: # integration/jca/src/main/java/org/apache/cxf/jca/inbound/DispatchMDBMessageListenerImpl.java --- .../core/resourceadapter/JndiNameValidator.java | 34 +++++++++++++++ .../inbound/DispatchMDBMessageListenerImpl.java | 2 + .../org/apache/cxf/jca/servant/EJBEndpoint.java | 2 + .../resourceadapter/JndiNameValidatorTest.java | 48 ++++++++++++++++++++++ 4 files changed, 86 insertions(+) diff --git a/integration/jca/src/main/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidator.java b/integration/jca/src/main/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidator.java new file mode 100644 index 00000000000..ae9a6b7a14e --- /dev/null +++ b/integration/jca/src/main/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidator.java @@ -0,0 +1,34 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.jca.core.resourceadapter; + +/** + * Validates JNDI names before lookup to prevent remote URL-based lookups. + */ +public final class JndiNameValidator { + + private JndiNameValidator() { + } + + public static void validateJndiName(String name) { + if (name != null && name.contains("://")) { + throw new IllegalArgumentException("JNDI name must not contain a URL: " + name); + } + } +} \ No newline at end of file diff --git a/integration/jca/src/main/java/org/apache/cxf/jca/inbound/DispatchMDBMessageListenerImpl.java b/integration/jca/src/main/java/org/apache/cxf/jca/inbound/DispatchMDBMessageListenerImpl.java index d889a068401..044d9e61648 100644 --- a/integration/jca/src/main/java/org/apache/cxf/jca/inbound/DispatchMDBMessageListenerImpl.java +++ b/integration/jca/src/main/java/org/apache/cxf/jca/inbound/DispatchMDBMessageListenerImpl.java @@ -23,6 +23,7 @@ import java.lang.reflect.Method; import javax.ejb.MessageDrivenBean; import javax.ejb.MessageDrivenContext; import javax.naming.InitialContext; +import org.apache.cxf.jca.core.resourceadapter.JndiNameValidator; /** * DispatchMDBMessageListenerImpl supports dispatching of calls to a @@ -49,6 +50,7 @@ public class DispatchMDBMessageListenerImpl * Looks up the target object by EJB local reference. */ public Object lookupTargetObject(String targetJndiName) throws Exception { + JndiNameValidator.validateJndiName(targetJndiName); Object home = new InitialContext().lookup(targetJndiName); Method method = home.getClass().getMethod("create", new Class[0]); return method.invoke(home, new Object[0]); diff --git a/integration/jca/src/main/java/org/apache/cxf/jca/servant/EJBEndpoint.java b/integration/jca/src/main/java/org/apache/cxf/jca/servant/EJBEndpoint.java index a247c9154d0..2c5efcc7474 100644 --- a/integration/jca/src/main/java/org/apache/cxf/jca/servant/EJBEndpoint.java +++ b/integration/jca/src/main/java/org/apache/cxf/jca/servant/EJBEndpoint.java @@ -38,6 +38,7 @@ import org.apache.cxf.common.util.PackageUtils; import org.apache.cxf.endpoint.Server; import org.apache.cxf.frontend.ServerFactoryBean; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; +import org.apache.cxf.jca.core.resourceadapter.JndiNameValidator; import org.apache.cxf.jca.cxf.WorkManagerThreadPool; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngine; import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory; @@ -67,6 +68,7 @@ public class EJBEndpoint { public Server publish() throws Exception { jndiContext = new InitialContext(); + JndiNameValidator.validateJndiName(config.getJNDIName()); Object obj = jndiContext.lookup(config.getJNDIName()); ejbHome = (EJBHome) PortableRemoteObject.narrow(obj, EJBHome.class); diff --git a/integration/jca/src/test/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidatorTest.java b/integration/jca/src/test/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidatorTest.java new file mode 100644 index 00000000000..0a0e32318ef --- /dev/null +++ b/integration/jca/src/test/java/org/apache/cxf/jca/core/resourceadapter/JndiNameValidatorTest.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.jca.core.resourceadapter; + +import org.junit.Assert; +import org.junit.Test; + +public class JndiNameValidatorTest { + + @Test + public void testValidateJndiNamePlainNamesAllowed() { + JndiNameValidator.validateJndiName("java:comp/env/ejb/MyBean"); + JndiNameValidator.validateJndiName("ejb/MyBeanLocal"); + JndiNameValidator.validateJndiName(null); + } + + @Test + public void testValidateJndiNameRemoteUrlRejected() { + for (String malicious : new String[]{ + "ldap://attacker.com/exploit", + "rmi://attacker.com/exploit", + "iiop://attacker.com/exploit" + }) { + try { + JndiNameValidator.validateJndiName(malicious); + Assert.fail("Expected IllegalArgumentException for: " + malicious); + } catch (IllegalArgumentException e) { + Assert.assertTrue(e.getMessage().contains("JNDI name must not contain a URL")); + } + } + } +} \ No newline at end of file
