File disable-jndi-by-default.patch of Package log4j.22206
From c362aff473e9812798ff8f25f30a2619996605d5 Mon Sep 17 00:00:00 2001
From: Ralph Goers <rgoers@apache.org>
Date: Sat, 11 Dec 2021 16:05:14 -0700
Subject: [PATCH] LOG4J2-3208 - Disable JNDI by default
---
.../log4j/core/appender/mom/JmsManager.java | 13 ++--
.../log4j/core/lookup/Interpolator.java | 19 ++++--
.../logging/log4j/core/net/JndiManager.java | 54 +++++++++++-----
.../core/selector/JndiContextSelector.java | 6 ++
.../core/appender/mom/JmsAppenderTest.java | 6 ++
.../routing/RoutingAppenderWithJndiTest.java | 10 ++-
.../log4j/core/lookup/InterpolatorTest.java | 3 +
.../core/lookup/JndiDisabledLookupTest.java | 64 +++++++++++++++++++
.../log4j/core/lookup/JndiLookupTest.java | 6 ++
.../core/lookup/JndiRestrictedLookupTest.java | 1 +
src/changes/changes.xml | 3 +
src/site/markdown/index.md.vm | 2 +-
src/site/markdown/security.md | 2 +-
src/site/xdoc/manual/appenders.xml | 3 +
src/site/xdoc/manual/configuration.xml.vm | 8 +++
src/site/xdoc/manual/logsep.xml | 3 +
src/site/xdoc/manual/lookups.xml | 5 ++
17 files changed, 177 insertions(+), 31 deletions(-)
create mode 100644 log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java
Index: apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java 2021-12-14 18:39:45.617280560 +0100
@@ -125,12 +125,17 @@ public class JmsManager extends Abstract
@Override
public JmsManager createManager(final String name, final JmsManagerConfiguration data) {
+ if (JndiManager.isIsJndiEnabled()) {
try {
return new JmsManager(name, data);
} catch (final Exception e) {
logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
return null;
}
+ } else {
+ logger().error("JNDI has not been enabled. The log4j2.enableJndi property must be set to true");
+ return null;
+ }
}
}
Index: apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java 2021-12-14 18:39:45.617280560 +0100
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.Log
import org.apache.logging.log4j.core.config.ConfigurationAware;
import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
import org.apache.logging.log4j.core.config.plugins.util.PluginType;
+import org.apache.logging.log4j.core.net.JndiManager;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.ReflectionUtil;
import org.apache.logging.log4j.status.StatusLogger;
@@ -77,7 +78,9 @@ public class Interpolator extends Abstra
for (final Map.Entry<String, PluginType<?>> entry : plugins.entrySet()) {
try {
final Class<? extends StrLookup> clazz = entry.getValue().getPluginClass().asSubclass(StrLookup.class);
+ if (!clazz.getName().equals(JndiLookup.class.getName()) || JndiManager.isIsJndiEnabled()) {
strLookupMap.put(entry.getKey().toLowerCase(), ReflectionUtil.instantiate(clazz));
+ }
} catch (final Throwable t) {
handleError(entry.getKey(), t);
}
@@ -106,6 +109,7 @@ public class Interpolator extends Abstra
strLookupMap.put("lower", new LowerLookup());
strLookupMap.put("upper", new UpperLookup());
// JNDI
+ if (JndiManager.isIsJndiEnabled()) {
try {
// [LOG4J2-703] We might be on Android
strLookupMap.put(LOOKUP_KEY_JNDI,
@@ -113,6 +117,7 @@ public class Interpolator extends Abstra
} catch (final LinkageError | Exception e) {
handleError(LOOKUP_KEY_JNDI, e);
}
+ }
// JMX input args
try {
// We might be on Android
Index: apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java 2021-12-14 18:39:45.617280560 +0100
@@ -73,6 +73,10 @@ public class JndiManager extends Abstrac
private final DirContext context;
+ public static boolean isIsJndiEnabled() {
+ return PropertiesUtil.getProperties().getBooleanProperty("log4j2.enableJndi", false);
+ }
+
private JndiManager(final String name, final DirContext context, final List<String> allowedHosts,
final List<String> allowedClasses, final List<String> allowedProtocols) {
super(null, name);
@@ -82,6 +86,14 @@ public class JndiManager extends Abstrac
this.allowedProtocols = allowedProtocols;
}
+ private JndiManager(final String name) {
+ super(null, name);
+ this.context = null;
+ this.allowedProtocols = null;
+ this.allowedClasses = null;
+ this.allowedHosts = null;
+ }
+
/**
* Gets the default JndiManager using the default {@link javax.naming.InitialContext}.
*
@@ -194,8 +206,11 @@ public class JndiManager extends Abstrac
@Override
protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
+ if (context != null) {
return JndiCloser.closeSilently(this.context);
}
+ return true;
+ }
/**
* Looks up a named object through this JNDI context.
@@ -207,6 +222,9 @@ public class JndiManager extends Abstrac
*/
@SuppressWarnings("unchecked")
public synchronized <T> T lookup(final String name) throws NamingException {
+ if (context == null) {
+ return null;
+ }
try {
URI uri = new URI(name);
if (uri.getScheme() != null) {
@@ -261,6 +279,7 @@ public class JndiManager extends Abstrac
@Override
public JndiManager createManager(final String name, final Properties data) {
+ if (isIsJndiEnabled()) {
String hosts = data != null ? data.getProperty(ALLOWED_HOSTS) : null;
String classes = data != null ? data.getProperty(ALLOWED_CLASSES) : null;
String protocols = data != null ? data.getProperty(ALLOWED_PROTOCOLS) : null;
@@ -277,6 +296,9 @@ public class JndiManager extends Abstrac
LOGGER.error("Error creating JNDI InitialContext.", e);
return null;
}
+ } else {
+ return new JndiManager(name);
+ }
}
private void addAll(String toSplit, List<String> list, List<String> permanentList, String propertyName,
Index: apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java 2021-12-14 18:39:45.617280560 +0100
@@ -93,6 +93,12 @@ public class JndiContextSelector impleme
private static final StatusLogger LOGGER = StatusLogger.getLogger();
+ public JndiContextSelector() {
+ if (!JndiManager.isIsJndiEnabled()) {
+ throw new IllegalStateException("JNDI must be enabled by setting log4j2.enableJndi=true");
+ }
+ }
+
@Override
public void shutdown(String fqcn, ClassLoader loader, boolean currentContext, boolean allContexts) {
LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/mom/JmsAppenderTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -49,6 +49,7 @@ import org.apache.logging.log4j.message.
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.message.StringMapMessage;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -83,6 +84,11 @@ public class JmsAppenderTest {
@Rule
public RuleChain rules = RuleChain.outerRule(jndiRule).around(ctx);
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ System.setProperty("log4j2.enableJndi", "true");
+ }
+
public JmsAppenderTest() throws Exception {
// this needs to set up before LoggerContextRule
given(connectionFactory.createConnection()).willReturn(connection);
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.ap
import java.io.File;
import java.util.Collections;
+import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -29,6 +30,7 @@ import org.apache.logging.log4j.message.
import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.After;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.RuleChain;
@@ -47,8 +49,12 @@ public class RoutingAppenderWithJndiTest
public static LoggerContextRule loggerContextRule = new LoggerContextRule("log4j-routing-by-jndi.xml");
@ClassRule
- public static RuleChain rules = RuleChain.outerRule(new JndiRule(Collections.<String, Object>emptyMap()))
- .around(loggerContextRule);
+ public static RuleChain rules = RuleChain.outerRule(new JndiRule(initBindings())).around(loggerContextRule);
+
+ private static Map<String, Object> initBindings() {
+ System.setProperty("log4j2.enableJndi", "true");
+ return Collections.emptyMap();
+ }
@Before
public void before() throws NamingException {
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.junit.JndiRule;
+import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
@@ -48,12 +49,14 @@ public class InterpolatorTest {
protected void before() throws Throwable {
System.setProperty(TESTKEY, TESTVAL);
System.setProperty(TESTKEY2, TESTVAL);
+ System.setProperty("log4j2.enableJndi", "true");
}
@Override
protected void after() {
System.clearProperty(TESTKEY);
System.clearProperty(TESTKEY2);
+ System.clearProperty("log4j2.enableJndi");
}
}).around(new JndiRule(
JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME));
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiDisabledLookupTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -0,0 +1,64 @@
+/*
+ * 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.logging.log4j.core.lookup;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.junit.JndiRule;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * JndiDisabledLookupTest
+ *
+ * Verifies the Lookups are disabled without the log4j2.enableJndi property set to true.
+ */
+public class JndiDisabledLookupTest {
+
+ private static final String TEST_CONTEXT_RESOURCE_NAME = "logging/context-name";
+ private static final String TEST_CONTEXT_NAME = "app-1";
+ private static final String TEST_INTEGRAL_NAME = "int-value";
+ private static final int TEST_INTEGRAL_VALUE = 42;
+ private static final String TEST_STRINGS_NAME = "string-collection";
+ private static final Collection<String> TEST_STRINGS_COLLECTION = Arrays.asList("one", "two", "three");
+
+ @Rule
+ public JndiRule jndiRule = new JndiRule(createBindings());
+
+ private Map<String, Object> createBindings() {
+ final Map<String, Object> map = new HashMap<>();
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_INTEGRAL_NAME, TEST_INTEGRAL_VALUE);
+ map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_STRINGS_NAME, TEST_STRINGS_COLLECTION);
+ return map;
+ }
+
+ @Test
+ public void testLookup() {
+ final StrLookup lookup = new JndiLookup();
+
+ String contextName = lookup.lookup(TEST_CONTEXT_RESOURCE_NAME);
+ assertNull(contextName);
+ }
+}
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.junit.JndiRule;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
@@ -42,6 +43,11 @@ public class JndiLookupTest {
@Rule
public JndiRule jndiRule = new JndiRule(createBindings());
+ @BeforeClass
+ public static void beforeClass() {
+ System.setProperty("log4j2.enableJndi", "true");
+ }
+
private Map<String, Object> createBindings() {
final Map<String, Object> map = new HashMap<>();
map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
Index: apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java
===================================================================
--- apache-log4j-2.13.0-src.orig/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java 2021-12-14 18:39:45.617280560 +0100
@@ -54,6 +54,7 @@ public class JndiRestrictedLookupTest {
public static void beforeClass() {
System.setProperty("log4j2.allowedLdapClasses", Level.class.getName());
System.setProperty("log4j2.allowedJndiProtocols", "dns");
+ System.setProperty("log4j2.enableJndi", "true");
}
@Test
Index: apache-log4j-2.13.0-src/src/site/xdoc/manual/appenders.xml
===================================================================
--- apache-log4j-2.13.0-src.orig/src/site/xdoc/manual/appenders.xml 2021-12-14 18:39:38.369421272 +0100
+++ apache-log4j-2.13.0-src/src/site/xdoc/manual/appenders.xml 2021-12-14 18:39:45.621280482 +0100
@@ -1527,6 +1527,9 @@ public class ConnectionFactory {
<a name="JMSTopicAppender"/>
<subsection name="JMS Appender">
<p>The JMS Appender sends the formatted log event to a JMS Destination.</p>
+ <p>The JMS Appender requires JNDI support so as of release 2.15.1 this appender will not function unless
+ <code>log4j2.enableJndi=true</code>log4j2.enableJndi=true is configured as a system property or environment
+ variable. See the <a href="./configuration.html#enableJndi">enableJndi</a> system property.</p>
<p>
Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting
in Log4j 2.1, these appenders were combined into the JMS Appender which makes no distinction between queues
Index: apache-log4j-2.13.0-src/src/site/xdoc/manual/configuration.xml.vm
===================================================================
--- apache-log4j-2.13.0-src.orig/src/site/xdoc/manual/configuration.xml.vm 2021-12-14 18:39:38.373421194 +0100
+++ apache-log4j-2.13.0-src/src/site/xdoc/manual/configuration.xml.vm 2021-12-14 18:39:45.621280482 +0100
@@ -1938,6 +1938,14 @@ public class AwesomeTest {
</td>
</tr>
<tr>
+ <td><a name="enableJndi"/>log4j2.enableJndi</td>
+ <td>LOG4J_ENABLE_JNDI</td>
+ <td>false</td>
+ <td>
+ When true, Log4j components that use JNDI are enabled. When false, the default, they are disabled.
+ </td>
+ </tr>
+ <tr>
<td><a name="allowedLdapClasses"/>log4j2.allowedLdapClasses</td>
<td>LOG4J_ALLOWED_LDAP_CLASSES</td>
<td> </td>
Index: apache-log4j-2.13.0-src/src/site/xdoc/manual/logsep.xml
===================================================================
--- apache-log4j-2.13.0-src.orig/src/site/xdoc/manual/logsep.xml 2021-12-14 18:39:38.373421194 +0100
+++ apache-log4j-2.13.0-src/src/site/xdoc/manual/logsep.xml 2021-12-14 18:39:45.621280482 +0100
@@ -111,6 +111,9 @@
to use JNDI to locate each web application's <code>LoggerContext</code>. Be sure to set the
<code>isLog4jContextSelectorNamed</code> context parameter to <kbd>true</kbd> and also set the
<code>log4jContextName</code> and <code>log4jConfiguration</code> context parameters.
+ Note that the JndiContextSelector will not work unless <code>log4j2.enableJndi=true</code> is set as a
+ system property or environment variable. See the
+ <a href="./configuration.html#enableJndi">enableJndi</a> system property.
</li>
</ol>
<p>
Index: apache-log4j-2.13.0-src/src/site/xdoc/manual/lookups.xml
===================================================================
--- apache-log4j-2.13.0-src.orig/src/site/xdoc/manual/lookups.xml 2021-12-14 18:39:38.373421194 +0100
+++ apache-log4j-2.13.0-src/src/site/xdoc/manual/lookups.xml 2021-12-14 18:39:45.621280482 +0100
@@ -184,6 +184,11 @@
<a name="JndiLookup"/>
<subsection name="Jndi Lookup">
<p>
+ As of Log4j 2.15.1 JNDI operations require that <code>log4j2.enableJndi=true</code> be set as a system
+ property or the corresponding environment variable for this lookup to function. See the
+ <a href="./configuration.html#enableJndi">enableJndi</a> system property.
+ </p>
+ <p>
The JndiLookup allows variables to be retrieved via JNDI. By default the key will be prefixed with
java:comp/env/, however if the key contains a ":" no prefix will be added.
</p>