Every CVE Search/ Get API key

CVE-2026-59213

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

3.5 LowFix available

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.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
Low
Integrity
None
Availability
None

Exploit likelihood

0.37%Up 0.1 points since Jul 10, 2026
90%50%10%1%

What each source reports

CVE List Score used 3.5

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

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.

Record
CVE-2026-59213
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Weakness
CWE-524
Updated
2026-11-02
EUVDEUVD-2026-42629 3.5

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.

Record
EUVD-2026-42629
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-3wp3-xxj9-5jqq 3.5

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

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:

@cached(
    ttl=MODELS_CACHE_TTL,
    key_builder=lambda _func, request, user=None: (
        f'openai_all_models_{user.id}' if user else 'openai_all_models'
    ),
)
Record
GHSA-3wp3-xxj9-5jqq
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Weakness
CWE-524
Updated
2026-11-02
NVD 3.5

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.

Record
CVE-2026-59213
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
CVSS 3.1
5.0 MediumCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:N/A:N
Weakness
CWE-524
Updated
2026-11-02
OSV 3.5

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

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.

Record
CVE-2026-59213
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Weakness
CWE-524
Updated
2026-11-02
OSVGHSA-3wp3-xxj9-5jqq 3.5

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

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:

@cached(
    ttl=MODELS_CACHE_TTL,
    key_builder=lambda _func, request, user=None: (
        f'openai_all_models_{user.id}' if user else 'openai_all_models'
    ),
)
Record
GHSA-3wp3-xxj9-5jqq
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Weakness
CWE-524
Updated
2026-11-02
OSVPYSEC-2026-3589 3.5

Open WebUI: Cross-user model-list exposure via static cache key in get_all_models (aiocache key= vs key_builder= misuse)

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:

@cached(
    ttl=MODELS_CACHE_TTL,
    key_builder=lambda _func, request, user=None: (
        f'openai_all_models_{user.id}' if user else 'openai_all_models'
    ),
)
Record
PYSEC-2026-3589
CVSS 3.1
3.5 LowCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:N/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
open-webui
PyPI
0.6.27 up to 0.10.0
0.10.0
open-webui
PyPI
0.6.27 up to 0.10.0, plus listed versions
0.6.280.6.290.6.300.6.310.6.32
Show 34 moreShow less
0.6.330.6.340.6.350.6.360.6.370.6.380.6.390.6.400.6.410.6.420.6.430.7.00.7.10.7.20.8.00.8.10.8.100.8.110.8.120.8.20.8.30.8.40.8.50.8.60.8.70.8.80.8.90.9.00.9.10.9.20.9.30.9.40.9.50.9.6
0.10.0

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-59213 is a low vulnerability (CVSS 3.5) in Openwebui Open Webui, published July 9, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.37%, the 31st percentile. Fixed in open-webui 0.10.0.

References

MoveEnter Open