{"id":"CVE-2026-80104","title":"DB-GPT builds the destination path for an uploaded skill from the multipart filename without constraining it to the upload directory","summary":"DB-GPT builds the destination path for an uploaded skill from the multipart filename without constraining it to the upload directory. skill_upload in packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/agentic_data_api.py takes file.filename…","severity":"critical","cvss":9.8,"cvssVector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H","cwe":["CWE-22"],"published":"2026-08-25","updated":"2026-09-23","sourceUpdated":"2026-09-23T17:17:45.463","source":"NVD","sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-80104","references":[{"url":"https://github.com/eosphoros-ai/DB-GPT","label":"disclosure@vulncheck.com"},{"url":"https://github.com/eosphoros-ai/DB-GPT/blob/v0.8.0/packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/agentic_data_api.py","label":"disclosure@vulncheck.com"},{"url":"https://github.com/eosphoros-ai/DB-GPT/releases/tag/v0.8.1","label":"disclosure@vulncheck.com"},{"url":"https://pypi.org/project/dbgpt-app/","label":"disclosure@vulncheck.com"},{"url":"https://www.vulncheck.com/advisories/db-gpt-0.8.0-path-traversal-arbitrary-file-write-via-skill-upload-filename","label":"disclosure@vulncheck.com"}],"tags":["nvd"],"epss":0.00713,"epssPercentile":0.52231,"ingestedAt":"2026-08-29T21:42:33.886Z","slug":"CVE-2026-80104","body":"## Overview\n\nDB-GPT builds the destination path for an uploaded skill from the multipart filename without constraining it to the upload directory. skill_upload in packages/dbgpt-app/src/dbgpt_app/openapi/api_v1/agentic_data_api.py takes file.filename as given and writes the request body to upload_dir / filename. A path composed with that operator discards the left operand when the right one is absolute and follows parent references otherwise, so a filename such as ../../../tmp/x or /tmp/x resolves outside the intended directory; nothing canonicalises the result, checks that it remains under the upload root, or prevents a .py suffix. The route's only dependency is get_user_from_headers in dbgpt_serve/utils/auth.py, which returns a request carrying the admin role whether or not a user_id header is supplied, so the endpoint is reachable without credentials. A remote attacker holding no account can therefore write attacker-controlled bytes to any path the server process can write, place a new Python module inside the application package or replace one the application already imports, and obtain code execution in the server process when that module is next imported.\n\n## Remediation\n\nRefer to the linked advisories for vendor-supplied fixes and affected version ranges.","depth":"midnight","depthScore":54,"depthScoreParts":{"impact":53.9,"likelihood":0.1,"exploitation":0,"ransomware":0},"changes":[]}