Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2025-59059-Misattributed-RCE-in-Apache-Ranger-Static-Analysis-Correction — CVE-2025-59059: Attribuzione errata di RCE nella correzione dell'analisi statica di Apache Ranger | Kitploit
Strumenti/GitHubGitHub/pl4tyz/cve-2025-59059-misattributed-rce-in-apache-ranger-static-analysis-correction
Analisi StaticaAnalisi delle VulnerabilitàAnalisi del CodiceExploitSicurezza WebApprendimento e Formazione
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: Attribuzione errata di RCE nella correzione dell'analisi statica di Apache Ranger

Vedi Repository
155 mesi faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2025-59059: RCE attribuita in modo errato in Apache Ranger – una correzione

CVE: CVE-2025-59059
Versioni interessate: Apache Ranger <= 2.7.0
Corretto in: Apache Ranger 2.8.0
CVSS (ufficiale): 9.8 Critico
Gravità effettiva (argomentata): ~6.0 Media — vedi analisi sotto


Prefazione

questo articolo non riguarda un nuovo exploit o un PoC funzionante. il punto è correggere ciò che non va nella divulgazione pubblica di CVE-2025-59059, in particolare due cose: è stata indicata la classe sbagliata come componente vulnerabile, e il punteggio CVSS non riflette i reali vincoli di sfruttabilità. tutto ciò si basa sull'analisi statica del codice sorgente di Apache Ranger 2.7.0 e sul diff della patch integrata in 2.8.0.


Cosa dice l'avviso

l'avviso ufficiale recita:

"Remote Code Execution Vulnerability in NashornScriptEngineCreator è segnalata in Apache Ranger versioni <= 2.7.0."

questo è sbagliato, o quantomeno fuorviante. NashornScriptEngineCreator non è la classe vulnerabile. semmai è quella più robusta tra i due componenti Nashorn presenti nel codice — come vedremo.


Contesto: Nashorn in Apache Ranger

Apache Ranger utilizza espressioni JavaScript per valutare le policy di filtro a livello di riga. si tratta di regole che decidono se un determinato utente può accedere a un record specifico in un dataset. Per eseguire effettivamente tali espressioni sulla JVM, Ranger incorpora un motore JavaScript. nelle versioni <= 2.7.0 quel motore è Nashorn, il motore JS integrato di Oracle fornito con JDK 8 fino a 14.

una cosa che l'avviso omette completamente — e questo conta molto per la delimitazione dell'impatto — è che jdk.nashorn.api.scripting.NashornScriptEngineFactory non fa affatto parte del codice sorgente di Ranger. è un componente integrato del JDK. è stato incluso in JDK 8, deprecato in JDK 11 e rimosso completamente in JDK 15. quindi questa vulnerabilità è sfruttabile solo se si esegue Ranger su JDK 8–14. qualsiasi cosa su JDK 15+ non è interessata perché Nashorn semplicemente non esiste, e ScriptEngineUtil passa silenziosamente a GraalJS o JavaScriptEngineCreator.

due classi in Ranger utilizzano Nashorn. lo trattano in modo molto diverso.


Le due classi correlate a Nashorn

1. NashornScriptEngineCreator — quella nominata ma più sicura

posizionata in:

root@kitploit:~
agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
root@kitploit:~
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 bloccato: tentativo di usare la classe Java {}", className);
            return false;
        }
    }
}

questa classe in realtà fa tre cose per indurire il motore:

  • --no-java — taglia l'accesso diretto al namespace java.* dagli script
  • --no-syntax-extensions — disabilita le estensioni sintattiche non standard di Nashorn
  • RangerClassFilter — blocca ogni accesso alle classi Java a livello di ClassFilter, restituisce false per tutto

è a prova di proiettile? no. esistono bypass di Nashorn ClassFilter attraverso catene di reflection e trucchi con java.lang.invoke. ma è significativamente più bloccato rispetto a ciò che troviamo nell'altra classe.


2. RecordFilterJavaScript — la classe effettivamente vulnerabile

posizionata in:

root@kitploit:~
plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
root@kitploit:~
public class RecordFilterJavaScript {

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

