CVE Patch Review

CVE-2026-59213: Root-Cause Cache Key Fix in Open WebUI

CVE-2026-59213 · Updated 2026-07-24 Root-cause

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.

Sources