
solução alternativa de propósito geral para a vulnerabilidade log4j CVE-2021-44228
Este projeto fornece uma solução alternativa de propósito geral para a vulnerabilidade log4j CVE-2021-44228, que pode ser usada caso você não tenha a alternativa em curto prazo de reconstruir seu respectivo projeto ou corrigir os jars log4j-core.
A ideia por trás disso é bastante simples: Forçamos o carregador de classes a carregar uma versão "vazia" da classe JndiLookup usando a opção do runtime Java "-Xbootclasspath/a".
Portanto, toda a solução alternativa consiste apenas nesta única classe "org.apache.logging.log4j.core.lookup.JndiLookup.java" e não tem outras dependências.
Há também um pom.xml para conveniência, para compilar e gerar o jar via Maven, mas você também pode fazer o mesmo simplesmente usando seu JDK preferido, com os comandos "javac" e "jar".
Observe que esta versão vazia da classe "JndiLookup" não pode ser compatível com a implementação original do log4j2, pois isso falharia em certas situações de carregamento de classes.
Ao aplicar a solução alternativa, você verá a seguinte mensagem:
"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"
O Log4j2 continuará funcionando sem problemas, apenas sem usar nenhuma consulta JNDI - pronto! A consulta JNDI foi desativada!
Depois de compilar a classe e criar o arquivo jar, basta adicionar a opção "-Xbootclasspath/a:<caminho para o seu jar de solução alternativa>" no início do seu comando Java e apontar para o diretório onde você colocou o arquivo jar (por exemplo, log4j-workaround-1.0-SNAPSHOT.jar). Veja a seção de prova de conceito para um exemplo de como fazer isso.
Um comando java ao qual você aplicaria esta solução alternative poderia iniciar qualquer coisa (Weblgic, Tomcat, fat jar construído pelo Spring, ...).
Você pode ignorar o seguinte se estiver apenas interessado na solução alternativa, mas não em como verificar se realmente funciona.
Para validar a abordagem, adicionei uma pasta "POC", que contém outro projeto Maven. Não quis usar testes unitários, mas sim me manter próximo de configurações de produção, que usam inicialização explícita de fat jars via linha de comando ou um contêiner como o Tomcat com o qual validei.
A prova de conceito tem duas classes, "POC.java" para testar a solução alternativa na linha de comando e "POCServlet.java" para testar o mesmo em um servidor de aplicações.
Ambos os cenários tentam registrar "${jndi:ldap://localhost/test}", devido ao qual o log4j tentaria conectar ao ldap no seu host local sem a solução alternativa aplicada e falharia com conexão recusada.
Para executar a POC de linha de comando (depois de construí-la no Maven):
Vá para o diretório "target\log4j-workaround-1.0-SNAPSHOT\WEB-INF" e execute (se estiver em uma linha de comando do Windows):
java -Xbootclasspath/a:..\..\..\..\target\log4j-workaround-1.0-SNAPSHOT.jar -classpath classes;lib\* com.github.grimch.log4j_workaround.poc.POC
Para executar a POC com Tomcat:
Por que usar "-Xbootclasspath" em vez de apenas colocar o jar da solução alternativa como a primeira entrada no "classpath" normal? Bem - alguns contêineres permitem que você influencie o carregamento de classes de forma que arquivos jar no arquivo de aplicação implantado tenham preferência sobre os mesmos no classpath do sistema. Por outro lado, o que está no bootstrap classpath tem preferência sobre todo o resto.
Se você tem certeza de que não está usando nada disso (por exemplo, "prefer-application-packages" no Weblogic"), então você também pode optar pela alternativa "-classpath".