flawopen.com/Incidents/log4shell-jndi-injection-december-2021
Log4Shell (CVE-2021-44228): causa e correção
O CVE-2021-44228 permitia que dados registrados acionassem lookups do Log4j 2 e carregamento via JNDI. Atualize o Log4j e inventarie cópias embutidas.[1], [2], [4]
Um escritório tem um funcionário cuja única tarefa é anotar o que os visitantes dizem. Alguém descobre que, se um visitante disser certa frase, o funcionário para de anotar, vai até um endereço citado na frase, pega um envelope lacrado de um desconhecido e segue as instruções que estão dentro. O funcionário só deveria anotar.[1]
Conceitos Centrais e Termos
Lookups de mensagem- Um recurso do Log4j 2 que substituía expressões ${...} dentro das mensagens de log por valores na hora do registro. Antes da 2.15.0, isso valia também para os dados dentro da mensagem, não só para o padrão configurado.[1]
JNDI- Java Naming and Directory Interface, uma API para buscar objetos em serviços de diretório como o LDAP. Um lookup JNDI num servidor remoto podia devolver uma classe para a JVM carregar.[1]
Injeção de expressão (CWE-917)- Dados não confiáveis chegam a um avaliador de expressões, e um texto fornecido como dado é executado como instrução.[1]
Dependência transitiva- Uma biblioteca que a aplicação inclui só porque outra biblioteca depende dela. Muitas exposições ao Log4Shell vieram de cópias do Log4j que ninguém havia listado.[4]
Mapeamentos de frameworks
- Referência CWE para a fraqueza descrita neste guia: CWE-20 CWE-502 CWE-917
- D3-OTF Filtragem de tráfego de saída — A restrição de rede de saída deste guia limita os destinos que o serviço ou host pode alcançar.
- CISA KEV — adicionado em 2021-12-10 — CVE-2021-44228
Linha do Tempo do Incidente
Chen Zhaojun, da Alibaba Cloud Security, relata a falha de forma privada à Apache.[1]
A CISA emite a Emergency Directive 22-02, exigindo que os órgãos federais dos EUA localizem e mitiguem o Log4j.[3]
O Log4j 2.17.1 corrige a CVE-2021-44832, a última de três CVEs posteriores à 2.15.0 (CVE-2021-45046 e CVE-2021-45105).[1]
Fluxo de Ataque Passo a Paso
Um texto do atacante chega a uma chamada de log
Qualquer valor que a aplicação registre, como nome de usuário, cabeçalho ou termo de busca, pode trazer uma expressão de lookup escolhida pelo atacante.[1]
Código-Fonte: Vulnerável vs. Seguro
Configuração Maven ilustrativa. Importar o log4j-bom faz todos os módulos do Log4j, inclusive cópias trazidas por outras bibliotecas, se resolverem numa única versão atual. A regra do enforcer então reprova o build se algum log4j-core anterior à 2.17.1 ainda estiver acessível, inclusive de forma transitiva, para que uma nova dependência não reintroduza em silêncio o código vulnerável. Atualizar é a correção de fato; bloquear LDAP e RMI de saída nos servidores de aplicação é a defesa em profundidade que interrompeu a exploração mesmo onde o patch atrasou.
<!-- pom.xml: a direct dependency pinned to a vulnerable release -->
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<!-- Nothing stops another library from pulling in an older log4j-core transitively. -->
<!-- pom.xml: one version for every Log4j module, and a build that fails on old ones -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.24.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>ban-vulnerable-log4j</id>
<goals><goal>enforce</goal></goals>
<configuration>
<rules>
<bannedDependencies>
<searchTransitive>true</searchTransitive>
<excludes>
<exclude>org.apache.logging.log4j:log4j-core:[2.0-beta9,2.17.1)</exclude>
</excludes>
</bannedDependencies>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Lista de Verificação de Segurança para Engenharia
- ✓Atualize o log4j-core para 2.17.1 ou posterior (2.12.4 no Java 7, 2.3.2 no Java 6) e reprove builds que resolvam uma versão mais antiga em qualquer ponto da árvore de dependências.[1]
- ✓Gere um SBOM a cada build e guarde-o junto com o artefato, para que um aviso futuro seja cruzado com os serviços afetados em minutos.[4], [3]
- ✓Analise os artefatos implantados, não só os repositórios de código: JARs sombreados e empacotados esconderam o Log4j dos manifestos de dependências em muitos produtos.[4]
- ✓Aplique egress com negação por padrão aos servidores de aplicação; a exploração exigia LDAP, RMI e DNS de saída para hosts arbitrários.[4], [3]
- ✓Quando uma falha estrutural é corrigida, espere CVEs posteriores e mantenha o incidente aberto até as correções do fornecedor se estabilizarem.[1]
Fontes
- Apache Log4j — vulnerabilidades de segurança (CVE-2021-44228 e posteriores)
- CVE-2021-44228 — registro CVE
- CISA — Emergency Directive 22-02: mitigar a vulnerabilidade do Apache Log4j
- CISA — orientações sobre a vulnerabilidade do Apache Log4j
- O ObjectInputStream do Java é seguro com dados não confiáveis?
- Injeção de comandos — referência completa da classe