Skip to content

Commit 4456909

Browse files
committed
LOG4J2-3208 - Disable JNDI by default
1 parent 3a5836b commit 4456909

File tree

16 files changed

+191
-29
lines changed

16 files changed

+191
-29
lines changed

log4j-core/src/main/java/org/apache/logging/log4j/core/lookup/Interpolator.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.apache.logging.log4j.Logger;
2525
import org.apache.logging.log4j.core.LogEvent;
2626
import org.apache.logging.log4j.core.config.ConfigurationAware;
27+
import org.apache.logging.log4j.core.net.JndiManager;
2728
import org.apache.logging.log4j.core.util.Loader;
2829
import org.apache.logging.log4j.util.ReflectionUtil;
2930
import org.apache.logging.log4j.plugins.util.PluginManager;
@@ -77,7 +78,9 @@ public Interpolator(final StrLookup defaultLookup, final List<String> pluginPack
7778
for (final Map.Entry<String, PluginType<?>> entry : plugins.entrySet()) {
7879
try {
7980
final Class<? extends StrLookup> clazz = entry.getValue().getPluginClass().asSubclass(StrLookup.class);
80-
strLookupMap.put(entry.getKey().toLowerCase(), ReflectionUtil.instantiate(clazz));
81+
if (!clazz.getName().equals(JndiLookup.class.getName()) || JndiManager.isIsJndiEnabled()) {
82+
strLookupMap.put(entry.getKey().toLowerCase(), ReflectionUtil.instantiate(clazz));
83+
}
8184
} catch (final Throwable t) {
8285
handleError(entry.getKey(), t);
8386
}
@@ -107,12 +110,14 @@ public Interpolator(final Map<String, String> properties) {
107110
strLookupMap.put("lower", new LowerLookup());
108111
strLookupMap.put("upper", new UpperLookup());
109112
// JNDI
110-
try {
111-
// [LOG4J2-703] We might be on Android
112-
strLookupMap.put(LOOKUP_KEY_JNDI,
113-
Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JndiLookup", StrLookup.class));
114-
} catch (final LinkageError | Exception e) {
115-
handleError(LOOKUP_KEY_JNDI, e);
113+
if (JndiManager.isIsJndiEnabled()) {
114+
try {
115+
// [LOG4J2-703] We might be on Android
116+
strLookupMap.put(LOOKUP_KEY_JNDI,
117+
Loader.newCheckedInstanceOf("org.apache.logging.log4j.core.lookup.JndiLookup", StrLookup.class));
118+
} catch (final LinkageError | Exception e) {
119+
handleError(LOOKUP_KEY_JNDI, e);
120+
}
116121
}
117122
// JMX input args
118123
try {

log4j-core/src/main/java/org/apache/logging/log4j/core/net/JndiManager.java

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ public class JndiManager extends AbstractManager {
7373

7474
private final DirContext context;
7575

76+
public static boolean isIsJndiEnabled() {
77+
return PropertiesUtil.getProperties().getBooleanProperty("log4j2.enableJndi", false);
78+
}
79+
7680
private JndiManager(final String name, final DirContext context, final List<String> allowedHosts,
7781
final List<String> allowedClasses, final List<String> allowedProtocols) {
7882
super(null, name);
@@ -82,6 +86,14 @@ private JndiManager(final String name, final DirContext context, final List<Stri
8286
this.allowedProtocols = allowedProtocols;
8387
}
8488

89+
private JndiManager(final String name) {
90+
super(null, name);
91+
this.context = null;
92+
this.allowedProtocols = null;
93+
this.allowedClasses = null;
94+
this.allowedHosts = null;
95+
}
96+
8597
/**
8698
* Gets the default JndiManager using the default {@link javax.naming.InitialContext}.
8799
*
@@ -194,6 +206,9 @@ public static Properties createProperties(final String initialContextFactoryName
194206

195207
@Override
196208
protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
209+
if (context != null) {
210+
return JndiCloser.closeSilently(this.context);
211+
}
197212
return JndiCloser.closeSilently(this.context);
198213
}
199214

@@ -207,6 +222,9 @@ protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
207222
*/
208223
@SuppressWarnings("unchecked")
209224
public synchronized <T> T lookup(final String name) throws NamingException {
225+
if (context == null) {
226+
return null;
227+
}
210228
try {
211229
URI uri = new URI(name);
212230
if (uri.getScheme() != null) {
@@ -262,21 +280,25 @@ private static class JndiManagerFactory implements ManagerFactory<JndiManager, P
262280

263281
@Override
264282
public JndiManager createManager(final String name, final Properties data) {
265-
String hosts = data != null ? data.getProperty(ALLOWED_HOSTS) : null;
266-
String classes = data != null ? data.getProperty(ALLOWED_CLASSES) : null;
267-
String protocols = data != null ? data.getProperty(ALLOWED_PROTOCOLS) : null;
268-
List<String> allowedHosts = new ArrayList<>();
269-
List<String> allowedClasses = new ArrayList<>();
270-
List<String> allowedProtocols = new ArrayList<>();
271-
addAll(hosts, allowedHosts, permanentAllowedHosts, ALLOWED_HOSTS, data);
272-
addAll(classes, allowedClasses, permanentAllowedClasses, ALLOWED_CLASSES, data);
273-
addAll(protocols, allowedProtocols, permanentAllowedProtocols, ALLOWED_PROTOCOLS, data);
274-
try {
275-
return new JndiManager(name, new InitialDirContext(data), allowedHosts, allowedClasses,
276-
allowedProtocols);
277-
} catch (final NamingException e) {
278-
LOGGER.error("Error creating JNDI InitialContext.", e);
279-
return null;
283+
if (isIsJndiEnabled()) {
284+
String hosts = data != null ? data.getProperty(ALLOWED_HOSTS) : null;
285+
String classes = data != null ? data.getProperty(ALLOWED_CLASSES) : null;
286+
String protocols = data != null ? data.getProperty(ALLOWED_PROTOCOLS) : null;
287+
List<String> allowedHosts = new ArrayList<>();
288+
List<String> allowedClasses = new ArrayList<>();
289+
List<String> allowedProtocols = new ArrayList<>();
290+
addAll(hosts, allowedHosts, permanentAllowedHosts, ALLOWED_HOSTS, data);
291+
addAll(classes, allowedClasses, permanentAllowedClasses, ALLOWED_CLASSES, data);
292+
addAll(protocols, allowedProtocols, permanentAllowedProtocols, ALLOWED_PROTOCOLS, data);
293+
try {
294+
return new JndiManager(name, new InitialDirContext(data), allowedHosts, allowedClasses,
295+
allowedProtocols);
296+
} catch (final NamingException e) {
297+
LOGGER.error("Error creating JNDI InitialContext.", e);
298+
return null;
299+
}
300+
} else {
301+
return new JndiManager(name);
280302
}
281303
}
282304

log4j-core/src/main/java/org/apache/logging/log4j/core/selector/JndiContextSelector.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ public class JndiContextSelector implements NamedContextSelector {
9393

9494
private static final StatusLogger LOGGER = StatusLogger.getLogger();
9595

96+
public JndiContextSelector() {
97+
if (!JndiManager.isIsJndiEnabled()) {
98+
throw new IllegalStateException("JNDI must be enabled by setting log4j2.enableJndi=true");
99+
}
100+
}
101+
96102
@Override
97103
public void shutdown(final String fqcn, final ClassLoader loader, final boolean currentContext, final boolean allContexts) {
98104
LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();

log4j-core/src/test/java/org/apache/logging/log4j/core/appender/routing/RoutingAppenderWithJndiTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.File;
2020
import java.util.Collections;
21+
import java.util.Map;
2122
import javax.naming.Context;
2223
import javax.naming.InitialContext;
2324
import javax.naming.NamingException;
@@ -47,9 +48,14 @@ public class RoutingAppenderWithJndiTest {
4748
public static LoggerContextRule loggerContextRule = new LoggerContextRule("log4j-routing-by-jndi.xml");
4849

4950
@ClassRule
50-
public static RuleChain rules = RuleChain.outerRule(new JndiRule(Collections.<String, Object>emptyMap()))
51+
public static RuleChain rules = RuleChain.outerRule(new JndiRule(initBindings()))
5152
.around(loggerContextRule);
5253

54+
private static Map<String, Object> initBindings() {
55+
System.setProperty("log4j2.enableJndi", "true");
56+
return Collections.emptyMap();
57+
}
58+
5359
@Before
5460
public void before() throws NamingException {
5561
listAppender1 = RoutingAppenderWithJndiTest.loggerContextRule.getListAppender("List1");

log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/InterpolatorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ public class InterpolatorTest {
4848
protected void before() throws Throwable {
4949
System.setProperty(TESTKEY, TESTVAL);
5050
System.setProperty(TESTKEY2, TESTVAL);
51+
System.setProperty("log4j2.enableJndi", "true");
5152
}
5253

5354
@Override
5455
protected void after() {
5556
System.clearProperty(TESTKEY);
5657
System.clearProperty(TESTKEY2);
58+
System.clearProperty("log4j2.enableJndi");
5759
}
5860
}).around(new JndiRule(
5961
JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME));
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache license, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the license for the specific language governing permissions and
15+
* limitations under the license.
16+
*/
17+
package org.apache.logging.log4j.core.lookup;
18+
19+
import java.util.Arrays;
20+
import java.util.Collection;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import org.apache.logging.log4j.core.test.junit.JndiRule;
25+
import org.junit.Rule;
26+
import org.junit.Test;
27+
28+
import static org.junit.Assert.assertNull;
29+
30+
/**
31+
* JndiDisabledLookupTest
32+
*
33+
* Verifies the Lookups are disabled without the log4j2.enableJndi property set to true.
34+
*/
35+
public class JndiDisabledLookupTest {
36+
37+
private static final String TEST_CONTEXT_RESOURCE_NAME = "logging/context-name";
38+
private static final String TEST_CONTEXT_NAME = "app-1";
39+
private static final String TEST_INTEGRAL_NAME = "int-value";
40+
private static final int TEST_INTEGRAL_VALUE = 42;
41+
private static final String TEST_STRINGS_NAME = "string-collection";
42+
private static final Collection<String> TEST_STRINGS_COLLECTION = Arrays.asList("one", "two", "three");
43+
44+
@Rule
45+
public JndiRule jndiRule = new JndiRule(createBindings());
46+
47+
private Map<String, Object> createBindings() {
48+
final Map<String, Object> map = new HashMap<>();
49+
map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);
50+
map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_INTEGRAL_NAME, TEST_INTEGRAL_VALUE);
51+
map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_STRINGS_NAME, TEST_STRINGS_COLLECTION);
52+
return map;
53+
}
54+
55+
@Test
56+
public void testLookup() {
57+
final StrLookup lookup = new JndiLookup();
58+
59+
String contextName = lookup.lookup(TEST_CONTEXT_RESOURCE_NAME);
60+
assertNull(contextName);
61+
}
62+
}

log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiLookupTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.Map;
2323

2424
import org.apache.logging.log4j.core.test.junit.JndiRule;
25+
import org.junit.BeforeClass;
2526
import org.junit.Rule;
2627
import org.junit.Test;
2728

@@ -42,6 +43,11 @@ public class JndiLookupTest {
4243
@Rule
4344
public JndiRule jndiRule = new JndiRule(createBindings());
4445

46+
@BeforeClass
47+
public static void beforeClass() {
48+
System.setProperty("log4j2.enableJndi", "true");
49+
}
50+
4551
private Map<String, Object> createBindings() {
4652
final Map<String, Object> map = new HashMap<>();
4753
map.put(JndiLookup.CONTAINER_JNDI_RESOURCE_PATH_PREFIX + TEST_CONTEXT_RESOURCE_NAME, TEST_CONTEXT_NAME);

log4j-core/src/test/java/org/apache/logging/log4j/core/lookup/JndiRestrictedLookupTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class JndiRestrictedLookupTest {
5454
public static void beforeClass() {
5555
System.setProperty("log4j2.allowedLdapClasses", Level.class.getName());
5656
System.setProperty("log4j2.allowedJndiProtocols", "dns");
57+
System.setProperty("log4j2.enableJndi", "true");
5758
}
5859

5960
@Test

log4j-jms/src/main/java/org/apache/logging/log4j/jms/appender/JmsManager.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,15 @@ private static class JmsManagerFactory implements ManagerFactory<JmsManager, Jms
125125

126126
@Override
127127
public JmsManager createManager(final String name, final JmsManagerConfiguration data) {
128-
try {
129-
return new JmsManager(name, data);
130-
} catch (final Exception e) {
131-
logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
128+
if (JndiManager.isIsJndiEnabled()) {
129+
try {
130+
return new JmsManager(name, data);
131+
} catch (final Exception e) {
132+
logger().error("Error creating JmsManager using JmsManagerConfiguration [{}]", data, e);
133+
return null;
134+
}
135+
} else {
136+
logger().error("JNDI has not been enabled. The log4j2.enableJndi property must be set to true");
132137
return null;
133138
}
134139
}

log4j-jms/src/test/java/org/apache/logging/log4j/jms/appender/JmsAppenderTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.apache.logging.log4j.message.SimpleMessage;
5050
import org.apache.logging.log4j.message.StringMapMessage;
5151
import org.junit.Before;
52+
import org.junit.BeforeClass;
5253
import org.junit.Rule;
5354
import org.junit.Test;
5455
import org.junit.experimental.categories.Category;
@@ -83,6 +84,11 @@ public class JmsAppenderTest {
8384
@Rule
8485
public RuleChain rules = RuleChain.outerRule(jndiRule).around(ctx);
8586

87+
@BeforeClass
88+
public static void beforeClass() throws Exception {
89+
System.setProperty("log4j2.enableJndi", "true");
90+
}
91+
8692
public JmsAppenderTest() throws Exception {
8793
// this needs to set up before LoggerContextRule
8894
given(connectionFactory.createConnection()).willReturn(connection);

0 commit comments

Comments
 (0)