Skip to content
Open WebUIGHSA-vrhc-3fr6-pc3c

Open WebUI: Forged chat-file link allows cross-user file read and deletion

High8.3CVE-2026-54010 · Published Jun 17, 2026 · updated Jul 20, 2026

GitHub advisory

Affected versions

PackageAffectedFixed in
open-webui
PyPI
< 0.9.60.9.6
Details and references

## Summary Open WebUI `v0.9.5` lets an authenticated user attach arbitrary `file_id` values to their own chat message without checking whether they own or can read those files. If the attacker then shares that chat and grants themselves read access, `has_access_to_file()` treats the victim file as accessible through the shared chat, and the file endpoints read or delete the victim file. ## Impact Security boundary crossed: file confidentiality and integrity. An authenticated attacker who knows or obtains a victim `file_id` can make Open WebUI authorize, through an attacker-owned shared chat: - reading the victim file via `GET /api/v1/files/{id}/content`, and - deleting the victim file via `DELETE /api/v1/files/{id}`. ## Root Cause Client-controlled message file IDs are persisted without file authorization checks: ```python # backend/open_webui/main.py await Chats.insert_chat_files( chat_id, user_message.get('id'), [ file_item.get('id') for file_item in user_message_files if file_item.get('type') == 'file' ], user.id, ) ``` `insert_chat_files()` stores the provided IDs directly: ```python # backend/open_webui/models/chats.py ChatFileModel( user_id=user_id, chat_id=chat_id, message_id=message_id, file_id=file_id, ) ``` Later, file authorization trusts shared-chat associations: ```python # backend/open_webui/utils/access_control/files.py shared_chat_ids = await Chats.get_shared_chat_ids_by_file_id(file_id, db=db) if shared_chat_ids: accessible_ids = await AccessGrants.get_accessible_resource_ids( user_id=user.id, resource_type='shared_chat', resource_ids=shared_chat_ids, permission='read', ) if accessible_ids: return True ``` The download endpoint uses this helper: ```python # backend/open_webui/routers/files.py if file.user_id == user.id or user.role == 'admin' or await has_access_to_file(id, 'read', user, db=db): return FileResponse(file_path, ...) ``` On affected versions this shared-chat branch is not gated on `access_type` (the grant lookup hardcodes `permission='read'`, but nothing checks that the request itself is a read). The same forged association therefore also satisfies the `write` check that `DELETE /api/v1/files/{id}` performs, so the attacker can delete the victim file, not only read it. Because the shared-chat branch ignores `access_type`, the deletion does not require the forged association at all. A user granted only **read** access to a chat that the owner legitimately shared can delete the owner's own files attached to that chat via `DELETE /api/v1/files/{id}`, since the read grant satisfies the `write` check. The forged association (above) broadens this to any victim `file_id`; a legitimate read-only share reaches it without any forgery. ## PoC 1. Attacker creates or uses a chat they own. 2. Attacker sends `POST /api/chat/completions` or `POST /api/v1/chat/completions` where top-level `user_message.files` contains: ```json [ { "type": "file", "id": "VICTIM_FILE_ID" } ] ``` 3. Backend inserts a `chat_file` row linking the attacker chat to `VICTIM_FILE_ID`. 4. Attacker shares the chat and grants read access to themselves or public access. 5. Attacker requests: ```text GET /api/v1/files/VICTIM_FILE_ID/content ``` Expected: 404/403 because the attacker does not own or otherwise have access to the victim file. Actual: file authorization succeeds through the attacker-controlled shared-chat association. ## Local Verification I verified the bug locally with Open WebUI's real `Chats.insert_chat_files()` and real `has_access_to_file()` implementations. The harness uses fake DB adapters only to avoid this environment's async SQLite hang; the security-sensitive logic under test is the application code. Result: ```json { "before_chat_file_link_attacker_can_read": false, "insert_sink": { "db_commit_called": true, "insert_returned_rows": true, "stored_chat

CVSS 3.1
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
Severity from
GitHub (reviewed advisory)
Weakness
CWE-284, CWE-639, CWE-862
Also known as
CVE-2026-54010, PYSEC-2026-2763

More Open WebUI advisories

All Open WebUI
DateAdvisory
Jun 17Open WebUI IDOR: Calendar event re-parenting allows writing events into another user's calendar
CVE-2026-54006Medium4.3fixed in 0.9.6
Jun 17Open WebUI: Cross-origin postMessage confirmation bypass via action:submit
CVE-2026-54007High6.5fixed in 0.9.6
Jun 17Open WebUI: Redirect-Bypass SSRF in OAuth `_process_picture_url` (incomplete-fix sibling of CVE-2026-45401)
CVE-2026-54008High8.5fixed in 0.9.6
Jun 17Open WebUI: Cross-user file disclosure via /api/chat/completions image_url field
CVE-2026-54009Medium6.5fixed in 0.9.6
Jun 17Open WebUI: Stored XSS in Mermaid Markdown Preview
CVE-2026-54011High8.7fixed in 0.9.6
Jun 17Open WebUI: Forged model meta.knowledge allows cross-user file read and deletion
CVE-2026-54012High7.1fixed in 0.9.6

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.