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.
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: https://www.minecraft.net/download/server
And after the update I see that minecraft
1.18.1 uses log4j
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.
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
You can download the latest version here: https://logging.apache.org/log4j/2.x/download.html
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.
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:
EXEC SQL BEGIN DECLARE SECTION; const char *stmt = "INSERT INTO test1 VALUES(?, ?);"; EXEC SQL END DECLARE SECTION; EXEC SQL PREPARE mystmt FROM :stmt; EXEC SQL EXECUTE mystmt USING 42, 'foobar';
And here is an example from MS SQL Server with Parameter Binding:
SQLExecDirect(hstmt, "SELECT * FROM AdventureWorks2014.Production.Product WHERE ProductSubcategoryID = ?", SQL_NTS);
Less is more
Another solution is to simply remove the functionality all together. You can not hack what is not there.