Sense behind the LDAP lookup feature in log4j
Asked Answered
B

1

15

Recently a 0-day exploit got disclosed, that uses a security vulnerability in log4j which allows unauthorised remote code execution.

I'm wondering, what was the actual reason, why log4j has implemented this JNDI lookups, which have cause the vulnerability at all?

What would be an example for using this LDAP lookup feature in log4j?

Beeler answered 16/12, 2021 at 8:14 Comment(0)
I
8

Log4j is a popular logging framework used in Java (you can figure the popularity by seeing the widespread impact of the vulnerability). Log4j offers a specific feature, where you can add tokens to your logging string, that get interpolated to fetch specific data. E.g. "%d{dd MMM yyyy}" will insert the date at which the message was logged.

In the mean time JNDI (Java Naming and Directory Interface) is commonly used for sharing configuration settings to multiple (mirco)services.

You can imagine a situation where somebody would like to log configuration settings in e.g. error situations.

See this article explaining a bit

A Java based application can use JNDI + LDAP together to find a Business object containing data that it might need. For example, the following URL ldap://localhost:3xx/o=BusinessObjectID to find and invoke theBusinessObject remotely from an LDAP server running on either a same machine (localhost) on port 3xx or remote machine hosted in a controlled environment and goes on to read attributes from it.

The update it refers to mentions it as "LOG4J2-313: Add JNDILookup plugin." The motivation is found in the Apache JIRA entry

Currently, Lookup plugins [1] don't support JNDI resources. It would be really convenient to support JNDI resource lookup in the configuration.

One use case with JNDI lookup plugin is as follows: I'd like to use RoutingAppender [2] to put all the logs from the same web application context in a log file (a log file per web application context). And, I want to use JNDI resources look up to determine the target route (similarly to JNDI context selector of logback [3]).

Determining the target route by JNDI lookup can be advantageous because we don't have to add any code to set properties for the thread context and JNDI lookup should always work even in a separate thread without copying thread context variables.

[1] http://logging.apache.org/log4j/2.x/manual/lookups.html [2] http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender [3] http://logback.qos.ch/manual/contextSelector.html

The big problem with log4j, is that by default all string interpolation of all modules is turned on. In the mean time it has become opt-out, but it wasn't always.

Imbecilic answered 16/12, 2021 at 8:34 Comment(6)
Maybe I still don't understand it. But somehow I'm still wondering how such a special requirement, that would be only helpful for an extremely small group of users, could have made it into log4j. Log4j is a very generic log library and this is a very specific feature, that could have been implemented easily by them selfs, who really need such a specialised thing.Beeler
@Beeler do you have experience with open source libraries? This is just how things go. in 2013, when this was added, they were happy with this addition. The author proposed it, but wouldn't be able to add it himself. Instead the patch was added by Ralph Goers, the Vice President Apache Logging Services.Imbecilic
@eztam: web applications often do JNDI lookups to retrieve configuration parameters, datasources and other objects (for example Spring does it), since system properties can not be customized per application. However usually only java:comp/env lookups are allowed. What went terribly wrong here is allowing also ldap: lookups. I believe that was unintentional.Clover
@PiotrP.Karwasz Thanks for the explanation. That makes totally sense now.Beeler
What I really don't get is the reason for JNDI allowing access to an arbitrary LDAP server - that can serve up jar files for your process to execute for you! - via a run-time string! At the very least it should be have been restricted to a JVM configuration parameter - you want a different LDAP server you've got to add it to the config and restart your JVM. What's the use case for allowing access to an arbitrary run-time determined LDAP server anyway? Oh, and by the way, allowing an LDAP server to cough up an arbitrary jar for you to execute? Why was that itself a good idea?Complication
@Complication Java is traditionally backwards compatible as much as possible. This was how it was originally done back in the mists of time so behavior has been kept. The ACTUAL culprit is the ability of the Serialization mechanism to deserialize any object what so ever.Apprehend

© 2022 - 2024 — McMap. All rights reserved.