Support my work ♥

Updating minecraft to mitigate log4j - got a new log4j RCE - and how I would go forward

Now, this is not meant to be funny. I read about the log4j debacle on the news and was relieved that the only java based service I operate is one minecraft instance.

Here is the official minecraft blog post that basically tells you to update to 1.18.1 or apply a workaround. There is a second version of the same article as well.

Updating to the latest release

Sadly, finding the binary on the official minecraft website without a search engine is next to impossible. Here is the direct link for you:

And after the update I see that minecraft 1.18.1 uses log4j 2.14.1. Now, the precise readers note that this is still one of the affected releases.


The clients should update themselves after a complete restart of the application and launcher. So that is good.

log4j 2.16.0

On the Microsoft security response center they detail how this JndiLookup can be exploited and how to delete the class from the jar file in case there is no legitimate use for it in the application.

log4j 2.17.0 and DoS

This release should fix infinite recursion but as some pointed out: maybe not

You can download the latest version here:

Minecraft Server in the future

For the minecraft operators, wait for 1.18.2 and hope that it contains a more recent version that contains all the fixes.

Running services on the internet is always risky and very useful. So one has to make the best efforts to keep them secure and operational.

What now?

Well as heise put it: works as specified

The function with the lookup in the string that is to be logged falls in the same category as SQL injections. Both build on the same error:

  • Have multiple contexts (control and data) in one and
  • Let remote attackers control the one of them (data) that ends up in the parsed string

With SQL the solution was a change in protocol where we have placeholders now and the untrusted data is submitted separately

How did SQL fix it?

The answer is Input Parameters. Basically, instead of having control and data in the same string we have the ? to indicate where in the parsed AST we want to insert dynamic data and in a second step we actually send the data so we do not have any confusion on what is what.

To quote from the PostgreSQL manual, here is how to use a named stored procedure:

const char *stmt = "INSERT INTO test1 VALUES(?, ?);";

EXEC SQL EXECUTE mystmt USING 42, 'foobar';

And here is an example from MS SQL Server with Parameter Binding:

   "SELECT * FROM AdventureWorks2014.Production.Product 
   WHERE ProductSubcategoryID = ?",

Less is more

Another solution is to simply remove the functionality all together. You can not hack what is not there.