CVE-2026-59213: Root-Cause Cache Key Fix in Open WebUI
Summary
The patch corrects misuse of aiocache by replacing a static `key=` configuration with `key_builder=` in two model-listing routers. This change restores per-request cache key derivation based on `user.id`, preventing cross-session reuse of cached model metadata during the TTL window.
Analysis
Vulnerability
CVE-2026-59213 describes an authorization bypass and cross-session cache leakage issue in Open WebUI. The vulnerable code attempted to scope cached model-list responses by user, but it passed a lambda to the aiocache decorator's key= parameter instead of the per-call hook. As documented by the patch itself, in aiocache 0.12 key= is treated as a static key, so supplying key=lambda ... caused callers to collapse onto one shared cache entry rather than generating a distinct key per request. With a 1-second TTL, a low-privileged user could receive model metadata cached from a different session, including restricted model listings, if requests overlapped within the cache window.
The issue affects both the Ollama and OpenAI model-list routers referenced in the upstream fix and associated pull request: commit 0fc630b and PR #25783. Additional vulnerability context is recorded by MITRE.
# Vulnerable pattern
key=lambda _, user: f'openai_all_models_{user.id}' if user else 'openai_all_models',
# Because `key=` is static in aiocache 0.12, this does not derive a per-user key
# and can collapse requests into a shared cache entry.Patch
The patch changes the decorator configuration in both affected files from key=... to key_builder=..., which is the aiocache 0.12 mechanism for computing a cache key per invocation. The new callback signature includes the wrapped function and request object, and still derives the cache namespace from user.id when a user is present.
# backend/open_webui/routers/openai.py and backend/open_webui/routers/ollama.py
# key_builder (not key) is the per-call hook in aiocache 0.12; `key=` is a
# static key, so a `key=lambda` collapsed every caller to one shared entry.
key_builder=lambda _func, request, user=None: f'openai_all_models_{user.id}' if user else 'openai_all_models',This is a narrowly targeted fix that directly addresses the implementation error identified in the upstream commit: https://github.com/open-webui/open-webui/commit/0fc630b34b2899599dabffffa012afd47599aa75. The same change is mirrored for the Ollama router in the same patch set and review thread: https://github.com/open-webui/open-webui/pull/25783.
Review
Pros
- The patch directly fixes the root implementation mistake: using a static decorator parameter where a per-call key derivation hook was required.
- It applies the correction consistently in both affected routers, reducing the chance of one backend remaining vulnerable.
- The inline comment is technically useful and explains the exact semantic mismatch in aiocache 0.12, which should help prevent regression.
- Per-user cache partitioning is restored without changing endpoint behavior or authorization logic, making the fix low risk and easy to reason about.
Cons
- The patch is narrowly scoped to the two known call sites; it does not demonstrate a broader audit for similar misuse of caching decorators elsewhere in the codebase.
- The fallback branch for unauthenticated access still uses a shared key, which is acceptable only if anonymous callers are intended to see the same model set; that assumption should be validated by tests and policy.
- No test changes are shown in the provided sources, so there is no source-grounded evidence here of regression coverage for cross-user cache isolation.
- The fix addresses cache-key isolation but does not add defense-in-depth measures such as disabling caching for authorization-sensitive responses or asserting user context in cache wrappers.
Verdict
Root-cause.
The patch corrects the actual cause of the leakage: incorrect aiocache API usage that converted intended per-user cache partitioning into a shared cache entry. By switching to key_builder=, the cache key is again derived per invocation and keyed by user.id, which is the necessary control to stop cross-session model metadata exposure described in NVD. The remaining concerns are around assurance and coverage, not the correctness of the remediation itself.
Recommended Labs
Try this vulnerability pattern yourself with hands-on labs.
- Privilege Escalation.py
Best direct match for the Open WebUI issue’s authorization-bypass aspect. This Python/FastAPI lab maps to broken object-level authorization style weaknesses (CWE-639/CWE-266, OWASP A01:2021) and is useful for practising defensive fixes that ensure responses are scoped to the requesting user rather than leaked across privilege boundaries.
- OAuth.py
Useful for the identity and authorization-validation side of this vulnerability. While not a cache-leak lab specifically, it focuses on authentication/authorization decision integrity in a Python web context and helps reinforce defensive patterns for verifying caller identity before exposing restricted data.
- Polluted access.ts
Strong complementary lab for practising access-control failures that can expose data across trust boundaries. Although it is TypeScript rather than Python, it is highly relevant to the same defensive theme as CVE-2026-59213: enforcing per-request authorization context and preventing unintended cross-user data exposure.