github-actions[bot] commented on code in PR #67206:
URL: https://github.com/apache/doris/pull/67206#discussion_r3877692537


##########
fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHivePlugin.java:
##########
@@ -17,17 +17,39 @@
 
 package org.apache.doris.catalog.authorizer.ranger.hive;
 
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
 import org.apache.ranger.plugin.service.RangerAuthContextListener;
 import org.apache.ranger.plugin.service.RangerBasePlugin;
 
+import java.util.Map;
+
 public class RangerHivePlugin extends RangerBasePlugin {
+    static final String POLICY_REST_URL_PROPERTY = 
"ranger.plugin.hive.policy.rest.url";
+
     public RangerHivePlugin(String serviceName) {
         super(serviceName, null);
     }
 
     public RangerHivePlugin(String serviceName, RangerAuthContextListener 
rangerAuthContextListener) {
-        super(serviceName, null, null);
+        this(serviceName, null, rangerAuthContextListener);
+    }
+
+    public RangerHivePlugin(String serviceName, Map<String, String> properties,
+            RangerAuthContextListener rangerAuthContextListener) {
+        super(createPluginConfig(serviceName, properties));
         super.init();
         super.registerAuthContextEventListener(rangerAuthContextListener);
     }
+
+    static RangerPluginConfig createPluginConfig(String serviceName, 
Map<String, String> properties) {
+        if (properties != null && 
properties.containsKey(POLICY_REST_URL_PROPERTY)) {
+            RangerPluginConfig config = new RangerPluginConfig("hive", 
serviceName, null, null, null, null);
+            // Keep audit, UGI, and credentials process-scoped. Catalog 
properties may only override the policy URL.
+            config.set(POLICY_REST_URL_PROPERTY, 
properties.get(POLICY_REST_URL_PROPERTY));

Review Comment:
   [P1] Do not send process Ranger credentials to a catalog-selected host
   
   `RangerPluginConfig("hive", ...)` loads the process XML before this 
assignment. Ranger 2.8 later reads 
`ranger.plugin.hive.policy.rest.client.username/password` from that same 
config, and `super.init()` synchronously downloads roles and policies during 
CREATE CATALOG's dry run. Because catalog `CREATE` is sufficient, a non-admin 
can point this property at an HTTP server they control and receive the FE's 
process-scoped Basic Authorization header before the temporary controller is 
closed. This is distinct from the existing SHOW/masking thread: the secret 
never appears in catalog properties. Keep the URL in the same process-owned 
profile as its credentials, or clear all process authentication material for 
catalog-selected endpoints and use separately scoped, masked credentials. 
Please add a capture-server test proving an unapproved URL receives no 
Authorization header.
   



##########
fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHivePlugin.java:
##########
@@ -17,17 +17,39 @@
 
 package org.apache.doris.catalog.authorizer.ranger.hive;
 
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
 import org.apache.ranger.plugin.service.RangerAuthContextListener;
 import org.apache.ranger.plugin.service.RangerBasePlugin;
 
+import java.util.Map;
+
 public class RangerHivePlugin extends RangerBasePlugin {
+    static final String POLICY_REST_URL_PROPERTY = 
"ranger.plugin.hive.policy.rest.url";
+
     public RangerHivePlugin(String serviceName) {
         super(serviceName, null);
     }
 
     public RangerHivePlugin(String serviceName, RangerAuthContextListener 
rangerAuthContextListener) {
-        super(serviceName, null, null);
+        this(serviceName, null, rangerAuthContextListener);
+    }
+
+    public RangerHivePlugin(String serviceName, Map<String, String> properties,
+            RangerAuthContextListener rangerAuthContextListener) {
+        super(createPluginConfig(serviceName, properties));
         super.init();
         super.registerAuthContextEventListener(rangerAuthContextListener);
     }
+
+    static RangerPluginConfig createPluginConfig(String serviceName, 
Map<String, String> properties) {
+        if (properties != null && 
properties.containsKey(POLICY_REST_URL_PROPERTY)) {
+            RangerPluginConfig config = new RangerPluginConfig("hive", 
serviceName, null, null, null, null);
+            // Keep audit, UGI, and credentials process-scoped. Catalog 
properties may only override the policy URL.
+            config.set(POLICY_REST_URL_PROPERTY, 
properties.get(POLICY_REST_URL_PROPERTY));

Review Comment:
   [P1] Keep the Ranger policy authority operator-controlled
   
   A principal with catalog `ALTER` but no `SELECT` can change this property on 
an existing working catalog; the property merge preserves its HMS/storage 
settings, then controller reset makes this server the authority for 
`checkDbPriv`, `checkTblPriv`, and `checkColsPriv`. The principal can point it 
at a Ranger-compatible server they control, return a `select` policy for 
themselves, and pass external-table authorization without any conjunctive Doris 
`SELECT` grant. `CREATE CATALOG` has the same problem for a new reachable 
source. The added regression demonstrates the decisive behavior by authorizing 
an otherwise ungranted user solely from policies fetched at this URL. This is 
not the threat model's disclaimed outbound-request/SSRF case: the untrusted 
response becomes the RBAC decision. Keep the Ranger Admin URL 
operator-owned/allowlisted, or require an administrator-only privilege to set 
or alter it, and add a negative test proving a restricted caller cannot replace 
the policy author
 ity.
   



##########
fe/fe-core/src/main/java/org/apache/doris/catalog/authorizer/ranger/hive/RangerHivePlugin.java:
##########
@@ -17,17 +17,39 @@
 
 package org.apache.doris.catalog.authorizer.ranger.hive;
 
+import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
 import org.apache.ranger.plugin.service.RangerAuthContextListener;
 import org.apache.ranger.plugin.service.RangerBasePlugin;
 
+import java.util.Map;
+
 public class RangerHivePlugin extends RangerBasePlugin {
+    static final String POLICY_REST_URL_PROPERTY = 
"ranger.plugin.hive.policy.rest.url";
+
     public RangerHivePlugin(String serviceName) {
         super(serviceName, null);
     }
 
     public RangerHivePlugin(String serviceName, RangerAuthContextListener 
rangerAuthContextListener) {
-        super(serviceName, null, null);
+        this(serviceName, null, rangerAuthContextListener);
+    }
+
+    public RangerHivePlugin(String serviceName, Map<String, String> properties,
+            RangerAuthContextListener rangerAuthContextListener) {
+        super(createPluginConfig(serviceName, properties));
         super.init();
         super.registerAuthContextEventListener(rangerAuthContextListener);
     }
+
+    static RangerPluginConfig createPluginConfig(String serviceName, 
Map<String, String> properties) {
+        if (properties != null && 
properties.containsKey(POLICY_REST_URL_PROPERTY)) {
+            RangerPluginConfig config = new RangerPluginConfig("hive", 
serviceName, null, null, null, null);

Review Comment:
   [P1] Isolate Ranger authorization caches by Admin endpoint
   
   This constructor defaults `appId` to `hive`. Ranger 2.8 names its policy, 
role, and implicit GDS caches from `appId` plus `serviceName`; none of those 
identities includes this catalog-selected URL. With a configured cache 
directory, two catalogs that use the same service name on different Ranger 
Admins therefore share unsynchronized cache writers. A dry run for endpoint A 
can leave A's permissive authorization state behind, and if endpoint B is 
temporarily unavailable when its controller initializes, Ranger can load that 
service-name-matching state and authorize B with A's policy or role membership. 
Controller cleanup does not remove the files. Namespace every authorization 
cache by a stable endpoint/catalog identity (and publish atomically), then test 
same-service controllers on different endpoints with one endpoint unavailable.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to