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

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.2 by this push:
     new 309b8a6cbdc branch-4.2: [Fix](auth) Restrict processlist visibility by 
user identity #66746 (#70113)
309b8a6cbdc is described below

commit 309b8a6cbdc0514ca2cc654719b9ccf1b79c89d8
Author: morrySnow <[email protected]>
AuthorDate: Wed Nov 4 08:31:20 2026 +0800

    branch-4.2: [Fix](auth) Restrict processlist visibility by user identity 
#66746 (#70113)
    
    picked from master #66746
    
    Co-authored-by: linrrarity <[email protected]>
---
 .../schema_processlist_scanner.cpp                 |  1 +
 .../apache/doris/service/FrontendServiceImpl.java  | 10 ++---
 .../doris/service/FrontendServiceImplTest.java     | 11 +++++
 .../suites/show_p0/test_show_processlist.groovy    | 48 +++++++++++++++++++++-
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/be/src/information_schema/schema_processlist_scanner.cpp 
b/be/src/information_schema/schema_processlist_scanner.cpp
index 43f97d5248c..6e06830a58d 100644
--- a/be/src/information_schema/schema_processlist_scanner.cpp
+++ b/be/src/information_schema/schema_processlist_scanner.cpp
@@ -59,6 +59,7 @@ Status SchemaProcessListScanner::start(RuntimeState* state) {
     TShowProcessListRequest request;
     request.__set_show_full_sql(true);
     request.__set_time_zone(state->timezone());
+    
request.__set_current_user_ident(*_param->common_param->current_user_ident);
 
     for (const auto& fe_addr : _param->common_param->fe_addr_list) {
         TShowProcessListResult tmp_ret;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java 
b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
index 30493552832..8834be5cb48 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
@@ -5078,15 +5078,15 @@ public class FrontendServiceImpl implements 
FrontendService.Iface {
     }
 
     @Override
-    public TShowProcessListResult showProcessList(TShowProcessListRequest 
request) {
+    public TShowProcessListResult showProcessList(TShowProcessListRequest 
request) throws TException {
+        if (!request.isSetCurrentUserIdent()) {
+            throw new TException("Current user identity is not set");
+        }
         boolean isShowFullSql = false;
         if (request.isSetShowFullSql()) {
             isShowFullSql = request.isShowFullSql();
         }
-        UserIdentity userIdentity = UserIdentity.ROOT;
-        if (request.isSetCurrentUserIdent()) {
-            userIdentity = 
UserIdentity.fromThrift(request.getCurrentUserIdent());
-        }
+        UserIdentity userIdentity = 
UserIdentity.fromThrift(request.getCurrentUserIdent());
         String timeZone = 
VariableMgr.getDefaultSessionVariable().getTimeZone();
         if (request.isSetTimeZone()) {
             timeZone = request.getTimeZone();
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/service/FrontendServiceImplTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/service/FrontendServiceImplTest.java
index b97c34058f6..1bcb6c0b815 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/service/FrontendServiceImplTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/service/FrontendServiceImplTest.java
@@ -70,6 +70,7 @@ import org.apache.doris.thrift.TPrivilegeType;
 import org.apache.doris.thrift.TRollbackTxnRequest;
 import org.apache.doris.thrift.TSchemaTableName;
 import org.apache.doris.thrift.TSchemaTableRequestParams;
+import org.apache.doris.thrift.TShowProcessListRequest;
 import org.apache.doris.thrift.TShowUserRequest;
 import org.apache.doris.thrift.TShowUserResult;
 import org.apache.doris.thrift.TStatusCode;
@@ -84,6 +85,7 @@ import org.apache.doris.utframe.UtFrameUtils;
 import com.google.common.collect.Sets;
 import mockit.Mocked;
 import org.apache.logging.log4j.Level;
+import org.apache.thrift.TException;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -190,6 +192,15 @@ public class FrontendServiceImplTest {
         }
     }
 
+    @Test
+    public void testShowProcessListRejectsMissingUserIdentity() {
+        FrontendServiceImpl impl = new FrontendServiceImpl(exeEnv);
+        TShowProcessListRequest request = new TShowProcessListRequest();
+
+        TException exception = Assert.assertThrows(TException.class, () -> 
impl.showProcessList(request));
+        Assert.assertEquals("Current user identity is not set", 
exception.getMessage());
+    }
+
     @Test
     public void testGetTableNamesWithSysTablePattern() throws Exception {
         FrontendServiceImpl impl = new FrontendServiceImpl(exeEnv);
diff --git a/regression-test/suites/show_p0/test_show_processlist.groovy 
b/regression-test/suites/show_p0/test_show_processlist.groovy
index fbadaafa703..abba471b35e 100644
--- a/regression-test/suites/show_p0/test_show_processlist.groovy
+++ b/regression-test/suites/show_p0/test_show_processlist.groovy
@@ -18,6 +18,20 @@
 import org.apache.doris.regression.util.Http
 
 suite("test_show_processlist") {
+    def victimUser = "test_processlist_victim"
+    def attackerUser = "test_processlist_attacker"
+    def userPassword = "C123_567p"
+    try_sql "DROP USER '${victimUser}'"
+    try_sql "DROP USER '${attackerUser}'"
+    sql "CREATE USER '${victimUser}' IDENTIFIED BY '${userPassword}'"
+    sql "CREATE USER '${attackerUser}' IDENTIFIED BY '${userPassword}'"
+    sql "GRANT SELECT_PRIV ON regression_test.* TO '${victimUser}'"
+    sql "GRANT SELECT_PRIV ON regression_test.* TO '${attackerUser}'"
+    if (isCloudMode()) {
+        sql "GRANT USAGE_PRIV ON COMPUTE GROUP '%' TO '${victimUser}'"
+        sql "GRANT USAGE_PRIV ON COMPUTE GROUP '%' TO '${attackerUser}'"
+    }
+
     sql """set fetch_all_fe_for_system_table = false;"""
     def result = sql """show processlist;"""
     logger.info("result:${result}")
@@ -42,7 +56,39 @@ suite("test_show_processlist") {
     logger.info("result:${result}")
     assertTrue(result[0].size() == 15)
 
-    
+    connect(victimUser, userPassword, context.config.jdbcUrl) {
+        sql "select 1"
+        connect(attackerUser, userPassword, context.config.jdbcUrl) {
+            def attackerRows = sql """
+                SELECT User, Info
+                FROM information_schema.processlist
+                WHERE User IN ('${victimUser}', '${attackerUser}')
+                ORDER BY User
+            """
+            assertFalse(attackerRows.isEmpty())
+            assertTrue(attackerRows.every { row -> row[0] == attackerUser })
+            assertFalse(attackerRows.any { row -> row[0] == victimUser })
+            assertTrue(attackerRows.any { row ->
+                row[1] != null && 
row[1].toString().contains("information_schema.processlist")
+            })
+
+            def showRows = sql "SHOW FULL PROCESSLIST"
+            assertFalse(showRows.isEmpty())
+            assertTrue(showRows.every { row -> row[2] == attackerUser })
+
+            connect('root', context.config.getRootPassword(), 
context.config.jdbcUrl) {
+                def adminRows = sql """
+                    SELECT User
+                    FROM information_schema.processlist
+                    WHERE User IN ('${victimUser}', '${attackerUser}')
+                    ORDER BY User
+                """
+                assertTrue(adminRows.any { row -> row[0] == victimUser })
+                assertTrue(adminRows.any { row -> row[0] == attackerUser })
+            }
+        }
+    }
+
     def result1 = connect('root', context.config.getRootPassword(), 
context.config.jdbcUrl) {
         // execute sql with admin user
         sql 'select 99 + 1'


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

Reply via email to