AI and data stack advisories

Severe, 6 weeks1496Projects326

1496 severe, 6 weeks · 326 projects

Open WebUIGHSA-vjqm-6gcc-62cr

Open WebUI: Forged model meta.knowledge allows cross-user file read and deletion

Open WebUI

CVE-2026-54012 · Published Jun 17, 2026 · updated Jul 20, 2026

High7.1
Fix: upgrade to 0.9.6 or later
GitHub advisory

Summary

Open WebUI lets a user who can create, update, or import workspace models store arbitrary meta.knowledge entries on their model without checking whether they own or can read the referenced files. Open WebUI then treats meta.knowledge entries of type file as an authorization source in two places: the built-in view_file tool reads the file's extracted text, and has_access_to_file()'s model branch authorizes the file content and file delete endpoints. A malicious model owner can therefore attach another user's file ID to their model metadata and read or delete that private file.

Impact

Security boundary crossed: file confidentiality and integrity.

An authenticated attacker needs the workspace.models or workspace.models_import permission (or write access to an existing model) and a victim file ID. With those, for a file they do not own and cannot otherwise read, the attacker can:

  • read the file's extracted text (up to 100000 characters per view_file call from file.data.content),
  • read the file's content via GET /api/v1/files/{id}/content, and
  • delete the file via DELETE /api/v1/files/{id}.

Root Cause

ModelMeta allows extra metadata fields and ModelForm accepts that metadata without a validator for meta.knowledge file access:

```python

backend/open_webui/models/models.py

class ModelForm(BaseModel):

model_config =...

Affected versions

PackageAffectedFixed in
open-webui
PyPI
< 0.9.60.9.6
Details and references

## Summary Open WebUI lets a user who can create, update, or import workspace models store arbitrary `meta.knowledge` entries on their model without checking whether they own or can read the referenced files. Open WebUI then treats `meta.knowledge` entries of type `file` as an authorization source in two places: the built-in `view_file` tool reads the file's extracted text, and `has_access_to_file()`'s model branch authorizes the file content and file delete endpoints. A malicious model owner can therefore attach another user's file ID to their model metadata and read or delete that private file. ## Impact Security boundary crossed: file confidentiality and integrity. An authenticated attacker needs the `workspace.models` or `workspace.models_import` permission (or write access to an existing model) and a victim file ID. With those, for a file they do not own and cannot otherwise read, the attacker can: - read the file's extracted text (up to `100000` characters per `view_file` call from `file.data.content`), - read the file's content via `GET /api/v1/files/{id}/content`, and - delete the file via `DELETE /api/v1/files/{id}`. ## Root Cause `ModelMeta` allows extra metadata fields and `ModelForm` accepts that metadata without a validator for `meta.knowledge` file access: ```python # backend/open_webui/models/models.py class ModelForm(BaseModel): model_config = ConfigDict(extra='ignore') id: str base_model_id: Optional[str] = None name: str meta: ModelMeta params: ModelParams ``` Model creation only checks the caller's model-workspace permission and then stores the form data: ```python # backend/open_webui/routers/models.py if user.role != 'admin' and not await has_permission( user.id, 'workspace.models', request.app.state.config.USER_PERMISSIONS, db=db ): raise HTTPException(...) model = await Models.insert_new_model(form_data, user.id, db=db) ``` The insert sink persists the supplied `meta`: ```python # backend/open_webui/models/models.py result = Model( **{ **form_data.model_dump(exclude={'access_grants'}), 'user_id': user_id, ... } ) ``` When built-in tools are assembled, `meta.knowledge` is passed through as `__model_knowledge__`, and any `file` entry enables `view_file`: ```python # backend/open_webui/utils/tools.py model_knowledge = model.get('info', {}).get('meta', {}).get('knowledge', []) ... knowledge_types = {item.get('type') for item in model_knowledge} if 'file' in knowledge_types or 'collection' in knowledge_types: builtin_functions.append(view_file) ``` `view_file` treats matching `__model_knowledge__` file IDs as authorization, before `has_access_to_file()`: ```python # backend/open_webui/tools/builtin.py if ( file.user_id != user_id and user_role != 'admin' and not any( item.get('type') == 'file' and item.get('id') == file_id for item in (__model_knowledge__ or []) ) and not await has_access_to_file(...) ): return json.dumps({'error': 'File not found'}) ``` The same forged `meta.knowledge` is also trusted outside the tool path. `has_access_to_file()` iterates the caller's accessible models and returns true when a model's `meta.knowledge` contains the requested file ID: ```python # backend/open_webui/utils/access_control/files.py for model in await Models.get_models_by_user_id(user.id, permission=access_type, db=db): knowledge_items = getattr(model.meta, 'knowledge', None) or [] for item in knowledge_items: if isinstance(item, dict) and item.get('type') == 'file' and item.get('id') == file.id: return True ``` This branch is not restricted to read, so it also satisfies the `write` check that `DELETE /api/v1/files/{id}` performs. The same missing validation applies to the import path (`POST /api/v1/models/import`) and the update path, not only create. ## PoC ```python #!/usr/bin/env python3 """ Verifier for forged model meta.knowledge file entries reaching builtin to

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

More Open WebUI advisories

All Open WebUI