Log4Shell and its relation to Clojure

Log4Shell and its relation to Clojure

A new vulnerability was recently discovered on the Internet. Many internet services appear to be vulnerable. Lightpad.ai itself isn't affected by this particular type, but nevertheless, we're conducting and sharing analysis of the situation for better understanding and future prevention.

What it is

The subject was found in the logging library "log4j".


For some versions of Java and this logging library configurations a malicious actor can send strings containing an expansion pattern leading to download and execution of arbitrary code.

Root pull request https://issues.apache.org/jira/browse/LOG4J2-313

Affected software

  • Log4j version – all 2.x versions before 2.15.0 (released on Friday, December 10, 2021) are affected. [Later note, a couple of minor vulnerabilities were found and fixed, the recommended version is now 2.17.1 (released on Wednesday, December 29).
  • Log4j 1.x – configurations using a JMS appender may be affected https://github.com/apache/logging-log4j2/pull/608#issuecomment-990494126
  • JVM version - if lower than:
    • Java 6 – 6u212
    • Java 7 – 7u202
    • Java 8 – 8u192
    • Java 11 – 11.0.2

How bad is it

It's pretty bad, to say the least. There's evidence of some of the most established companies being compromised: Amazon, Google, Twitter, Apple, LinkedIn, VMWare, etc. If your bank / company uses Java – it may be compromised.

Data breaches of these companies will lead to more consequent breaches. This may or may not be the single biggest Internet vulnerability ever. And we're only at the beginning of it. Its echoes may be heard in months and years to come.

Existing analyses

By Cloudflare


Microsoft's report covers different exploitation methods, different evasion techniques


Mogwai Labs explaining how it works


Veracode with suggested mitigations


Detailed Twitter thread by Kevin Beaumont


Suggested mitigations

The following mitigations are copied from the sources above.

If you happen to use the affected version. In order to mitigate vulnerabilities, users should switch log4j2.formatMsgNoLookups to true by adding: "‐Dlog4j2.formatMsgNoLookups=True" to the JVM command for starting the application. This is supposedly enabled by default on more recent Java versions.

You can also upgrade to version 2.15.0, but I'm not sure if it wasn't rushed by the situation.

formatMsgNoLookups: true

// for java > 8u121 set system properties
com.sun.jndi.rmi.object.trustURLCodebase to false
com.sun.jndi.cosnaming.object.trustURLCodebase to false

How you can work with system properties:

Properties props = System.getProperties();
props.setProperty("gate.home", "http://gate.ac.uk/wiki/code-repository");
// or
System.setProperty("gate.home", "/some/directory");

Removing JndiLookup class from the classpath

zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

You can use a canary token (use it in a logged header) to check if it affects you. More info.

You can limit outgoing traffic.

You can start using Java security policy. Official doc

There's hotpatch tool going around (haven't checked it ourselves) – https://github.com/corretto/hotpatch-for-apache-log4j2

To fellow Clojurians

If you use clojure.tools.logging, and you didn't explicitly specify your logging implementation as specified in the project's README

:jvm-opts ["-Dclojure.tools.logging.factory=clojure.tools.logging.impl/slf4j-factory"]

Then clojure.tools.logging can automatically use log4j as a logging backend implementation. Its preferred order of logging implementations is cited in its README:

  1. SLF4J
  2. Apache Commons Logging
  3. Log4J 2
  4. Log4J
  5. java.util.logging

To see your full dependency tree, including transitives, you can use `lein deps :tree` or `clj -Stree`, then add exclusions where necessary. For a full sorted plain list of all transitive dependencies use `clj -X:deps list`

We used this snippet import's to check what implementations we can load

(.name clojure.tools.logging/*logger-factory*) ;; get your current logging implementation name

  (import (org.slf4j.impl SimpleLogger))
  (import (org.apache.commons.logging.impl NoOpLog))
  (import (org.apache.logging.log4j Level))
  (import (java.util.logging Level)))

Reminding you about a wonderful blog post on Clojure logging (whose author preferred logback).


You can also use Timbre or μ/log.

One can also use Vedang Manerikar's guide on log4j2 upgrade https://github.com/vedang/clj-logging 

Clojure security scanners

nvd-clojure – vulnerable dependencies finder for Clojure, thanks to Vedang Manerikar and Sean Corfield for the mention.

clj-holmes – scan project sources for patterns of insecure code (or any patterns), based on an extensible rule set. Thanks to Alex Miller for this addition.


Log4J seems to still be a good logging solution, with native map support – but we'll probably have to wait until a further investigation is conducted.

Of course, we, software developers, should review software before using it or upgrading, but this also can be a daunting task, can't it? Maybe we could use scanners to detect usage of JNDI, JNI, and other potentially privilege-escalating APIs? Maybe we could also label it with a GitLab / GitHub badge? Lightpad would support such an initiative with a couple of bucks per month. Overall – if you happen to know any automated scanning projects for Java / JavaScript please let us know on Twitter or by email – hello at lightpad.ai

You can subscribe to monthly donations to Clojurists Together. We think in the next few months it'll be much easier fund security-related projects.

Don't forget to remind your friends and family:

  • to change passwords again
  • to use 2-factor auth where possible and stop using SMS as a second factor
  • to store money on a separate account from your card account
  • to have card spending limits set in place
  • be ready for their photos, notes and emails being leaked again
  • be ready for their IoT devices being compromised


Social Image credit: Kevin Beaumont

Thanks to Alex Miller for the addition of clj-holmes and `clj -Sdeps list`!