Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059: Correção de Análise Estática do RCE Atribuído Incorretamente no Apache Ranger | Kitploit
Ferramentas/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoExploraçãoSegurança WebAprendizado e Educação
GitHubpl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction

CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction

CVE-2025-59059: Correção de Análise Estática do RCE Atribuído Incorretamente no Apache Ranger

Ver Repositório
42há 6 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2025-59059: RCE Atribuída Incorretamente no Apache Ranger — uma correção

CVE: CVE-2025-59059
Versões afetadas: Apache Ranger <= 2.7.0
Corrigido em: Apache Ranger 2.8.0
CVSS (oficial): 9.8 Crítica
Severidade real (argumentada): ~6.0 Média — veja análise abaixo


Prefácio

Este artigo não é sobre um novo exploit ou um PoC funcional. O objetivo aqui é corrigir o que está errado na divulgação pública da CVE-2025-59059, especificamente duas coisas: a classe errada foi nomeada como componente vulnerável, e a pontuação CVSS não reflete as restrições reais de explorabilidade. Tudo aqui é baseado na análise estática do código-fonte do Apache Ranger 2.7.0 e no diff do patch que entrou na versão 2.8.0.


O que o aviso diz

O aviso oficial diz:

"Vulnerabilidade de Execução Remota de Código em NashornScriptEngineCreator é relatada no Apache Ranger versões <= 2.7.0."

Isso está errado, ou pelo menos é enganoso. NashornScriptEngineCreator não é a classe vulnerável. Na verdade, é a mais endurecida dos dois componentes relacionados a Nashorn no código — o que veremos a seguir.


Contexto: Nashorn no Apache Ranger

O Apache Ranger usa expressões JavaScript para avaliar políticas de filtro no nível de linha. Essas são regras que decidem se um determinado usuário tem acesso a um registro específico em um conjunto de dados. Para executar essas expressões na JVM, o Ranger incorpora um mecanismo JavaScript. Nas versões <= 2.7.0, esse mecanismo é o Nashorn, o mecanismo JS embutido da Oracle que acompanhava o JDK 8 até o 14.

Uma coisa que o aviso omite completamente — e isso importa muito para dimensionar o impacto — é que jdk.nashorn.api.scripting.NashornScriptEngineFactory não faz parte do código-fonte do Ranger. É um componente embutido do JDK. Foi incluído no JDK 8, descontinuado no JDK 11 e totalmente removido no JDK 15. Portanto, essa vulnerabilidade só é alcançável se você estiver executando o Ranger em JDK 8 a 14. Qualquer ambiente no JDK 15+ não é afetado, pois o Nashorn simplesmente não existe nele, e o ScriptEngineUtil apenas cai silenciosamente para o GraalJS ou JavaScriptEngineCreator.

Duas classes no Ranger usam Nashorn. Elas o tratam de forma muito diferente.


As duas classes relacionadas ao Nashorn

1. NashornScriptEngineCreator — a nomeada, porém mais segura

Localizada em:

agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
public class NashornScriptEngineCreator implements ScriptEngineCreator {

    private static final String[] SCRIPT_ENGINE_ARGS = new String[] {
        "--no-java", "--no-syntax-extensions"
    };

    @Override
    public ScriptEngine getScriptEngine(ClassLoader clsLoader) {
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ret = factory.getScriptEngine(SCRIPT_ENGINE_ARGS, clsLoader, RangerClassFilter.INSTANCE);
        ...
    }

    private static class RangerClassFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String className) {
            LOG.warn("script blocked: attempt to use Java class {}", className);
            return false;
        }
    }
}

Essa classe na verdade faz três coisas para endurecer o mecanismo:

  • --no-java — corta o acesso direto ao namespace java.* de dentro dos scripts
  • --no-syntax-extensions — desabilita a sintaxe não padrão do Nashorn
  • RangerClassFilter — bloqueia todo acesso a classes Java no nível do ClassFilter, retorna false para tudo

