Any authenticated user can overwrite any file's content by ID through the POST /api/v1/retrieval/process/files/batch endpoint. The endpoint performs no ownership check, so a regular user with read access to a shared knowledge base can obtain file UUIDs via GET /api/v1/knowledge/{id}/files and then overwrite those files, escalating from read to write. The overwritten content is served to the LLM via RAG, meaning the attacker controls what the model tells other users.
The process_files_batch() function in backend/open_webui/routers/retrieval.py appears to be designed as an internal helper. The knowledge base router (add_files_to_knowledge_batch() in knowledge.py) imports and calls it directly after performing its own ownership and access control checks. The frontend never calls the retrieval route directly; all legitimate UI flows go through the knowledge base wrapper.
However, the function is also exposed as a standalone HTTP endpoint via @router.post(...). This direct route only requires get_verified_user (any authenticated user) and performs no ownership check of its own:
for file in form_data.files:
text_content = file.data.get("content", "") # attacker-controlled
file_updates.append(FileUpdateForm(
hash=calculate_sha256_string(text_content),
data={"content": text_content}, # written to DB
))
for file_update, file_result in zip(file_updates, file_results):
Files.update_file_by_id(id=file_result.file_id, form_data=file_update)
# ^^^ no ownership check
There is no verification that file.user_id == user.id before the write. Any authenticated user who knows a file UUID can overwrite that file.
How an attacker obtains file UUIDs:
Same as with read access, any user who can see a knowledge base can retrieve file IDs for every document in it via GET /api/v1/knowledge/{id}/files. In deployments where knowledge bases are shared...
0.8.6Exploitability
AV:NAC:LPR:LUI:NScope
S:UImpact
C:NI:HA:L7.1/CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L