CVE-2012-0391
Corrija agora. Ela está sob exploração confirmada pelo CISA e tem exploit funcional público.
Apply updates per vendor instructions.
Resumo
Falha de injeção OGNL no Apache Struts 2, anterior à versão 2.2.3.1, que permite execução remota de código sem autenticação quando o framework trata um erro de conversão de tipo em um campo de formulário. Afeta qualquer aplicação Struts 2 que use os interceptors padrão de conversão/validação e exponha um campo tipado (ex.: Integer) a entrada do usuário — ou seja, a maioria das aplicações Struts 2 da época. Está no catálogo KEV da CISA desde 2022, o que indica exploração continuada em sistemas legados ainda expostos.
Detalhamento técnico
O problema está no ConversionErrorInterceptor e no RepopulateConversionErrorFieldValidatorSupport (com.opensymphony.xwork2). Quando o Struts tenta popular uma propriedade tipada (por exemplo, um campo Integer) com um valor de parâmetro HTTP que não pode ser convertido para aquele tipo, o framework precisa 'repopular' o campo com o valor original para reexibir o formulário. Para isso, o código concatena o valor bruto do usuário dentro de aspas simples — return "'" + value + "'"; — e esse valor volta a ser processado como expressão OGNL.
O defeito é um caso clássico de validação de entrada insuficiente (CWE-20): o valor nunca é sanitizado antes de ser reinjetado no motor OGNL. Como o parser OGNL do Struts nessa época já permitia navegar por variáveis de contexto (#application, #context, #session) e, a partir delas, alcançar chamadas de método Java, um atacante que conseguisse 'escapar' das aspas simples inseridas pelo interceptor recuperava capacidade de expressão OGNL arbitrária dentro do contexto da aplicação.
A falha foi documentada pelos mantenedores no ticket WW-3668, reproduzida no exemplo 'Struts Showcase' (Validation > Field Validators > Integer Validator Field), injetando uma string como '' no campo — o que já bastava para vazar variáveis de escopo application. A correção original mudou o tratamento em ConversionErrorInterceptor e RepopulateConversionErrorFieldValidatorSupport para não reprocessar o valor como OGNL.
O atacante controla integralmente o valor do parâmetro HTTP; o único pré-requisito estrutural é que esse parâmetro esteja mapeado para uma propriedade de tipo diferente de String (Integer, Long, Date etc.), o que força o interceptor de conversão a entrar no caminho de erro vulnerável.
Como é explorada
O vetor é um parâmetro HTTP comum (GET ou POST) de uma aplicação Struts 2 que usa o interceptor stack padrão, que inclui o ConversionErrorInterceptor. Não é necessária autenticação nem configuração fora do padrão — o comportamento vulnerável está ativo por default em qualquer ação que tenha uma propriedade tipada exposta a input do usuário. O atacante envia um valor malformado para esse campo, provocando o erro de conversão, e usa a sintaxe do valor para fechar a string entre aspas simples inserida pelo framework e anexar uma expressão OGNL adicional.
A complexidade de exploração é baixa: existe PoC pública (Exploit-DB), módulo Metasploit e o próprio caso de teste documentado pelos mantenedores no Struts Showcase, o que tornou a falha trivial de automatizar. O resultado final, quando a expressão OGNL alcança métodos Java como Runtime.exec, é execução arbitrária de código no contexto do processo da aplicação — o CVSS 9.8 reflete corretamente esse alcance.
A presença no catálogo KEV da CISA (adicionada em 2022, dez anos após a publicação) confirma exploração ativa continuada, tipicamente contra instâlações legadas de Struts 2 nunca atualizadas — não indica uma nova onda de descoberta, mas a persistência de alvos vulneráveis na internet.
Versões
Como se proteger
A correção do fornecedor está na versão 2.2.3.1. Entretanto, o próprio boletim S2-008 da Apache observa que essa correção pontual não fechou todo o vetor de execução de código via OGNL nesse fluxo de tratamento de exceções — outras variantes relacionadas (CVE-2012-0392/0393/0394) só foram endereçadas com a whitelist de nomes de parâmetro (acceptedParamNames) e outras restrições introduzidas até a 2.3.18. Por isso a recomendação prática é atualizar para 2.3.18 ou superior, não apenas para 2.2.3.1.
Se a atualização imediata não for viável, não existe um paliativo de configuração documentado pelo fornecedor que neutralize especificamente esse vetor do ConversionErrorInterceptor sem alterar código-fonte — a mitigação real é a atualização de versão. Um WAF pode reduzir a superfície bloqueando padrões OGNL óbvios em parâmetros (uso de aspas simples seguidas de operadores OGNL, referências a #application/#context/#session, chamadas com @java.lang), mas isso é detecção de assinatura, não correção, e pode ser contornado por variações de sintaxe.
O que não funciona: acreditar que apenas restringir métodos estáticos (allowStaticMethodAccess=false) ou aplicar o filtro de nomes de parâmetro do ParameterInterceptor resolve esse caso específico — esses controles endereçam as variantes relacionadas descritas no S2-008 (CookieInterceptor, ParameterInterceptor), não o caminho do ConversionErrorInterceptor, que é corrigido apenas na lógica interna a partir da 2.2.3.1.
Como detectar
Em logs de aplicação ou WAF, procure por parâmetros HTTP contendo aspas simples seguidas de sintaxe OGNL — sequências como ' + #application, ' + #context, ' + #session, ou referências a @java.lang.Runtime/@java.lang.ProcessBuilder — enviadas para campos que normalmente esperam valores numéricos ou de data. Erros de conversão de tipo registrados pelo Struts (ConversionErrorInterceptor) correlacionados com esses padrões de parâmetro são um indicador forte de tentativa de exploração.
Não há um único indicador de rede confiável isolado, porque o vetor é um parâmetro de formulário legítimo do ponto de vista de protocolo — a diferenciação depende do conteúdo do payload, não do endpoint ou método HTTP usado.