CVE-2026-28786: 
Python vulnerability analysis and mitigation

Overview

CVE-2026-28786 is a path traversal and information disclosure vulnerability in Open WebUI, a self-hosted AI platform, affecting all versions prior to 0.8.6. The flaw resides in the speech-to-text transcription endpoint (POST /api/v1/audio/transcriptions), where an unsanitized filename field allows any authenticated non-admin user to trigger a FileNotFoundError that leaks the server's absolute DATA_DIR filesystem path verbatim in the HTTP 400 response body. It was published on March 26, 2026, and patched in version 0.8.6. The vulnerability carries a CVSS v3.1 base score of 4.3 (Medium) (GitHub Advisory, Open WebUI Advisory).

Technical details

The root cause is a combination of CWE-22 (Path Traversal) and CWE-209 (Generation of Error Message Containing Sensitive Information). In backend/open_webui/routers/audio.py at line 1197, the file extension is extracted from the raw multipart filename using file.filename.split(".")[-1] with no path sanitization, then concatenated into a filesystem path passed to open(). If the filename is crafted as audio./etc/passwd, the split yields /etc/passwd, causing open() to fail with a FileNotFoundError; the outer exception handler at line 1231 returns the full error message — including the absolute path — via ERROR_MESSAGES.DEFAULT(e). The MIME-type guard checks only the Content-Type multipart field (not the filename), so setting Content-Type: audio/wav bypasses it entirely. Notably, sibling handlers in files.py and pipelines.py correctly apply os.path.basename() to filenames, making this handler an isolated oversight (Open WebUI Advisory).

Impact

Successful exploitation allows any authenticated non-admin user to leak the server's absolute DATA_DIR filesystem path, which can be used to enumerate directory structure by varying traversal depth and observing error message changes. The impact is limited to confidentiality (low) — there is no integrity or availability impact, and the write primitive is OS-blocked in practice because the UUID segment in the path never pre-exists as a directory. Multi-tenant and shared Open WebUI deployments are most exposed, as every registered account (gated only by the lowest privilege tier get_verified_user) is a potential attacker (Open WebUI Advisory, GitHub Advisory).

Exploitability

A public proof-of-concept (PoC) Python script is available in the GitHub Security Advisory, demonstrating the full exploit flow against a live Open WebUI instance with a standard user account. The EPSS score is approximately 0.02–0.037% (11th percentile), indicating low near-term exploitation probability. There is no evidence of active in-the-wild exploitation, no known threat actor attribution, and the vulnerability is not listed in the CISA KEV catalog (Open WebUI Advisory, GitHub Advisory).

Exploitation steps

  1. Setup: Deploy or identify a target Open WebUI instance running version ≤ 0.8.5 (e.g., via Docker: docker run -d -p 3000:8080 ghcr.io/open-webui/open-webui:latest).
  2. Authenticate: Register or use an existing standard (non-admin) user account. Obtain a bearer token by sending a POST request to /api/v1/auths/signin with valid credentials.
  3. Craft malicious multipart request: Construct a multipart form-data body with the file field using a crafted filename such as audio./etc/passwd and Content-Type: audio/wav. Include a minimal WAV stub (RIFF\x00\x00\x00\x00WAVE) as the file body.
  4. Send request to vulnerable endpoint: POST the crafted body to POST /api/v1/audio/transcriptions with the bearer token in the Authorization header.
  5. Extract leaked path: Parse the HTTP 400 response body, which contains the verbatim FileNotFoundError message including the server's absolute DATA_DIR path (e.g., /app/backend/data/cache/audio/transcriptions/<uuid>./etc/passwd).
  6. Enumerate filesystem structure: Vary the traversal depth in the filename (e.g., audio./var/log/, audio./home/) and observe changes in error messages to map the server's directory layout (Open WebUI Advisory).

Indicators of compromise

  • Network: Repeated POST requests to /api/v1/audio/transcriptions from authenticated users with unusual or non-audio filenames in the multipart body; HTTP 400 responses to this endpoint at higher-than-normal frequency.
  • Logs: Application logs showing FileNotFoundError exceptions referencing paths like /etc/passwd, /etc/shadow, or other system paths within the transcription cache directory; error log entries from audio.py line 1231 containing absolute filesystem paths.
  • Application Behavior: Multiple 400-status responses to the transcription endpoint from a single user account in a short time window, especially with varying path traversal strings in filenames (e.g., audio./etc/, audio./var/, audio./home/) (Open WebUI Advisory).

Mitigation and workarounds

Upgrade Open WebUI to version 0.8.6 or later, which patches the issue by sanitizing the filename field in the transcription endpoint. As a workaround prior to patching, restrict access to the POST /api/v1/audio/transcriptions endpoint to trusted users only, or disable the speech-to-text feature if not required. The recommended code fix is to apply Path(file.filename).name for safe extension extraction and replace the verbose exception response with a generic error message (e.g., "Transcription failed.") to suppress path leakage (Open WebUI Advisory, GitHub Advisory).

Community reactions

The vulnerability was reported by security researcher akshatgit via manual static analysis of Open WebUI commit b8112d72b, with AI assistance (Claude) used to draft the report and PoC. The advisory notes this is an isolated oversight — sibling file upload handlers in the same codebase already apply os.path.basename() correctly, suggesting the fix was straightforward. No significant broader media coverage or notable community debate has been observed beyond the GitHub advisory (Open WebUI Advisory).

Additional resources


Source: This report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-v2f8-6655-7grjCRITICAL10
  • Python logoPython
  • vibe-trading-ai
NoYesOct 02, 2026
CVE-2026-105782HIGH7.5
  • Python logoPython
  • scrapy
NoYesOct 06, 2026
GHSA-v853-p72q-4cfwHIGH7.5
  • Python logoPython
  • quart
NoYesOct 05, 2026
CVE-2026-105751MEDIUM6.9
  • Python logoPython
  • docling
NoYesOct 05, 2026
CVE-2026-105750MEDIUM5.9
  • Python logoPython
  • docling
NoYesOct 05, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management