
workaround di uso generale per la vulnerabilità log4j CVE-2021-44228
Questo progetto fornisce una soluzione generica per la vulnerabilità log4j CVE-2021-44228, che può essere utilizzata nel caso in cui non si abbia l'alternativa a breve termine di ricostruire il proprio progetto o di applicare la patch ai jar log4j-core.
L'idea alla base è piuttosto semplice: forziamo il class loader a caricare una versione "vuota" della classe JndiLookup utilizzando l'opzione java runtime "-Xbootclasspath/a".
Pertanto l'intera soluzione consiste solo in questa singola classe "org.apache.logging.log4j.core.lookup.JndiLookup.java" e non ha altre dipendenze.
C'è anche un pom.xml per comodità per compilare e creare il jar tramite Maven, ma puoi anche fare lo stesso semplicemente usando il tuo JDK preferito, con i comandi "javac" e "jar".
Nota che questa versione vuota della classe "JndiLookup" non può essere compatibile con l'implementazione originale di log4j2, perché fallirebbe in determinate situazioni di caricamento delle classi.
Quando applichi la soluzione, vedrai il seguente messaggio:
"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 continuerà a funzionare senza problemi comunque, solo senza utilizzare alcun JNDI lookup - ci siamo - JNDI lookup è stato disabilitato!
Una volta compilata la classe e creato il file jar, aggiungi l'opzione "-Xbootclasspath/a:" all'inizio del tuo comando Java e punta alla directory in cui hai posizionato il file jar (ad es. log4j-workaround-1.0-SNAPSHOT.jar). Vedi la sezione proof of concept per un esempio di come fare.
Un comando Java a cui applicheresti questo workaround potrebbe avviare qualsiasi cosa (WebLogic, Tomcat, fat jar costruito con Spring, ...).
Puoi ignorare quanto segue se sei interessato solo al workaround, ma non a verificare se funziona davvero.
Per validare l'approccio ho aggiunto una cartella "POC", che contiene un altro progetto Maven. Non ho voluto usare unit test, ma piuttosto restare vicino a configurazioni di produzione, che utilizzano l'avvio esplicito da riga di comando di fat jar o l'avvio di un container come quello Tomcat con cui l'ho validato.
La proof of concept ha due classi, "POC.java" per testare il workaround da riga di comando e "POCServlet.java" per testare lo stesso in un application server.
Entrambi gli scenari provano a loggare "${jndi:ldap://localhost/test}", a causa del quale log4j tenterebbe di connettersi a ldap sul tuo localhost senza il workaround applicato e fallirebbe con connessione rifiutata.
Per eseguire il POC da riga di comando (una volta costruito con Maven):
Vai nella directory "target\log4j-workaround-1.0-SNAPSHOT\WEB-INF" ed esegui (se sei su una riga di comando Windows):
java -Xbootclasspath/a:..\..\..\..\target\log4j-workaround-1.0-SNAPSHOT.jar -classpath classes;lib\* com.github.grimch.log4j_workaround.poc.POC
Per eseguire il POC con Tomcat:
Perché usare "-Xbootclasspath" e non semplicemente mettere il jar del workaround come prima voce nel "classpath" normale? Beh - alcuni container ti permettono di influenzare il class loading in modo tale che i file jar nell'archivio dell'applicazione deployata abbiano preferenza rispetto a quelli nel classpath di sistema. D'altra parte, tutto ciò che è nel bootstrap classpath ha preferenza su tutto il resto.
Se tuttavia sei sicuro di non utilizzare nulla di simile (ad es. "prefer-application-packages" in WebLogic) allora puoi anche optare per l'alternativa "-classpath".