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 81e98cbbe RANGER-5799: Validate class assignability before 
instantiating configured service-def classes (#1323)
81e98cbbe is described below

commit 81e98cbbee434ae0aeaf76755e29a654baf03445
Author: Vyom Mani Tiwari <[email protected]>
AuthorDate: Wed Oct 21 19:53:51 2026 +0530

    RANGER-5799: Validate class assignability before instantiating configured 
service-def classes (#1323)
---
 .../RangerAbstractGeolocationProvider.java         | 12 +++-
 .../plugin/contextenricher/RangerTagEnricher.java  | 13 +++-
 .../contextenricher/RangerUserStoreEnricher.java   | 13 +++-
 .../policyengine/RangerPolicyRepository.java       | 10 ++-
 .../TestRangerPolicyRepositoryContextEnricher.java | 73 ++++++++++++++++++++++
 .../java/org/apache/ranger/biz/ServiceMgr.java     |  5 +-
 .../java/org/apache/ranger/biz/TestServiceMgr.java |  6 +-
 7 files changed, 119 insertions(+), 13 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractGeolocationProvider.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractGeolocationProvider.java
index 1dc76edbd..f5ba9b2fa 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractGeolocationProvider.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerAbstractGeolocationProvider.java
@@ -27,6 +27,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.Map;
 
 public abstract class RangerAbstractGeolocationProvider extends 
RangerAbstractContextEnricher {
@@ -62,10 +63,15 @@ public void init() {
                if (context != null) {
                        try {
                                // Get the class definition and ensure it is of 
the correct type
+                               Class<?> cls = Class.forName(geoSourceLoader, 
false, RangerAbstractGeolocationProvider.class.getClassLoader());
+                               if 
(!GeolocationStore.class.isAssignableFrom(cls)) {
+                                       throw new ClassCastException("class " + 
geoSourceLoader + " is not assignable to " + GeolocationStore.class.getName());
+                               }
+
                                @SuppressWarnings("unchecked")
-                               Class<GeolocationStore> geoSourceLoaderClass = 
(Class<GeolocationStore>) Class.forName(geoSourceLoader);
+                               Class<GeolocationStore> geoSourceLoaderClass = 
(Class<GeolocationStore>) cls;
                                // instantiate the loader class and initialize 
it with options
-                               geoStore = geoSourceLoaderClass.newInstance();
+                               geoStore = 
geoSourceLoaderClass.getDeclaredConstructor().newInstance();
                        }
                        catch (ClassNotFoundException exception) {
                                
LOG.error("RangerAbstractGeolocationProvider.init() - Class " + geoSourceLoader 
+ " not found, exception=" + exception);
@@ -76,7 +82,7 @@ public void init() {
                        catch (IllegalAccessException exception) {
                                
LOG.error("RangerAbstractGeolocationProvider.init() - Class " + geoSourceLoader 
+ " could not be instantiated, exception=" + exception);
                        }
-                       catch (InstantiationException exception) {
+                       catch (InstantiationException | NoSuchMethodException | 
InvocationTargetException exception) {
                                
LOG.error("RangerAbstractGeolocationProvider.init() - Class " + geoSourceLoader 
+ " could not be instantiated, exception=" + exception);
                        }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 779ee8a4b..3e99b2f15 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -58,6 +58,7 @@
 import java.io.FileWriter;
 import java.io.Reader;
 import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -116,10 +117,16 @@ public void init() {
                if (StringUtils.isNotBlank(tagRetrieverClassName)) {
 
                        try {
+                               Class<?> cls = 
Class.forName(tagRetrieverClassName, false, 
RangerTagEnricher.class.getClassLoader());
+
+                               if 
(!RangerTagRetriever.class.isAssignableFrom(cls)) {
+                                       throw new ClassCastException("class " + 
tagRetrieverClassName + " is not assignable to " + 
RangerTagRetriever.class.getName());
+                               }
+
                                @SuppressWarnings("unchecked")
-                               Class<RangerTagRetriever> tagRetriverClass = 
(Class<RangerTagRetriever>) Class.forName(tagRetrieverClassName);
+                               Class<RangerTagRetriever> tagRetriverClass = 
(Class<RangerTagRetriever>) cls;
 
-                               tagRetriever = tagRetriverClass.newInstance();
+                               tagRetriever = 
tagRetriverClass.getDeclaredConstructor().newInstance();
 
                        } catch (ClassNotFoundException exception) {
                                LOG.error("Class " + tagRetrieverClassName + " 
not found, exception=" + exception);
@@ -127,7 +134,7 @@ public void init() {
                                LOG.error("Class " + tagRetrieverClassName + " 
is not a type of RangerTagRetriever, exception=" + exception);
                        } catch (IllegalAccessException exception) {
                                LOG.error("Class " + tagRetrieverClassName + " 
illegally accessed, exception=" + exception);
-                       } catch (InstantiationException exception) {
+                       } catch (InstantiationException | NoSuchMethodException 
| InvocationTargetException exception) {
                                LOG.error("Class " + tagRetrieverClassName + " 
could not be instantiated, exception=" + exception);
                        }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerUserStoreEnricher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerUserStoreEnricher.java
index f2845e8d4..24d646395 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerUserStoreEnricher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerUserStoreEnricher.java
@@ -28,6 +28,7 @@
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Timer;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -66,10 +67,16 @@ public void init() {
         if (StringUtils.isNotBlank(userStoreRetrieverClassName)) {
 
             try {
+                Class<?> cls = Class.forName(userStoreRetrieverClassName, 
false, RangerUserStoreEnricher.class.getClassLoader());
+
+                if (!RangerUserStoreRetriever.class.isAssignableFrom(cls)) {
+                    throw new ClassCastException("class " + 
userStoreRetrieverClassName + " is not assignable to " + 
RangerUserStoreRetriever.class.getName());
+                }
+
                 @SuppressWarnings("unchecked")
-                Class<RangerUserStoreRetriever> userStoreRetriverClass = 
(Class<RangerUserStoreRetriever>) Class.forName(userStoreRetrieverClassName);
+                Class<RangerUserStoreRetriever> userStoreRetriverClass = 
(Class<RangerUserStoreRetriever>) cls;
 
-                userStoreRetriever = userStoreRetriverClass.newInstance();
+                userStoreRetriever = 
userStoreRetriverClass.getDeclaredConstructor().newInstance();
 
             } catch (ClassNotFoundException exception) {
                 LOG.error("Class " + userStoreRetrieverClassName + " not 
found, exception=" + exception);
@@ -77,7 +84,7 @@ public void init() {
                 LOG.error("Class " + userStoreRetrieverClassName + " is not a 
type of RangerUserStoreRetriever, exception=" + exception);
             } catch (IllegalAccessException exception) {
                 LOG.error("Class " + userStoreRetrieverClassName + " illegally 
accessed, exception=" + exception);
-            } catch (InstantiationException exception) {
+            } catch (InstantiationException | NoSuchMethodException | 
InvocationTargetException exception) {
                 LOG.error("Class " + userStoreRetrieverClassName + " could not 
be instantiated, exception=" + exception);
             }
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index 7bb4611bd..317d206b6 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -1052,10 +1052,16 @@ private RangerContextEnricher 
buildContextEnricher(RangerServiceDef.RangerContex
 
             if (!StringUtils.isEmpty(clsName)) {
                 try {
+                    Class<?> cls = Class.forName(clsName, false, 
RangerPolicyRepository.class.getClassLoader());
+
+                    if (!RangerContextEnricher.class.isAssignableFrom(cls)) {
+                        throw new ClassCastException("class " + clsName + " is 
not assignable to " + RangerContextEnricher.class.getName());
+                    }
+
                     @SuppressWarnings("unchecked")
-                    Class<RangerContextEnricher> enricherClass = 
(Class<RangerContextEnricher>) Class.forName(clsName);
+                    Class<? extends RangerContextEnricher> enricherClass = 
(Class<? extends RangerContextEnricher>) cls;
 
-                    ret = enricherClass.newInstance();
+                    ret = enricherClass.getDeclaredConstructor().newInstance();
                 } catch (Exception excp) {
                     LOG.error("failed to instantiate context enricher '" + 
clsName + "' for '" + name + "'", excp);
                 }
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPolicyRepositoryContextEnricher.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPolicyRepositoryContextEnricher.java
new file mode 100644
index 000000000..c7dc86764
--- /dev/null
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestRangerPolicyRepositoryContextEnricher.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.plugin.policyengine;
+
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
+import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
+import org.apache.ranger.plugin.contextenricher.RangerTagEnricher;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import 
org.apache.ranger.plugin.model.RangerServiceDef.RangerContextEnricherDef;
+import org.apache.ranger.plugin.util.ServicePolicies;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+public class TestRangerPolicyRepositoryContextEnricher {
+    private static RangerPolicyRepository buildRepository(String 
enricherClassName) {
+        RangerServiceDef serviceDef = new RangerServiceDef();
+
+        serviceDef.setName("test-enricher-svc");
+        serviceDef.setContextEnrichers(Collections.singletonList(
+                new RangerContextEnricherDef(1L, "testEnricher", 
enricherClassName, Collections.emptyMap())));
+
+        ServicePolicies servicePolicies = new ServicePolicies();
+
+        servicePolicies.setServiceName("test-enricher-svc-instance");
+        servicePolicies.setServiceDef(serviceDef);
+        servicePolicies.setPolicies(Collections.emptyList());
+
+        RangerPluginContext pluginContext = new RangerPluginContext(new 
RangerPluginConfig("test-enricher-svc", "test-enricher-svc-instance", 
"test-enricher-svc", "cl1", "on-prem", null));
+
+        return new RangerPolicyRepository(servicePolicies, pluginContext);
+    }
+
+    @Test
+    public void testMaliciousEnricherClassIsNotInstantiated() {
+        // java.lang.Thread has a public no-arg constructor and is on the 
classpath,
+        // but does not implement RangerContextEnricher.
+        RangerPolicyRepository repository = 
buildRepository(Thread.class.getName());
+
+        List<RangerContextEnricher> enrichers = 
repository.getContextEnrichers();
+
+        Assertions.assertTrue(enrichers == null || enrichers.isEmpty(),
+                "a class not assignable to RangerContextEnricher must not be 
instantiated as one");
+    }
+
+    @Test
+    public void testLegitimateEnricherClassIsStillInstantiated() {
+        RangerPolicyRepository repository = 
buildRepository(RangerTagEnricher.class.getName());
+
+        List<RangerContextEnricher> enrichers = 
repository.getContextEnrichers();
+
+        Assertions.assertNotNull(enrichers);
+        Assertions.assertEquals(1, enrichers.size());
+        Assertions.assertEquals(RangerTagEnricher.class, 
enrichers.get(0).getClass());
+    }
+}
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java 
b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
index 6202d0539..3c283f7f2 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
@@ -848,7 +848,10 @@ private Class<? extends RangerBaseService> 
getClassForServiceType(RangerServiceD
                                                        } else {
                                                                URL[]          
pluginFiles = getPluginFilesForServiceType(serviceType);
                                                                URLClassLoader 
clsLoader   = new URLClassLoader(pluginFiles, 
Thread.currentThread().getContextClassLoader());
-                                                               Class<?>       
cls         = Class.forName(clsName, true, clsLoader);
+                                                               Class<?>       
cls         = Class.forName(clsName, false, clsLoader);
+                                                               if 
(!RangerBaseService.class.isAssignableFrom(cls)) {
+                                                                       throw 
new ClassCastException("class " + clsName + " is not assignable to " + 
RangerBaseService.class.getName());
+                                                               }
 
                                                                ret = (Class<? 
extends RangerBaseService>) cls;
                                                        }
diff --git 
a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceMgr.java 
b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceMgr.java
index e9669ffba..b0f075076 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceMgr.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceMgr.java
@@ -314,7 +314,11 @@ public void 
test11_getRangerServiceByService_rejectsImplClassNotAssignableToRang
         def.setImplClass(Thread.class.getName());
         when(store.getServiceDefByName("evil")).thenReturn(def);
 
-        Assertions.assertThrows(ClassCastException.class, () -> 
mgr.getRangerServiceByService(svc, store));
+        RangerBaseService built = mgr.getRangerServiceByService(svc, store);
+
+        Assertions.assertNotNull(built);
+        Assertions.assertEquals(RangerDefaultService.class, built.getClass());
+        Assertions.assertEquals("s", built.getServiceName());
     }
 
     @Test

Reply via email to