        boolean containsMalware(String filterExpr) {
            // controlla solo questa specifica stringa
            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("impossibile elaborare l'espressione di filtro per motivi di sicurezza...");
        }

        // istanzia Nashorn direttamente — senza --no-java, senza --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);
        ...
    }
}

confrontandola con NashornScriptEngineCreator la differenza è piuttosto evidente:

  • nessun flag --no-java: il namespace java.* è completamente aperto agli script
  • nessun --no-syntax-extensions
  • l'unica "sicurezza" è un controllo su una stringa: filterExpr.contains("this.engine")
  • filterExpr viene concatenato direttamente nello script che Nashorn valuta

poiché --no-java non è passato, il namespace java.* è completamente accessibile. non è necessaria alcuna tecnica di bypass:

root@kitploit:~
var runtime = java.lang.Runtime.getRuntime();
runtime.exec("id");

nessun this.engine qui. la blacklist è completamente irrilevante per questo percorso d'attacco.

ciò che è interessante è che gli sviluppatori erano chiaramente a conoscenza di almeno un modello di bypass. il file di test TestRecordFilterJavaScript.java contiene quanto segue:

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

quel test esiste per confermare che this.engine viene bloccato. ciò che non è stato bloccato è il percorso diretto java.*, che non necessita affatto di this.engine.


Il punto di ingresso

RecordFilterJavaScript.filterRow() viene chiamato solo da un punto:

root@kitploit:~
plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/NestedStructureAuthorizer.java
root@kitploit:~
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 proviene da result.getFilterExpr(): è l'espressione JavaScript memorizzata in una policy di filtro righe di Ranger. un attaccante con privilegi di amministratore delle policy può impostare quell'espressione a piacere. quando un qualsiasi utente accede successivamente a una risorsa governata da quella policy, hasAccessToRecord() si attiva, recupera filterExpr dall'archivio delle policy e filterRow() la passa a Nashorn praticamente senza sandboxing.

Catena d'attacco:

root@kitploit:~
Accesso come amministratore delle policy
       |
       v
Creare/modificare una policy di filtro righe su una risorsa nestedstructure
       |
       v
filterExpr impostata a: java.lang.Runtime.getRuntime().exec("...")
       |
       v
Qualsiasi utente accede alla risorsa → hasAccessToRecord() attivato
       |
       v
filterExpr fluisce in filterRow() → Nashorn la valuta → RCE

Il diff della patch

la correzione è tracciata come RANGER-4076: Remove Nashorn Script Engine, commit effettuato l'8 dicembre 2025 da Kishor Gollapalliwar. recuperato dall'archivio dei commit della mailing list Apache. tre file modificati, 27 inserimenti, 81 cancellazioni.

root@kitploit:~
commit 923a8473de2985cd389d45062cd4717d5ca13235
Author: Kishor Gollapalliwar
AuthorDate: Mon Dec 8 14:55:56 2025 +0530

    RANGER-4076: Rimuovere Nashorn Script Engine

 .../plugin/util/NashornScriptEngineCreator.java    | 67 ----------------------
 .../ranger/plugin/util/ScriptEngineUtil.java       |  7 +--
 .../authorizer/RecordFilterJavaScript.java         | 34 ++++++++---
 3 files changed, 27 insertions(+), 81 deletions(-)

File 1: NashornScriptEngineCreator.java eliminato completamente

root@kitploit:~
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
deleted file mode 100644
index b890fe85d..000000000
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/NashornScriptEngineCreator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.apache.ranger.plugin.util;
-
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
-
-public class NashornScriptEngineCreator implements ScriptEngineCreator {
-
-    private static final String[] SCRIPT_ENGINE_ARGS = new String[] {
-        "--no-java", "--no-syntax-extensions"
-    };
-    private static final String ENGINE_NAME = "NashornScriptEngine";
-
-    @Override
-    public ScriptEngine getScriptEngine(ClassLoader clsLoader) {
-        ScriptEngine ret = null;
-        if (clsLoader == null) {
-            clsLoader = getDefaultClassLoader();
-        }
-        try {
-            NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
-            ret = factory.getScriptEngine(SCRIPT_ENGINE_ARGS, clsLoader, RangerClassFilter.INSTANCE);
-        } catch (Throwable t) {
-            LOG.debug("NashornScriptEngineCreator.getScriptEngine(): impossibile creare il motore tipo {}", ENGINE_NAME, t);
-        }
-        return ret;
-    }
-
-    private static class RangerClassFilter implements ClassFilter {
-        static final RangerClassFilter INSTANCE = new RangerClassFilter();
-
-        @Override
-        public boolean exposeToScripts(String className) {
-            LOG.warn("script bloccato: tentativo di usare la classe Java {}", className);
-            return false;
-        }
-    }
-}

