Open WebUI Vulnerable to IDOR: Retrieval API Bypasses Knowledge Base Access Controls
High7.5CVE-2026-45398 · Published May 14, 2026 · updated Jul 13, 2026
# IDOR: Retrieval API Bypasses Knowledge Base Access Controls **Author:** Andrew Orr <aorr@tenable.com> ## Summary `_validate_collection_access()` ([PR #22109](https://github.com/open-webui/open-webui/pull/22109)) checks the `user-memory-*` and `file-*` collection name prefixes but does not check knowledge base collections, which use raw UUIDs as collection names. Any authenticated user who knows a private knowledge base UUID can read its content through the retrieval query endpoints, even though the knowledge API correctly denies that user access. The same gap affects the retrieval write endpoints (`/process/text`, `/process/file`, `/process/files/batch`, `/process/web`, `/process/youtube`), allowing an attacker to inject content into or overwrite another user's knowledge base. Reproduced on `main` at commit `4d058a125` (v0.8.11) on March 26, 2026. ## Severity - CWE-639: Authorization Bypass Through User-Controlled Key - CVSS 3.1: `7.5 (AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H)` -- `AC:H` because exploitation requires knowing a target UUID; `I:H` and `A:H` because the write path allows poisoning or destruction of another user's knowledge base ## Default Configuration Reachabilit...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| open-webui PyPI | < 0.9.5 | 0.9.5 |
Details and references
# IDOR: Retrieval API Bypasses Knowledge Base Access Controls **Author:** Andrew Orr <aorr@tenable.com> ## Summary `_validate_collection_access()` ([PR #22109](https://github.com/open-webui/open-webui/pull/22109)) checks the `user-memory-*` and `file-*` collection name prefixes but does not check knowledge base collections, which use raw UUIDs as collection names. Any authenticated user who knows a private knowledge base UUID can read its content through the retrieval query endpoints, even though the knowledge API correctly denies that user access. The same gap affects the retrieval write endpoints (`/process/text`, `/process/file`, `/process/files/batch`, `/process/web`, `/process/youtube`), allowing an attacker to inject content into or overwrite another user's knowledge base. Reproduced on `main` at commit `4d058a125` (v0.8.11) on March 26, 2026. ## Severity - CWE-639: Authorization Bypass Through User-Controlled Key - CVSS 3.1: `7.5 (AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H)` -- `AC:H` because exploitation requires knowing a target UUID; `I:H` and `A:H` because the write path allows poisoning or destruction of another user's knowledge base ## Default Configuration Reachability Reachable in default configuration. All affected endpoints require only `get_verified_user`, not `get_admin_user`, so any non-admin account in a typical multi-user deployment can reach them. The only prerequisite beyond authentication is knowledge of a target knowledge base UUID, which is reflected in the `AC:H` score. However, KB UUIDs are stable identifiers that leak through normal usage rather than secrets (see Prerequisites below). ## Root Cause Knowledge base embeddings are stored in vector DB collections named with the knowledge base's UUID (e.g., `550e8400-e29b-41d4-a716-446655440000`). The `_validate_collection_access` function only blocks two specific prefixes: ```python # backend/open_webui/routers/retrieval.py lines 2330-2355 def _validate_collection_access(collection_names: list[str], user) -> None: if user.role == "admin": return for name in collection_names: if name.startswith("user-memory-") and name != f"user-memory-{user.id}": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED, ) elif name.startswith("file-"): file_id = name[len("file-"):] if not has_access_to_file( file_id=file_id, access_type="read", user=user, ): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED, ) # No else clause -- knowledge base UUIDs pass through unchecked ``` Knowledge base UUIDs do not match either prefix, so the function returns without raising an exception. The query then executes against the vector DB with no further authorization check. ## Vulnerable Endpoints ### Read Endpoints Both retrieval query endpoints accept a collection name and call `_validate_collection_access` as their sole authorization gate: 1. `POST /api/v1/retrieval/query/doc` (line 2367) -- single `collection_name` 2. `POST /api/v1/retrieval/query/collection` (line 2432) -- list of `collection_names` ### Write Endpoints The following endpoints accept a `collection_name` parameter and write to the target collection without checking whether the caller owns it: 3. `POST /api/v1/retrieval/process/text` (line 1777) -- appends attacker-controlled content to the target collection 4. `POST /api/v1/retrieval/process/file` (line 1528) -- validates ownership of the uploaded file but not the destination collection 5. `POST /api/v1/retrieval/process/files/batch` (line 2578) -- same as above for multiple files 6. `POST /api/v1/retrieval/process/web` and `POST /api/v1/retrieval/process/youtube` (lines 1810-1811) -- same handler; `overwrite` d
- CVSS 3.1
- CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-639
- Also known as
- CVE-2026-45398, PYSEC-2026-2699
More Open WebUI advisories
All Open WebUI| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| May 14 | Open WebUI: LDAP and OAuth First-User Race Condition Allows Multiple Admin Accounts | High8.1 | 0.9.0 |
| May 14 | Open WebUI: Jupyter code execution works despite `ENABLE_CODE_EXECUTION=false` , feature gate bypassed | High8.8 | 0.8.12 |
| May 14 | Open WebUI: shared-chat branch ignores access_type, allowing unauthorized file deletion | High8.0 | 0.9.0 |
| May 14 | Open WebUI: Unauthenticated endpoint can trigger embedding generation (cost/DoS) | Medium6.5 | 0.8.0 |
| May 14 | Open WebUI has an Indirect Object Reference (IDOR) in user notes | Medium6.5 | 0.8.11 |
| May 14 | Open WebUI: insecure direct object reference | High8.1 | 0.9.5 |