CVE-2026-59213
mediumPriorität · verfolgen · 20EPSS 0.004 · 30. PerzentilEUUSEPSS · bewertet 2026-10-23
Open WebUI is an extensible, feature-rich, and user-friendly self-hosted AI platform. From 0.6.27 before 0.10.0, get_all_models handlers in routers/openai.py and routers/ollama.py passed a lambda to aiocache key instead of key_builder, causing permission-filtered per-user model lists to share a static cache entry and exposing one user’s model list to another caller during the TTL window. This issue is fixed in version 0.10.0.
cvss
Technischer Schweregrad, 0–10. Eine Zeile je Quelle.
Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen⚠ Quellen uneinig · low–medium · 3.5–5
SSVC
Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.
schwächen
Die CWE-Schwächeklassen, zu denen dies gehört.
betroffene Produkte (3)
Betroffene Produkte und Versionsbereiche.
Advisories (2)
Hersteller- und Ökosystem-Meldungen dazu.
- GHSA-3wp3-xxj9-5jqqOpen WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)2026-07-24ghsa · osvUS
## Summary The `get_all_models` handlers in `routers/openai.py` and `routers/ollama.py` intended to cache their **permission-filtered** model lists per user, but the `@cached` decorator was misconfigured: it passed a `key=` lambda instead of `key_builder=`. In aiocache 0.12.3 (the pinned version), `key=` is a **static** cache key — a callable passed there is used as a constant object, not invoked per call. As a result the per-user key was never computed, and all callers collided onto a single shared cache entry within the TTL window. During that window, one user's permission-filtered model list could be served to a different authenticated user, crossing the per-user authorization boundary. ## Impact - **Boundary crossed:** Confidentiality (cross-user). A caller can receive the model list scoped to a *different* security principal than themselves. - A user (or admin, or — depending on endpoint reachability — anonymous caller) who populates the cache causes the next caller within the TTL to receive *that* list rather than their own permission-filtered one. - What's disclosed is the set of models another principal can access, including potentially the existence and naming of models restricted from the receiving user. - Exposure is **incidental and timing-dependent**, not attacker-controlled: the leaked entry is whatever the most recent caller populated within `MODELS_CACHE_TTL` (default 1 second), and the attacker cannot select the victim or force a target's list into the cache. ## Affected component - `backend/open_webui/routers/openai.py` — `get_all_models` (~line 488) - `backend/open_webui/routers/ollama.py` — `get_all_models` (~line 302) Both decorated with `@cached(ttl=MODELS_CACHE_TTL, key=lambda ...)`. No other `@cached(... key=lambda ...)` misuse was found elsewhere in the backend. ## Root cause aiocache 0.12's `@cached` treats `key=` as a static key; the per-call hook is `key_builder=` with signature `key_builder(func, *args, **kwargs)`. Passing a callable to `key=` uses the callable object itself as a constant key, so every invocation resolved to the same entry and the intended per-`user.id` namespacing never occurred. ## Reproduction (default config) 1. On a default deployment, configure at least two users with *different* model-access permissions (e.g. one model restricted to user A). 2. As user A, request the model list (populates the shared cache entry). 3. Within `MODELS_CACHE_TTL` (default 1s), as user B, request the model list. 4. User B receives user A's permission-filtered list, including models B is not permitted to see. ## Remediation Replace `key=` with `key_builder=` at both call sites and adjust the lambda to take the function as its first argument: ```python @cached( ttl=MODELS_CACHE_TTL, key_builder=lambda _func, request, user=None: ( f'openai_all_models_{user.id}' if user else 'openai_all_models' ), ) ```
- PYSEC-2026-3589Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)2026-08-04vendor · osvUS
## Summary The `get_all_models` handlers in `routers/openai.py` and `routers/ollama.py` intended to cache their **permission-filtered** model lists per user, but the `@cached` decorator was misconfigured: it passed a `key=` lambda instead of `key_builder=`. In aiocache 0.12.3 (the pinned version), `key=` is a **static** cache key — a callable passed there is used as a constant object, not invoked per call. As a result the per-user key was never computed, and all callers collided onto a single shared cache entry within the TTL window. During that window, one user's permission-filtered model list could be served to a different authenticated user, crossing the per-user authorization boundary. ## Impact - **Boundary crossed:** Confidentiality (cross-user). A caller can receive the model list scoped to a *different* security principal than themselves. - A user (or admin, or — depending on endpoint reachability — anonymous caller) who populates the cache causes the next caller within the TTL to receive *that* list rather than their own permission-filtered one. - What's disclosed is the set of models another principal can access, including potentially the existence and naming of models restricted from the receiving user. - Exposure is **incidental and timing-dependent**, not attacker-controlled: the leaked entry is whatever the most recent caller populated within `MODELS_CACHE_TTL` (default 1 second), and the attacker cannot select the victim or force a target's list into the cache. ## Affected component - `backend/open_webui/routers/openai.py` — `get_all_models` (~line 488) - `backend/open_webui/routers/ollama.py` — `get_all_models` (~line 302) Both decorated with `@cached(ttl=MODELS_CACHE_TTL, key=lambda ...)`. No other `@cached(... key=lambda ...)` misuse was found elsewhere in the backend. ## Root cause aiocache 0.12's `@cached` treats `key=` as a static key; the per-call hook is `key_builder=` with signature `key_builder(func, *args, **kwargs)`. Passing a callable to `key=` uses the callable object itself as a constant key, so every invocation resolved to the same entry and the intended per-`user.id` namespacing never occurred. ## Reproduction (default config) 1. On a default deployment, configure at least two users with *different* model-access permissions (e.g. one model restricted to user A). 2. As user A, request the model list (populates the shared cache entry). 3. Within `MODELS_CACHE_TTL` (default 1s), as user B, request the model list. 4. User B receives user A's permission-filtered list, including models B is not permitted to see. ## Remediation Replace `key=` with `key_builder=` at both call sites and adjust the lambda to take the function as its first argument: ```python @cached( ttl=MODELS_CACHE_TTL, key_builder=lambda _func, request, user=None: ( f'openai_all_models_{user.id}' if user else 'openai_all_models' ), ) ```
auch bekannt als (6)
Weitere Namen und Kennungen dieser Entität.
quellen
Welche Quellen diesen Datensatz belegen und wann.
Referenzen (12)
Externe Belege — Patches, Meldungen, Analysen.
- https://github.com/open-webui/open-webui/commit/0fc630b34b2899599dabffffa012afd47599aa75cnnvd
- https://github.com/open-webui/open-webui/pull/25783cnnvd
- https://github.com/open-webui/open-webui/releases/tag/v0.10.0cnnvd
- https://github.com/open-webui/open-webui/security/advisories/GHSA-3wp3-xxj9-5jqqcnnvd
- https://github.com/open-webui/open-webui/commit/0fc630b34b2899599dabffffa012afd47599aa75enisa_euvd
- https://github.com/open-webui/open-webui/pull/25783enisa_euvd
- https://github.com/open-webui/open-webui/releases/tag/v0.10.0enisa_euvd
- https://github.com/open-webui/open-webui/security/advisories/GHSA-3wp3-xxj9-5jqqenisa_euvd
Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.
Kostenloser Scan