How can I find out what version of Log4J I am using?

As we all know, at least four or five Log4j JAR files end up being in the classpath. How can I tell which version I am using?


Solution 1:

I came here after learning my servers may be vulnerable to the new Log4j exploit (CVE-2021-44228). So I needed to know whether I had an outdated/vulnerable build of Log4j version 2 installed.

Previous answers here do not help with detecting old versions, because they are for letting already-running Java code figure out which version of Log4j that code uses, whereas I need to know if any Java app could be using a vulnerable version.

Here's what I did instead:

sudo find / -name 'log4j*'

This lists all Log4j related files on my (Linux) server. That showed me a few 1.x versions, which are not vulnerable to this specific CVE, and one 2.15.0 file, which already contains the fix for the CVE.

If you run this and find file or folder names that have 2.x, where x < 15, then you are likely vulnerable, and need to figure out how to update your files ASAP.

Caution

I was warned that this is not enough of a test for my purpose because the Log4j files may be hidden inside a .jar file, which the find command would not discover.

Update

Here's a public project that attempts to scan all .jar files, in order to find Log4j code inside archives as well: Log4-detector

Solution 2:

It depends on the ClassLoader, but have a look at the example:

import org.apache.log4j.Layout;

public class X {
    public static void main(String[] a) {
        Package p = Layout.class.getPackage();
        System.out.println(p);
        System.out.println("Implementation title:   " + p.getImplementationTitle());
        System.out.println("Implementation vendor:  " + p.getImplementationVendor());
        System.out.println("Implementation version: " + p.getImplementationVersion());
    }
}

You can call the method getImplementationVersion on the Layout class of log4j:

org.apache.log4j.Layout.class.getPackage().getImplementationVersion()

Solution 3:

I wouldn't expect this to be the preferred method, but it is how I determined the version of Log4j that my software was using:

Open, or extract the contents of, the Log4j .jar using a .zip archiving utility (Windows Explorer supports this). Navigate into the "META-INF" sub-directory and open the file "MANIFEST.MF" in a text editor. Find the line starting with "Implementation-Version", this is the Log4j version.

Obviously, this is not a programmatic solution. But if you simply want to know what version you are using and you have the .jar archive, it works.

I noticed that Package.getSpecificationVersion() and Package.getImplementationVersion(), as mentioned in Loic M.'s answer, work for other .jar libraries, but not my Log4j. It's possible that the version I am using just doesn't support it.

I downloaded version 2.13.1 to try out the above mentioned methods and found that they do work with it. So it was my version (1.2.16) that didn't support them and returned null.

Solution 4:

I've written a small Bash script to check versions of each Log4j JAR file located on that server. It reads the version information from the manifest file, since trusting in file names is a little risky.

locs=( $(sudo find / -name 'log4j*'|grep jar) )
fcount=${#locs[@]}

echo "Found $fcount jar files"
echo " "

for (( j=0; j<${fcount}; j++ ));
do
    unzip ${locs[$j]} META-INF/MANIFEST.MF
    mv META-INF/MANIFEST.MF META-INF/MANIFEST$j.MF
done

echo " "
for (( j=0; j<${fcount}; j++ ));
do
    echo ${locs[$j]}
    tail -2 META-INF/MANIFEST$j.MF
done

Solution 5:

To know the Log4j version during runtime in Java:

LOGGER.info("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());

Or

System.out.println("Log4j version: " + org.apache.logging.log4j.util.PropertiesUtil.class.getPackage().getImplementationVersion());