# DB-GPT — SQL Injection via Chart Editor Submit Endpoint (Missing Sanitization) ## meta platform: huntr program: DB-GPT asset: https://github.com/eosphoros-ai/DB-GPT date: 2026-02-13 status: DRAFT ```` Repository URL: https://github.com/eosphoros-ai/DB-GPT Package Manager: pip Version Affected: 0.7.4 (latest) Vulnerability Type: SQL Injection CVSS: - Attack Vector: Network - Attack Complexity: Low - Privileges Required: None - User Interaction: None - Scope: Unchanged - Confidentiality: High - Integrity: High - Availability: High Title: SQL Injection via unsanitized new_sql parameter in /api/v1/chart/editor/submit endpoint Description: # Description The `POST /api/v1/chart/editor/submit` endpoint in the DB-GPT chart editor accepts a `new_sql` parameter and passes it directly to `db_conn.query_ex()` without any sanitization. This contrasts with the other editor SQL endpoints (`/v1/editor/sql/run` at line 192 and `/v1/editor/chart/run` at line 273), which both pass user SQL through the `sanitize_sql()` function before execution. The `chart_editor_submit` handler at line 349 calls `dashboard_data_loader.get_chart_values_by_conn(db_conn, chart_edit_context.new_sql)`, which in turn calls `db_conn.query_ex(chart_sql)`, ultimately executing `session.execute(text(sql))` with the raw user input. Additionally, the malicious SQL stored via this endpoint persists in conversation history. The `get_editor_chart_info` service method (service.py:172) later retrieves and re-executes this stored SQL via `conn.run(find_chart["chart_sql"])`, creating a stored SQL injection vector. No authentication middleware is applied to the editor routes — any user with network access to the API can exploit this. # Proof of Concept 1. Start DB-GPT with a connected database (e.g., MySQL or PostgreSQL). 2. Send a request to the vulnerable endpoint with malicious SQL: ```bash # First, create a chat session with a chart to get a valid conv_uid # Then exploit the submit endpoint: curl -X POST http://localhost:5670/api/v1/chart/editor/submit \ -H "Content-Type: application/json" \ -d '{ "conv_uid": "", "db_name": "", "chart_title": "", "new_sql": "SELECT 1; DROP TABLE users; --", "new_chart_type": "bar", "new_comment": "test" }' ``` 3. The `new_sql` value is passed directly to `session.execute(text(...))` without sanitization, executing the injected SQL. 4. For comparison, the same SQL sent to `/v1/editor/sql/run` would be blocked by `sanitize_sql()` at line 192. 5. The stored injection persists: subsequent calls to `GET /api/v1/editor/chart/info` with the same `conv_uid` re-execute the malicious SQL from conversation history (service.py:172). **Impact**: This vulnerability is capable of full database compromise on any datasource connected to DB-GPT. An attacker can read, modify, or delete data in any connected database. On MySQL, this includes potential file read/write via `LOAD DATA INFILE`. On PostgreSQL, potential OS command execution via `COPY ... FROM PROGRAM`. The stored injection variant means the payload persists and re-executes on subsequent chart info requests. **Occurrences**: - Permalink: https://github.com/eosphoros-ai/DB-GPT/blob/322792b9d25c872eff18403b03cc97292f8e3db9/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/editor/api_editor_v1.py#L346-L351 - Description: `chart_edit_context.new_sql` passed directly to `dashboard_data_loader.get_chart_values_by_conn()` without `sanitize_sql()` — unlike the `/sql/run` (line 192) and `/chart/run` (line 273) endpoints which DO sanitize - Permalink: https://github.com/eosphoros-ai/DB-GPT/blob/322792b9d25c872eff18403b03cc97292f8e3db9/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/editor/service.py#L172 - Description: `conn.run(find_chart["chart_sql"])` executes stored SQL from conversation history without sanitization — stored SQL injection **References**: - https://cwe.mitre.org/data/definitions/89.html — CWE-89: SQL Injection - https://owasp.org/www-community/attacks/SQL_Injection — OWASP SQL Injection - https://cwe.mitre.org/data/definitions/306.html — CWE-306: Missing Authentication for Critical Function - https://huntr.com/bounties/e32fda74-ca83-431c-8de8-08274ba686c9 — Prior DB-GPT SQLi via /api/v1/editor/sql/run (DIFFERENT endpoint — that one was fixed with sanitize_sql(), but /api/v1/chart/editor/submit was missed) ````