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

freeoneplus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-mcp-server.git


The following commit(s) were added to refs/heads/master by this push:
     new 5923cc1  [BUG]Fix security bug (#50)
5923cc1 is described below

commit 5923cc1c8973069a6d54eca1948a10488cbf409e
Author: Yijia Su <[email protected]>
AuthorDate: Fri Aug 29 08:48:38 2025 +0800

    [BUG]Fix security bug (#50)
    
    * 0.5.1 Version
    
    * fix 0.5.1 schema async bug
    
    * fix security bug
---
 doris_mcp_server/utils/query_executor.py | 83 ++++++++++++++++++++++++++------
 1 file changed, 69 insertions(+), 14 deletions(-)

diff --git a/doris_mcp_server/utils/query_executor.py 
b/doris_mcp_server/utils/query_executor.py
index 027ae06..63f5d54 100644
--- a/doris_mcp_server/utils/query_executor.py
+++ b/doris_mcp_server/utils/query_executor.py
@@ -557,22 +557,67 @@ class DorisQueryExecutor:
                         "data": None
                     }
 
+                # Import required security modules
+                from .security import DorisSecurityManager, AuthContext, 
SecurityLevel
+
+                # Create proper auth context with read-only permissions
+                auth_context = AuthContext(
+                    user_id=user_id,
+                    roles=["read_only_user"],  # Restrictive role for MCP 
interface
+                    permissions=["read_data"],  # Only read permissions
+                    session_id=session_id,
+                    security_level=SecurityLevel.INTERNAL
+                )
+
+                # Perform SQL security validation if enabled
+                if hasattr(self.connection_manager, 'config') and 
hasattr(self.connection_manager.config, 'security'):
+                    if 
self.connection_manager.config.security.enable_security_check:
+                        try:
+                            security_manager = 
DorisSecurityManager(self.connection_manager.config)
+                            validation_result = await 
security_manager.validate_sql_security(sql, auth_context)
+                            
+                            if not validation_result.is_valid:
+                                self.logger.warning(f"SQL security validation 
failed for query: {sql[:100]}...")
+                                return {
+                                    "success": False,
+                                    "error": f"SQL security validation failed: 
{validation_result.error_message}",
+                                    "error_type": "security_violation",
+                                    "blocked_operations": 
validation_result.blocked_operations,
+                                    "risk_level": validation_result.risk_level,
+                                    "data": None,
+                                    "metadata": {
+                                        "query": sql,
+                                        "validation_details": {
+                                            "blocked_operations": 
validation_result.blocked_operations,
+                                            "risk_level": 
validation_result.risk_level
+                                        }
+                                    }
+                                }
+                            else:
+                                self.logger.debug(f"SQL security validation 
passed for query: {sql[:100]}...")
+                        except Exception as security_error:
+                            self.logger.error(f"Security validation error: 
{str(security_error)}")
+                            # In case of security validation error, fail safe
+                            return {
+                                "success": False,
+                                "error": f"Security validation system error: 
{str(security_error)}",
+                                "error_type": "security_system_error",
+                                "data": None,
+                                "metadata": {
+                                    "query": sql,
+                                    "security_error": str(security_error)
+                                }
+                            }
+                    else:
+                        self.logger.info("SQL security check is disabled in 
configuration")
+                else:
+                    self.logger.warning("Security configuration not found, 
proceeding without validation")
+
                 # Add LIMIT if not present and it's a SELECT query
                 if sql.upper().startswith("SELECT") and "LIMIT" not in 
sql.upper():
                     if sql.endswith(";"):
                         sql = sql[:-1]
                     sql = f"{sql} LIMIT {limit}"
-
-                # Create auth context for MCP calls
-                class MockAuthContext:
-                    def __init__(self):
-                        self.user_id = user_id
-                        self.roles = ["data_analyst"]
-                        self.permissions = ["read_data", "execute_query"]
-                        self.session_id = session_id
-                        self.security_level = "internal"
-
-                auth_context = MockAuthContext()
                 
                 # Create query request
                 query_request = QueryRequest(
@@ -827,9 +872,13 @@ class QueryPerformanceMonitor:
 
 # Unified convenience function for MCP integration
 async def execute_sql_query(sql: str, connection_manager: 
DorisConnectionManager, **kwargs) -> Dict[str, Any]:
-    """Execute SQL query - unified convenience function for MCP tools"""
+    """Execute SQL query - unified convenience function for MCP tools
+    
+    This function now includes security validation to ensure safe query 
execution.
+    All queries are validated against the configured security policies before 
execution.
+    """
     try:
-        # Create query executor
+        # Create query executor with the connection manager's configuration
         executor = DorisQueryExecutor(connection_manager)
         
         try:
@@ -839,6 +888,7 @@ async def execute_sql_query(sql: str, connection_manager: 
DorisConnectionManager
             session_id = kwargs.get("session_id", "mcp_session")
             user_id = kwargs.get("user_id", "mcp_user")
             
+            # The execute_sql_for_mcp method now includes security validation
             result = await executor.execute_sql_for_mcp(
                 sql=sql,
                 limit=limit,
@@ -854,5 +904,10 @@ async def execute_sql_query(sql: str, connection_manager: 
DorisConnectionManager
         return {
             "success": False,
             "error": f"Query execution failed: {str(e)}",
-            "data": None
+            "error_type": "execution_error",
+            "data": None,
+            "metadata": {
+                "query": sql,
+                "execution_error": str(e)
+            }
         }


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

Reply via email to