Log4j Vulnerability in 3rd party applications like apache zookeeper

6k Views Asked by At

Apache log4j zookeeper uses log4j 1.2 which is vulnerable to RCE. To rectify this issue we planned to exclude log4j 1.2 and include log4j 2.17.1 core and log4j 2.17.1 api in the dependency

It doesnt help. Can somebody please suggest how to exclude jars from third party libraries

Error: Getting this errror : Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/jmx/HierarchyDynamicMBean at org.apache.zookeeper.jmx.ManagedUtil.registerLog4jMBeans(ManagedUtil.java:50) at org.apache.zookeeper.server.ZooKeeperServerMain.initializeAndRun(ZooKeeperServerMain.java:91) at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:61) at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:125) at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:79) Caused by: java.lang.ClassNotFoundException: org.apache.log4j.jmx.HierarchyDynamicMBean at java.net.URLClassLoader.findClass(URLClassLoader.

We tried this ..

<dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.5.1-alpha</version>
            <exclusions>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>2.17.1</version>
        </dependency>
    </dependencies>
3

There are 3 best solutions below

2
On

Zookeeper is apparently trying to directly access Log4j 1.2 internal classes, which no longer exist in log4j-1.2-api (cf. source code).

You can:

  • either set the system property zookeeper.jmx.log4j.disable to true
  • or upgrade to a newer version (e.g. 3.5.9), which will detect the absence of the HierarchyDynamicMBean class automatically.

You should upgrade anyway since the alpha version you are using has several security vulnerabilities: cf. Maven Repository.

2
On

The following dependency configuration seems to have worked for me:

        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.7.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.17.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.17.1</version>
        </dependency>
2
On

I believe I figured it out but I haven't tested this for long enough.

Considering this was applied to a v3.6.1 Zookeeper server, a summary of what needs to be done is:

  1. Delete old log4j libraries from Zookeeper
    1. log4j-1.2.17.jar
    2. log4j-1.2.17.LICENSE.txt (That's obviously not necessary)
  2. Add recent log4j libraries that has the fix for the log4shell vulerability.
    1. A log4j2 bridge that is backward compatible with log4j1.x: log4j-1.2-api-2.17.1.jar
    2. Necessary log4j libraries: log4j-api-2.17.1.jar & log4j-core-2.17.1.jar
  3. Modify Zookeeper's server environment options file (i.e. /zookeeper/conf/server_jvm.properties) by adding the following lines
    • -Dlog4j.configuration=/incorta/IncortaAnalytics/IncortaNode/zookeeper/conf/log4j.properties (A pointer for log4j2 to the existing log4j1.x configuration file, see the reference below for more details)
    • -Dzookeeper.jmx.log4j.disable=true (Disable Zookeeper's JMX dependency on log4j1.x. Thanks to Piotr for that tip he mentioned for this question)

What this does is that it keeps the sl4j libraries shipped with Zookeeper because changing those to a version that is log4j2 compatible wasn't a pleasant experience for me.

And instead, I upgraded log4j1.x libraries to log4j2 while having the log4j bridge library too to enable Zookeeper's outdated slf4j libraries to use the recent log4j2 ones.

Reference


Update: Using JDK 11, we faced a weird error where our Zookeeper client couldn't connect to Zookeeper, and the solution was to remove the slf4j-log4j12 binder from our classpath.