File 2: ScriptEngineUtil.java Nashorn rimosso dalla catena dei creatori di motori

root@kitploit:~
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ScriptEngineUtil.java
@@ -28,10 +28,9 @@
 public class ScriptEngineUtil {

-    private static final String   SCRIPT_ENGINE_CREATOR_NASHHORN =
-        "org.apache.ranger.plugin.util.NashornScriptEngineCreator";
     private static final String   SCRIPT_ENGINE_CREATOR_GRAAL    =
         "org.apache.ranger.plugin.util.GraalScriptEngineCreator";
     private static final String   SCRIPT_ENGINE_CREATOR_JS       =
         "org.apache.ranger.plugin.util.JavaScriptEngineCreator";
-    private static final String[] SCRIPT_ENGINE_CREATORS = new String[] {
-        SCRIPT_ENGINE_CREATOR_NASHHORN,
-        SCRIPT_ENGINE_CREATOR_GRAAL,
-        SCRIPT_ENGINE_CREATOR_JS
-    };
+    private static final String[] SCRIPT_ENGINE_CREATORS = new String[] {
+        SCRIPT_ENGINE_CREATOR_GRAAL,
+        SCRIPT_ENGINE_CREATOR_JS
+    };

@@ -108,9 +107,7 @@ private static void initScriptEngineCreator(String serviceType) {
         } catch (Throwable t) {
             boolean logWarn;

-            if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_NASHHORN)) {
-                logWarn = JVM_MAJOR_CLASS_VERSION < JVM_MAJOR_CLASS_VERSION_JDK15;
-            } else if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_GRAAL)) {
+            if (creatorClsName.equals(SCRIPT_ENGINE_CREATOR_GRAAL)) {
                 logWarn = JVM_MAJOR_CLASS_VERSION >= JVM_MAJOR_CLASS_VERSION_JDK15;
             } else {
                 logWarn = true;

File 3: RecordFilterJavaScript.java — la vera correzione

qui è dove avviene il vero cambiamento di sicurezza. la chiamata diretta a NashornScriptEngineFactory viene sostituita con GraalJS, e SecurityFilter perde completamente il suo ruolo di ClassFilter – viene declassato a una classe normale con solo il controllo sulla stringa.

root@kitploit:~
diff --git a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
--- a/plugin-nestedstructure/.../RecordFilterJavaScript.java
+++ b/plugin-nestedstructure/.../RecordFilterJavaScript.java
@@ -18,13 +18,16 @@
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineManager;
+import java.util.HashMap;
+import java.util.Map;

@@ -54,8 +57,25 @@
         if (securityFilter.containsMalware(filterExpr)) {
             throw new MaskingException("impossibile elaborare l'espressione di filtro...");
         }

-        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
-        ScriptEngine engine = factory.getScriptEngine(securityFilter);
+        ClassLoader clsLoader = Thread.currentThread().getContextClassLoader();
+        ScriptEngineManager mgr = new ScriptEngineManager(clsLoader);
+        ScriptEngine engine = mgr.getEngineByName("graal.js");
+
+        if (engine != null) {
+            try {
+                Map<String, Boolean> graalVmConfigs = new HashMap<>();
+                graalVmConfigs.put("polyglot.js.allowHostAccess", Boolean.TRUE);
+                graalVmConfigs.put("polyglot.js.nashorn-compat", Boolean.TRUE);
+
+                Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+                bindings.putAll(graalVmConfigs);
+                engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
+            } catch (Throwable t) {
+                logger.debug("RecordFilterJavaScript.filterRow(): impossibile creare il motore tipo {}", "graal.js", t);
+            }
+        }

@@ -83,12 +103,8 @@
-    static class SecurityFilter implements ClassFilter {
-        @Override
-        public boolean exposeToScripts(String s) {
-            return false;
-        }
-
+    static class SecurityFilter {
         boolean containsMalware(String filterExpr) {
             return filterExpr.contains("this.engine");
         }
     }

alcune cose degne di nota da questo diff:

  • SecurityFilter non è più un ClassFilter – perde il suo hook a livello di motore e diventa solo una classe normale con il solo controllo sulla stringa
  • le import di Nashorn sono scomparse, sostituite da ScriptEngineManager
  • GraalJS viene eseguito in modalità nashorn-compat per la compatibilità con le espressioni di policy esistenti
  • polyglot.js.allowHostAccess è impostato su true – questo è un compromesso per la compatibilità, si affida alla sandbox di GraalJS piuttosto che a un ClassFilter. vale la pena tenerlo d'occhio se ci interessa la qualità della correzione

la patch chiarisce che RecordFilterJavaScript era il bersaglio di sicurezza effettivo. eliminare NashornScriptEngineCreator è stata una pulizia, non la correzione.


Perché il CVE ha nominato la classe sbagliata

onestamente non è difficile capire come sia successo. NashornScriptEngineCreator si trova proprio in agents-common, è la classe Nashorn più ovvia in tutto il codebase, e una semplice grep per Nashorn la farebbe emergere immediatamente. RecordFilterJavaScript invece si trova in plugin-nestedstructure, che è un sottomodulo separato, e non c'è nulla nel nome della classe che suggerisca Nashorn. se qualcuno ha fatto un triage rapido senza seguire effettivamente il percorso del codice, probabilmente si sarebbe fermato su NashornScriptEngineCreator.

sembra essere ciò che è successo qui. la classe vulnerabile e la classe nominata nell'avviso sono due cose diverse.


Perché il CVSS 9.8 non regge

un 9.8 implica accessibile in rete, nessuna autenticazione richiesta, nessuna interazione con l'utente. la realtà è ben diversa:

FattoreRealtà
Autenticazionerichiede privilegi di amministratore delle policy in Ranger
Plugin richiestoplugin-nestedstructure non è abilitato per impostazione predefinita
Vincolo JDKsfruttabile solo su JDK 8–14, JDK 15+ non è interessato
Esposizione di reteIl fingerprinting FOFA ha restituito circa 35 istanze Ranger pubbliche

niente di tutto ciò è riflesso nell'avviso. per sfruttare effettivamente questa vulnerabilità è necessario l'accesso come amministratore delle policy, che è un livello di privilegio significativo all'interno di un deployment Ranger. non si tratta di RCE non autenticato. considerando il requisito di autenticazione e il plugin non predefinito, un punteggio nell'intervallo 6.0–7.0 sarebbe più onesto.


Riepilogo

Affermazione dell'avvisoRiscontro effettivo
Classe vulnerabileNashornScriptEngineCreatorRecordFilterJavaScript
Tipo di attaccoRCE non autenticatoRCE autenticato (amministratore policy richiesto)
JDK interessatoNon specificatoSolo JDK 8–14
Plugin richiestoNon specificatoplugin-nestedstructure (non predefinito)
CVSS9.8 Critico~6.0 Medio (argomentato)
Esposizione InternetNon specificata~35 istanze (FOFA)

la vulnerabilità è reale e l'aggiornamento alla 2.8.0 è la scelta giusta. ma l'avviso sbaglia la classe e il punteggio di gravità non riflette ciò che è effettivamente necessario per sfruttarla.


Riferimenti

  • Apache Ranger 2.8.0 release: https://ranger.apache.org/download.html
  • Commit della patch (RANGER-4076): https://gitbox.apache.org/repos/asf/ranger.git
  • Voce CVE: https://www.cve.org/CVERecord?id=CVE-2025-59059
  • Thread della mailing list Apache: https://lists.apache.org/thread/z47q86rho80390lf2qcmoc2josvs0gtv
Scarica lo strumento