Dust after log4shell CVE-2021-44228 vulnerability has already settled – at least I hope that everyone managed to update their software to prevent RCE attacks – therefore I would like to share with you guys my thoughts about the whole situation I observed.
Information about log4j2 vulnerability was initially announced on twitter on Thursday, December 9th along with POC on github. It was said that log4j2 versions since 2.0.0 to 2.14.0 were vulnerable. It was also depending on JVM it was running on. Nevertheless it would be great to get rid of faulty library or at least upgrade it. Hopefully, on Friday, December 10th, Apache team released log4j2 version 2.15.0 which was said to be not vulnerable (actually it still was). So, the fix was pretty fast, wasn’t it? Unfortunately I’ve heard from my developer-colleagues that some them had problems with patching their software against that threat. Come on, It’s just a logging library and not necessarily heart of your software. Perhaps you’ve just asked yourself “why?”. So I have. As usual in our industry – it depends.
* Actually it’s been so far week and a half 😉
Vulnerability patching problems
Well, I’d start trying to answer question – “why log4j2 appeared in our project” – in first place. I believe it will lead us to further going understanding of replacement/upgrade problems. Mainly, there are two reasons:
- you used log4j2 as logging library of your choice – it was your direct decision
- you used a library that was using log4j2 as logging library – it wasn’t your direct decision
While using it directly, it’s your fault how you use it, while indirect usage is not entirely your fault – it’s the author’s.
However, despite of reason how vulnerable library appeared in your project, you as the maintainer have to deal with that.
The only reason – I think – makes you unable to easily replace or upgrade a library you use is relying on specific implementation. In this case it was completely tying up your software with log4j2 API and it’s features.
Depending on implementation.
From my engineering perspective – libraries you use should be for your system like plug-n-play devices. If library does not fit, you should be able to easily unplug it and plug another one as a replacement*.
Consider JPA. If you stick only to JPA, you should be able (at least theoretically) switch between JPA providers seamlessly. You don’t like Hibernate? Well let’s try with EclipseLink. EclipseLink does not fit? It’s time for OpenJPA, and so on.
The same with the database. As long as you avoid native queries and stick to JPQL or at least HQL (if you are using Hibernate) while writing queries you should be able to seamlessly switch between databases. The only effort would be providing proper JDBC Driver. Simple and clever.
As I mentioned in previous paragraph – you could also avoid problems with replacing log4j2 using only SLF4J API.
Imagine that you have wrapped up log4j2 logger into a self made logger class/interface so you don’t rely on log4j2 logger across your software. If you need a replacement you just do that in one place*. I read about that(I believe it was around 2013) in “Clean code” by Robert C. Martin and I was quite shocked at first – I was asking myself – “who the hell would want to wrap a logger into project specific logger class?” – I understood that 2 years later and I understand it now. Even though it seems a bit crazy. If you don’t like that, you could at least use SLF4J as the logging facade so you don’t depend on implementation.
That could have been also your one of the libraries you use that uses log4j2 and therefore it appeared in your project making it vulnerable. If you would have wrapped it or use a facade – you probably wouldn’t struggle with replacing it with different one that provides same functionalities.
* it depends on the purpose of library usage – if it’s features are exotic by it’s nature, it will be hard to find a suitable replacement
* as long as you did not use any logging/resolving feature that is only provided by log4j2 library.
I believe that problems with migration to newer versions of log4j2 or problems with migration to another logging library could have been avoided – simply by wrapping up desired logic in dedicated system component.
Libraries should be easily replaceable. Strongly relying on third-party software implementation leads your system to inevitable state of being not upgradeable sooner or later. Therefore potentially making your software vulnerable. That’s the burden of using third-party software.
Before adding third-party software it’s always good to inspect its dependencies so you don’t end up with unwanted, vulnerable software. Doing small research whether software you are consider using is vulnerable or not would be also great. Perhaps it’s worth using dependency check tool against vulnerabilities – like OWASP Dependency-Check.
Keeping eye on security breach announcements is crucial for your system/organization safety.
Having hermetic network infrastructure with minimum outgoing traffic rules(so your system does not pull malicious code) could have helped avoiding log4j2 RCE vulnerability.
As a software engineer you have to be aware of threats coming from outside your organization.
Again – I think problems with replacing log4j2 could have been avoided – what do you think? Leave a comment below!
Another sad thing is that usage of log4j2 v2.16.0 in comparison to v2.15.0 looks poorly. It means that a lot of libraries out there, still contains vulnerable parts and is potential threat to your system and infrastructure.
Post scriptum #2
Sadly, it appears that fresh log4j2 2.16.0 release was also vulnerable(CVE-2021-45105) and log4j2 2.17.0 was released in the response for recent researchers announcements. Hopefully, mvnrepository.com introduced new column “Vulnerabilities” in the list of available artifact versions – I think this is awesome!
Sadly #2, so far only 25 libraries have already migrated to log4j2 2.17.0.
I would strongly recommend (if you have such possibility) to abandon log4j2 usage and migrate to other logging library – i.e. logback.
Software engineer, technical team leader and entrepreneur. JVM technology enthusiast. Loves digging into framework internals and optimizing bottle-necks.