#3242·DB-GPT

[Security] HITL tool-confirmation endpoints (`/pending-confirms`, `/confirm`) have no authentication — unauthenticated approval of arbitrary tool executions

Author: TardfyouCreated Sep 17, 2026Updated Sep 17, 2026

Summary

DB-GPT's human-in-the-loop tool-confirmation flow exposes two unauthenticated HTTP endpoints: GET {prefix}/pending-confirms returns the full pending-confirmation registry (confirm_id, tool_name, args summary), and POST {prefix}/confirm resolves (approves/rejects) any pending tool execution. Neither route carries any auth dependency — the router is instantiated as APIRouter() with no dependencies, unlike other API routes that use Depends(check_api_key). An attacker with network access to the service can list pending confirmations and approve them, executing tools with the user's privileges: the approval gate is fully bypassed.

Affected version

main@ca9f014 (2026-09-16, current HEAD at time of reporting; includes the latest release).

Vulnerable code path

  1. packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/tools/execute_tool.py:35-55should_confirm hit → UUID confirm_id generated → registered in module-level _PENDING_CONFIRMATIONS.
  2. packages/dbgpt-serve/src/dbgpt_serve/connector/api/endpoints.py:24router = APIRouter() with no auth dependencies.
  3. endpoints.py:169-173@router.get("/pending-confirms") returns the full pending registry (confirm_id, tool_name, args summary). No auth dependency.
  4. endpoints.py:176-196@router.post("/confirm") accepts {"confirm_id": "...", "approved": true} and calls registry.resolve(). No auth dependency.
  5. Contrast: packages/dbgpt-app/src/dbgpt_app/openapi/api_v2.py:71 — chat completion routes use Depends(check_api_key).

Secondary defect (same flow, fail-open)

The confirmation block around execute_tool.py:26-68 wraps registry/assembly errors in except Exception: pass and proceeds to execute the tool without any confirmation — two internal failure classes (registry directory error, component assembly error) silently skip the approval gate (fail-open). A same-shaped pattern exists in packages/dbgpt-app/src/dbgpt_app/openapi/agentic_data_api.py:1898-1964.

Attack chain

  1. Agent proposes a tool call → confirmation triggers, confirm_id created.
  2. Attacker: GET {prefix}/pending-confirms (unauthenticated) → confirm_id + tool_name + args.
  3. Attacker: POST {prefix}/confirm with {"confirm_id": "...", "approved": true} → approval recorded.
  4. Tool executes with the user's privileges — approval gate bypassed.

Impact

  • Information disclosure: full parameters of pending tool calls (may include SQL, connection strings, credentials) — CWE-200.
  • Privilege escalation: unauthenticated approval of arbitrary pending tool executions — CWE-306.
  • Combined with prompt injection: complete remote code execution chain.

CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N (deployments are often network-restricted, but no authentication is required at all).

Suggested fix

Add Depends(check_api_key) (or an equivalent auth dependency) to both /pending-confirms and /confirm, aligning with the rest of the API surface; additionally bind confirm resolution to the originating session/user; change the confirmation-block error handling to fail-closed (abort execution on registry/assembly errors).

Discoverer

Chengzhi Yi (GitHub @Tardfyou) — contact: [email protected]

An offline PoC is available (loads the real confirmation module via importlib; scenarios A/B/C: control guard works, approve-by-id executes, two fail-open paths execute with zero confirmation; exit=0).