This is an automated email from the ASF dual-hosted git repository.

vyommani pushed a commit to branch ranger-2.10
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.10 by this push:
     new c03beac49 RANGER-5818: Use the common hardened script engine for 
nestedstructure row-filter evaluation (#1282)
c03beac49 is described below

commit c03beac49b6a3b907581d495fa677bdbdc260e1a
Author: Vyom Mani Tiwari <[email protected]>
AuthorDate: Mon Oct 5 15:22:52 2026 +0530

    RANGER-5818: Use the common hardened script engine for nestedstructure 
row-filter evaluation (#1282)
---
 .../policyengine/RangerRequestScriptEvaluator.java |  3 +-
 .../ranger/plugin/util/ScriptEngineUtil.java       |  6 ++++
 .../authorizer/RecordFilterJavaScript.java         | 34 +++++++++-------------
 .../authorizer/TestRecordFilterJavaScript.java     | 11 ++++---
 4 files changed, 29 insertions(+), 25 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
index 437b89751..7dc7fc30e 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerRequestScriptEvaluator.java
@@ -32,6 +32,7 @@
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerTimeRangeChecker;
 import org.apache.ranger.plugin.util.RangerUserStore;
+import org.apache.ranger.plugin.util.ScriptEngineUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -160,7 +161,7 @@ public final class RangerRequestScriptEvaluator {
     private static final String  DEFAULT_RANGER_TAG_ATTRIBUTE_DATE_FORMAT     
= "yyyy/MM/dd";
     private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT_NAME 
= "ATLAS_DATE_FORMAT";
     private static final String  DEFAULT_ATLAS_TAG_ATTRIBUTE_DATE_FORMAT      
= "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
-    private static final String  SCRIPT_SAFE_PREEXEC                          
= 
"Object.defineProperty(this,'engine',{value:null,writable:false});Object.defineProperty(this,'context',{value:null,writable:false});Object.defineProperty(this,'__noSuchProperty__',{value:null,writable:false});Object.defineProperty(this,'loadWithNewGlobal',{value:null,writable:false});exit=null;quit=null;";
+    private static final String  SCRIPT_SAFE_PREEXEC                          
= ScriptEngineUtil.SCRIPT_SAFE_PREEXEC;
     private static final String  SCRIPT_PREEXEC                               
= SCRIPT_VAR__CTX + "=JSON.parse(" + SCRIPT_VAR__CTX_JSON + "); 
J=JSON.stringify;" +
             SCRIPT_VAR_REQ + "=" + SCRIPT_VAR__CTX + "." + 
SCRIPT_FIELD_REQUEST + ";" +
             SCRIPT_VAR_RES + "=" + SCRIPT_VAR_REQ + "." + 
SCRIPT_FIELD_RESOURCE + ";" +
diff --git 
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
index 1d0194e34..cbafb5392 100644
--- 
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
@@ -31,6 +31,12 @@
 public class ScriptEngineUtil {
     private static final Logger LOG = 
LoggerFactory.getLogger(RangerScriptConditionEvaluator.class);
 
+    /**
+     * Evaluated before a policy-condition or row-filter script, on the same 
bindings as that script.
+     * Supplements the engine from {@link NashornScriptEngineCreator} or 
{@link GraalScriptEngineCreator}.
+     */
+    public static final String SCRIPT_SAFE_PREEXEC = 
"Object.defineProperty(this,'engine',{value:null,writable:false});Object.defineProperty(this,'context',{value:null,writable:false});Object.defineProperty(this,'__noSuchProperty__',{value:null,writable:false});Object.defineProperty(this,'loadWithNewGlobal',{value:null,writable:false});exit=null;quit=null;";
+
     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";
diff --git 
a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
 
b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
index 77767767c..926e8a4ac 100644
--- 
a/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
+++ 
b/plugin-nestedstructure/src/main/java/org/apache/ranger/authorization/nestedstructure/authorizer/RecordFilterJavaScript.java
@@ -20,8 +20,8 @@
 
 package org.apache.ranger.authorization.nestedstructure.authorizer;
 
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import org.apache.ranger.plugin.util.NashornScriptEngineCreator;
+import org.apache.ranger.plugin.util.ScriptEngineUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -29,7 +29,8 @@
 import javax.script.ScriptEngine;
 
 /**
- * Executes an injected javascript command to determine if the user has access 
to the selected record
+ * Executes a row-filter expression to determine if the user has access to the 
selected record.
+ * The engine is created by {@link NashornScriptEngineCreator}, the same 
configuration policy-condition scripts use.
  */
 public class RecordFilterJavaScript {
     private static final Logger logger = 
LoggerFactory.getLogger(RecordFilterJavaScript.class);
@@ -46,31 +47,21 @@ public class RecordFilterJavaScript {
             "&& isNaN(x) && isNaN(y)); } while (k < len) { if 
(sameValueZero(o[k], valueToFind)) { return true; } k++; }" +
             " return false; } }); }";
 
-
     /**
-     * This class filter prevents javascript from importing, using or 
reflecting any java classes
-     * Helps keep javascript clean of injections.  It also contains other 
checks to ensure that injected
-     * javascript is reasonably safe.
+     * Checks applied before evaluation, in addition to the engine 
configuration.
      */
-    static class SecurityFilter implements ClassFilter {
-        @Override
-        public boolean exposeToScripts(String s) {
-            return false;
-        }
-
+    static class SecurityFilter {
         /**
-         *
-          * @param filterExpr the javascript to check if it contains 
potentially harmful commands
+         * @param filterExpr the javascript to check if it contains 
potentially harmful commands
          * @return if this script is likely bad
          */
-        boolean containsMalware(String filterExpr){
+        boolean containsMalware(String filterExpr) {
             //this.engine is the javascript notation for getting access to 
runtime that is executing the script
             //more checks can be added here
             return filterExpr.contains("this.engine");
         }
     }
 
-
     public static boolean filterRow(String user, String filterExpr, String 
jsonString) {
         SecurityFilter securityFilter = new SecurityFilter();
 
@@ -78,15 +69,18 @@ public static boolean filterRow(String user, String 
filterExpr, String jsonStrin
             throw new MaskingException("cannot process filter expression due 
to security concern \"this.engine\": " + filterExpr);
         }
 
-        NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
-        ScriptEngine               engine  = 
factory.getScriptEngine(securityFilter);
+        ScriptEngine engine = new 
NashornScriptEngineCreator().getScriptEngine(null);
+
+        if (engine == null) {
+            throw new MaskingException("unable to evaluate filter expression: 
script engine is not available");
+        }
 
         if (logger.isDebugEnabled()) {
             logger.debug("filterExpr: " + filterExpr);
         }
 
         // convert the given JSON string to JavaScript object, which the 
filterExpr expects, and then exec the filterExpr
-        String script = " jsonAttr = JSON.parse(jsonString); " + 
NASHORN_POLYFILL_ARRAY_PROTOTYPE_INCLUDES + " " + filterExpr;
+        String script = ScriptEngineUtil.SCRIPT_SAFE_PREEXEC + " jsonAttr = 
JSON.parse(jsonString); " + NASHORN_POLYFILL_ARRAY_PROTOTYPE_INCLUDES + " " + 
filterExpr;
 
         try {
             Bindings bindings = engine.createBindings();
diff --git 
a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java
 
b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java
index 9cb161b8d..60d0b3f16 100644
--- 
a/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java
+++ 
b/plugin-nestedstructure/src/test/java/org/apache/ranger/authorization/nestedstructure/authorizer/TestRecordFilterJavaScript.java
@@ -41,12 +41,15 @@ public void testAccessJava() {
         try {
             RecordFilterJavaScript.filterRow("user", "bufferedWriter = new 
java.io.BufferedWriter(new java.io.FileWriter('omg.txt'));\n" +
                     "            bufferedWriter.write(\"Writing line one to 
file\"); bufferedWriter.close;", TestJsonManipulator.bigTester);
-
+            Assert.fail("Java access from a row-filter expression must fail");
         } catch (MaskingException e) {
-            Assert.assertTrue(e.getCause() instanceof RuntimeException);
-            Assert.assertTrue(e.getCause().getCause() instanceof 
ClassNotFoundException);
+            Assert.assertFalse(Files.exists(Paths.get("omg.txt")));
         }
-        Assert.assertFalse(Files.exists(Paths.get("omg.txt")));
+    }
+
+    @Test
+    public void testEngineAndContextAreCleared() {
+        Assert.assertTrue(RecordFilterJavaScript.filterRow("user", "engine === 
null && context === null", TestJsonManipulator.bigTester));
     }
 
     @AfterTest

Reply via email to