
Allgemeiner Workaround für die log4j-Sicherheitslücke CVE-2021-44228
Dieses Projekt bietet einen allgemeinen Workaround für die log4j CVE-2021-44228-Sicherheitslücke, der verwendet werden kann, falls Sie kurzfristig keine Alternative haben, Ihr jeweiliges Projekt neu zu bauen oder die log4j-core-JARs zu patchen.
Die Idee dahinter ist recht einfach: Wir zwingen den Klassenlader, eine „leere“ Version der Klasse JndiLookup zu laden, indem wir die Java-Laufzeitoption -Xbootclasspath/a verwenden.
Daher besteht der gesamte Workaround nur aus dieser einen Klasse org.apache.logging.log4j.core.lookup.JndiLookup.java und hat keine weiteren Abhängigkeiten.
Es gibt auch eine pom.xml zur Bequemlichkeit, um es mit Maven zu kompilieren und zu einer JAR zu packen, aber Sie können dasselbe auch einfach mit Ihrem bevorzugten JDK und den Befehlen javac und jar tun.
Beachten Sie, dass diese leere Version der Klasse JndiLookup nicht mit der ursprünglichen log4j2-Implementierung kompatibel sein kann, da dies in bestimmten Klassenladesituationen fehlschlagen würde.
Wenn Sie den Workaround anwenden, würden Sie die folgende Meldung sehen:
"WARN JNDI lookup class is not available because this JRE does not support JNDI.
JNDI string lookups will not be available, continuing configuration.
Ignoring java.lang.ClassCastException: class org.apache.logging.log4j.core.lookup.JndiLookup"
Log4j2 wird trotzdem ohne Probleme weiterarbeiten, nur eben ohne JNDI-Lookup – und schon ist JNDI-Lookup deaktiviert!
Sobald Sie die Klasse kompiliert und die JAR-Datei erstellt haben, fügen Sie einfach die Option -Xbootclasspath/a:<Speicherort Ihrer Workaround-JAR> am Anfang Ihres Java-Befehls ein und verweisen Sie auf das Verzeichnis, in dem Sie die JAR-Datei abgelegt haben (z. B. log4j-workaround-1.0-SNAPSHOT.jar). Siehe den Proof-of-Concept-Abschnitt für ein Beispiel, wie das gemacht wird.
Ein Java-Befehl, auf den Sie diesen Workaround anwenden würden, könnte alles Mögliche starten (WebLogic, Tomcat, Fat-JARs von Spring usw.).
Sie können den folgenden Teil ignorieren, wenn Sie nur am Workaround interessiert sind, aber nicht daran, zu überprüfen, ob er wirklich funktioniert.
Um den Ansatz zu validieren, habe ich einen Ordner „POC“ hinzugefügt, der ein weiteres Maven-Projekt enthält. Ich wollte keine Unit-Tests verwenden, sondern mich eher an Produktions-Setups orientieren, die explizites Befehlszeilenstarten von Fat-JARs oder einen Containerstart wie den von Tomcat verwenden, mit dem ich es validiert habe.
Der Proof of Concept hat zwei Klassen: POC.java, um den Workaround auf der Befehlszeile zu testen, und POCServlet.java, um denselben in einem Anwendungsserver zu testen.
Beide Szenarien versuchen, ${jndi:ldap://localhost/test} zu loggen, weshalb log4j ohne angewendeten Workaround versuchen würde, sich per LDAP mit Ihrem lokalen Host zu verbinden, und mit Verbindungsverweigerung fehlschlagen würde.
So führen Sie den Befehlszeilen-POC aus (nachdem Sie ihn in Maven gebaut haben):
Gehen Sie in das Verzeichnis target\log4j-workaround-1.0-SNAPSHOT\WEB-INF und führen Sie dort aus (wenn Sie eine Windows-Befehlszeile verwenden):
java -Xbootclasspath/a:..\..\..\..\target\log4j-workaround-1.0-SNAPSHOT.jar -classpath classes;lib\* com.github.grimch.log4j_workaround.poc.POC
So führen Sie den POC mit Tomcat aus:
log4j-workaround-1.0-SNAPSHOT.war im Tomcat-Verzeichnis webapps bereit.CATALINA_OPTS entsprechend:CATALINA_OPTS=-Xbootclasspath/a:<Pfad-zu-log4j-workaround-1.0-SNAPSHOT.jar>catalina start.http://localhost:8080/log4j-workaround-1.0-SNAPSHOT/POC in Ihrem Browser.catalina.out auf die Meldung „WARN JNDI lookup class is not available ...“.Warum überhaupt -Xbootclasspath verwenden und nicht einfach das Workaround-JAR als ersten Eintrag in den „normalen“ Klassenpfad legen?
Nun – manche Container beeinflussen das Klassenladen so, dass JAR-Dateien in der bereitgestellten Anwendungsarchiven Vorrang vor denselben im Systemklassenpfad haben. Was sich dagegen im Bootstrap-Klassenpfad befindet, hat Vorrang vor allem anderen.
Wenn Sie jedoch sicher sind, dass Sie nichts Vergleichbares verwenden (z. B. prefer-application-packages in WebLogic), dann können Sie auch zur -classpath-Alternative greifen.