É à prova de balas? Não. Existem bypasses do ClassFilter do Nashorn por meio de cadeias de reflexão e truques com java.lang.invoke. Mas é significativamente mais restrito do que o que encontramos na outra classe.


2. RecordFilterJavaScript — a classe realmente vulnerável

Localizada em:

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
public class RecordFilterJavaScript {

    static class SecurityFilter implements ClassFilter {
        @Override
        public boolean exposeToScripts(String s) {
            return false;
        }

        boolean containsMalware(String filterExpr) {
            // only checks for this one specific string
            return filterExpr.contains("this.engine");
        }
    }

    public static boolean filterRow(String user, String filterExpr, String jsonString) {
        SecurityFilter securityFilter = new SecurityFilter();

        if (securityFilter.containsMalware(filterExpr)) {
            throw new MaskingException("cannot process filter expression due to security concern...");
        }

        // instantiates Nashorn directly — no --no-java, no --no-syntax-extensions
        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
        ScriptEngine engine = factory.getScriptEngine(securityFilter);

        String script = " jsonAttr = JSON.parse(jsonString); " + filterExpr;

        Bindings bindings = engine.createBindings();
        bindings.put("jsonString", jsonString);
        bindings.put("user", user);

        boolean hasAccess = (boolean) engine.eval(script, bindings);
        ...
    }
}

Compare isso com NashornScriptEngineCreator e a diferença é bem óbvia:

  • sem a flag --no-java — o namespace java.* está totalmente aberto para scripts
  • sem --no-syntax-extensions
  • a única "segurança" é uma verificação de string: filterExpr.contains("this.engine")
  • filterExpr é concatenado diretamente no script que o Nashorn avalia

Como --no-java não é passado, o namespace java.* fica totalmente acessível. Você não precisa de nenhuma técnica de bypass:

var runtime = java.lang.Runtime.getRuntime();
runtime.exec("id");

Não há this.engine em lugar nenhum. A blacklist é totalmente irrelevante para esse caminho de ataque.

O interessante é que os desenvolvedores claramente conheciam pelo menos um padrão de bypass. O arquivo de teste TestRecordFilterJavaScript.java contém isto:

RecordFilterJavaScript.filterRow("user",
    "this.engine.factory.scriptEngine.eval('java.lang.Runtime.getRuntime().exec(\"/Applications/Spotify.app/Contents/MacOS/Spotify\")')",
    ...);

Esse teste existe para confirmar que this.engine é bloqueado. O que não foi bloqueado é o caminho direto de java.*, que não precisa de this.engine de forma alguma.


O ponto de entrada

RecordFilterJavaScript.filterRow() só é chamado de um lugar:

plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java
private boolean hasAccessToRecord(String schema, String user, ..., String jsonString, ...) {
    RangerAccessResult result = plugin.evalRowFilterPolicies(request, null);

    if (result.isRowFilterEnabled()) {
        String filterExpr = result.getFilterExpr();
        ret = RecordFilterJavaScript.filterRow(user, filterExpr, jsonString);
    }
    return ret;
}

filterExpr vem de result.getFilterExpr() — essa é a expressão JavaScript armazenada em uma política de filtro de linha do Ranger. Um atacante com privilégios de administrador de políticas pode definir essa expressão como quiser. Quando qualquer usuário acessa um recurso regido por essa política, hasAccessToRecord() é acionado, busca filterExpr do armazenamento de políticas e filterRow() a entrega ao Nashorn praticamente sem sandbox.

Cadeia de ataque:

Policy admin access
       |
       v
Create/modify a row filter policy on a nestedstructure resource
       |
       v
filterExpr set to: java.lang.Runtime.getRuntime().exec("...")
       |
       v
Any user accesses the resource → hasAccessToRecord() triggered
       |
       v
filterExpr flows into filterRow() → Nashorn evaluates it → RCE

O diff do patch

Baixar ferramenta