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

Open WebUI trusts attacker-supplied model meta.knowledge file IDs, letting a model owner read and delete other users' private files via view_file and the files API.

- Payout: Research
- Severity: high
- Program: Open WebUI
- Found by: 0xEr3n, 5yu4n
- Disclosed: 2026-06-17
- CVE: CVE-2026-54012
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-vjqm-6gcc-62cr
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-vjqm-6gcc-62cr
- Tags: area:ai domain:ai domain:web impact:data-leak impact:integrity kind:research platform:ghsa sev:high tech:python technique:source-review vuln:access-control vuln:auth-bypass vuln:idor

**Target:** Open WebUI workspace models and file API (view_file builtin tool, /api/v1/files/{id})
**Root cause:** Model create/update/import paths store arbitrary meta.knowledge entries without validating file ownership or read access, and both view_file() and has_access_to_file()'s model branch treat those entries as an authorization source.
**Steps:**
1. Authenticate with workspace.models or workspace.models_import permission (or write access to an existing model).
2. Create a model with `meta.knowledge` containing `{"id": "VICTIM_FILE_ID", "type": "file", "name": "victim-private.txt"}` and `builtinTools.knowledge: true`.
3. Chat with that model using built-in tools and invoke `view_file` for `VICTIM_FILE_ID`; it returns the victim's extracted text (up to 100000 chars).
4. Alternatively call `GET /api/v1/files/{id}/content` or `DELETE /api/v1/files/{id}`; has_access_to_file()'s model branch returns true for the forged entry, satisfying even the write check.
**How found:** Code review of the model write path (ModelForm/insert_new_model) showed meta.knowledge is stored unvalidated, then tracing where meta.knowledge is consumed revealed view_file() and has_access_to_file() treat it as an authorization source.
**Exploitation:** Attacker needs a victim file ID and model-workspace permission. They forge meta.knowledge on their own model, then either drive the built-in view_file tool through a chat or hit the file content/delete endpoints directly; has_access_to_file() iterates the attacker's models and returns true on the forged file ID, granting read and delete of the victim's file.
**Escalation:** Same forged entry satisfies both read (view_file, GET content) and write (DELETE) checks because the model branch is not restricted to read access.
**Insight:** When a metadata field is later consumed as an authorization source (ACL shortcut), audit every write path that populates it — create, update, and import — and check whether the ACL branch is scoped to the specific access type (read vs write) it is being used for.

## Proof of concept (copied exactly from the original report)

**Forged model creation payload with victim file ID**

```
{
  "meta": {
    "knowledge": [
      {
        "id": "VICTIM_FILE_ID",
        "type": "file",
        "name": "victim-private.txt"
      }
    ],
    "builtinTools": {
      "knowledge": true
    }
  }
}
```

