Lessons learned from Log4j 2 vulnerability

In case you were hiding under a rock – or maybe you were hiding from yelping endlessly about security vulnerabilities – Log4j 2 recently revealed some serious security issues.

This is an ugly episode in Java history, but there are a few important takeaways for the Java community.

Beyond SQL Injection

The problem is that Log4j 2 gave us a new vector for code injection, via JNDI. Malicious actors can trick your virtual machines into downloading and executing arbitrary code via a simple JNDI reference embedded in text. This is SQL injection, part two.

Like SQL injection, it can be mitigated if you properly clean up the logging output and simply don’t use user-provided content as the logging template. Most static code analysis tools, such as FindBugs or PMD, check for these items, so it’s recommended to include these tools in your continuous integration builds. However, much like SQL injection, mitigation efforts rely on your entire stack to do the right thing, and you can’t rely on that assumption.

There are things you can do to mitigate exposure to risks like the Log4j 2 flaw. The most important step is to update your Log4j 2 dependencies.

If you are using Log4j 2 anywhere in your Java applications, update to the latest version of Log4j 2. According to the project site, if you are using Java 6, update to 2.3.2. If you are using Java 7, update to 2.12.4. If you’re using something newer, update to 2.17.1 or later.

The Log4j Blame Game 2

The next thing to think about is, how did it happen? The Log4j 2 security hole isn’t really a hole – it’s a cavernous tunnel. It’s hard to underestimate the potential seriousness of the problem. How could such a simple and common dependency as logging create such a mess?

The short answer is offered without judgment: pride. There’s a line at Michael Crichton jurassic parkwhere Ian Malcolm chastised people for creating a Frankenstein monster: “Your scientists were so preoccupied with whether they could or not, they didn’t stop to think whether they should.”

This is an appropriate quote for the havoc of Log4j 2. The cause of the JNDI attack vector is the ability to search logging content by providing an embedded JNDI reference, which can access an external site. This JNDI content can be a serialized Java class, which can execute arbitrary code in the virtual machine. Sounds like a really cool feature, if you need it.

But should you ever need it? How often do you really want to search for a logging pattern in an external resource? I think it’s fair to assume that someone wanted it somewhere at some point because they wrote the code for it. But is this really a feature that the main library needs?

Writing this code requires a degree of hubris, although I’m sure the original author justified it in some way. (I certainly hope so; if someone delivered this functionality on a lark without any requirements, it’s a tragedy of Homeric proportions.)

The Swiss Government Computer Emergency Response Team provides this table to describe how a Log4j 2 LDAP injection attack is performed on the server.

Origins of the Log4j 2 vulnerability: feature creep

The real pride, observed without reproach, belongs to the Log4j community who approved the feature to be included in the library. any real failure happened in the process, it was here. Maybe a programmer needing the JNDI lookup function for some reason, but this merge request has been sent to the Log4j community for inclusion. They allowed it.

I say this without contempt or ill will towards the Log4j community. There, but for the grace of God, I–I sure endorsed features that made no sense to me at the time, and saw no harm in them until further analysis.

Yet that’s how the problem began: unchecked feature creep, pride, and inattention. Instead of saying, “That sounds like a nice feature, but it’s not part of Log4j’s mission”, people said “sure, why not, what’s the harm?” – and now we see the answer to that question.

The impact of this bug on the community is even more emotional than anything else. Java has always had potential security vulnerabilities, but overall it has a pretty good record. Most of the holes appear, just like the Log4j 2 bug – in libraries that didn’t anticipate how bad actors might use specific features, and eventually fixed fairly quickly.

This does not erase the black mark on the Java folder. We laughed and sneered at the suffering of the JavaScript ecosystem when – and now we have our own variant of the same problem.

Lessons learned from Log4j J2

But what is the real long-term impact? It’s up to us, and what we can learn from it all.

We need a manageable

We can weather this storm around Log4j 2; we’ve handled worse. We just need to approach this situation rationally, as we should in any situation.