## Summary Several direct, index-addressed Ollama proxy routes accept a caller-supplied `url_idx` path parameter and use it as a raw index into the admin-configured `OLLAMA_BASE_URLS` list. Access control on these routes validates only whether the user may use the requested *model*, never which...
Full CISO analysis pending enrichment.
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Open WebUI | pip | <= 0.9.5 | 0.9.6 |
Do you use Open WebUI? You're affected.
How severe is it?
What is the attack surface?
What should I do?
Patch available
Update Open WebUI to version 0.9.6
Which compliance frameworks are affected?
Compliance analysis pending. Sign in for full compliance mapping when available.
Frequently Asked Questions
What is CVE-2026-54021?
## Summary Several direct, index-addressed Ollama proxy routes accept a caller-supplied `url_idx` path parameter and use it as a raw index into the admin-configured `OLLAMA_BASE_URLS` list. Access control on these routes validates only whether the user may use the requested *model*, never which *backend* the request is routed to. Any authenticated user can append an arbitrary `url_idx` to force their request onto an Ollama backend they were never authorized to reach, including internal, higher-privilege, or explicitly admin-disabled backends. ## Affected endpoints All indexed Ollama routes that resolve the backend through `get_ollama_url()`: ``` POST /ollama/api/chat/{url_idx} POST /ollama/api/generate/{url_idx} POST /ollama/api/embed/{url_idx} POST /ollama/api/embeddings/{url_idx} POST /ollama/v1/chat/completions/{url_idx} POST /ollama/v1/completions/{url_idx} POST /ollama/v1/messages/{url_idx} POST /ollama/v1/responses/{url_idx} ``` ## Root cause `backend/open_webui/routers/ollama.py` — `get_ollama_url()` consults the model-to-backend allow-list (`OLLAMA_MODELS[model]["urls"]`) only when `url_idx` is omitted. When the caller supplies `url_idx`, that mapping is skipped and the value is used directly as an index: ```python async def get_ollama_url(request: Request, model: str, url_idx: Optional[int] = None): if url_idx is None: models = request.app.state.OLLAMA_MODELS if model not in models: raise HTTPException(...) url_idx = random.choice(models[model].get("urls", [])) url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] # caller-controlled, no authz return url, url_idx ``` The outbound request is then sent to that backend using the backend's own configured API key. Backends an admin has disabled (`OLLAMA_API_CONFIGS["<idx>"].enable = false`) are hidden from model discovery but remain reachable through the indexed route, because the disabled state is never re-checked at request time. ## Impact A verified, non-admin user with read access to any single model can: - route requests to internal / higher-capability / restricted Ollama backends in multi-backend deployments, bypassing backend-level isolation; - reach backends the admin has explicitly disabled; - have those requests authenticated with the target backend's configured API key (the key is used server-side; it is not returned to the attacker); - consume the restricted backend's compute. There is no cross-user data disclosure and no exfiltration of the backend credential itself; the impact is unauthorized access to, and use of, restricted backend resources. ## Affected / Patched - Affected: `<= 0.9.5` - Patched: `>= 0.9.6` ## Fix 0.9.6 adds `validate_ollama_backend_idx()`, invoked on every indexed route (directly and via `get_ollama_url()`), which returns 403 for any non-admin caller-supplied `url_idx` that is not in the requested model's allowed `urls`. Because disabled backends are absent from every model's `urls`, the same check also blocks routing to disabled backends.
Is CVE-2026-54021 actively exploited?
No confirmed active exploitation of CVE-2026-54021 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-54021?
Update to patched version: Open WebUI 0.9.6.
What is the CVSS score for CVE-2026-54021?
CVE-2026-54021 has a CVSS v3.1 base score of 6.3 (MEDIUM). The EPSS exploitation probability is 0.04%.
What are the technical details?
Original Advisory
## Summary Several direct, index-addressed Ollama proxy routes accept a caller-supplied `url_idx` path parameter and use it as a raw index into the admin-configured `OLLAMA_BASE_URLS` list. Access control on these routes validates only whether the user may use the requested *model*, never which *backend* the request is routed to. Any authenticated user can append an arbitrary `url_idx` to force their request onto an Ollama backend they were never authorized to reach, including internal, higher-privilege, or explicitly admin-disabled backends. ## Affected endpoints All indexed Ollama routes that resolve the backend through `get_ollama_url()`: ``` POST /ollama/api/chat/{url_idx} POST /ollama/api/generate/{url_idx} POST /ollama/api/embed/{url_idx} POST /ollama/api/embeddings/{url_idx} POST /ollama/v1/chat/completions/{url_idx} POST /ollama/v1/completions/{url_idx} POST /ollama/v1/messages/{url_idx} POST /ollama/v1/responses/{url_idx} ``` ## Root cause `backend/open_webui/routers/ollama.py` — `get_ollama_url()` consults the model-to-backend allow-list (`OLLAMA_MODELS[model]["urls"]`) only when `url_idx` is omitted. When the caller supplies `url_idx`, that mapping is skipped and the value is used directly as an index: ```python async def get_ollama_url(request: Request, model: str, url_idx: Optional[int] = None): if url_idx is None: models = request.app.state.OLLAMA_MODELS if model not in models: raise HTTPException(...) url_idx = random.choice(models[model].get("urls", [])) url = request.app.state.config.OLLAMA_BASE_URLS[url_idx] # caller-controlled, no authz return url, url_idx ``` The outbound request is then sent to that backend using the backend's own configured API key. Backends an admin has disabled (`OLLAMA_API_CONFIGS["<idx>"].enable = false`) are hidden from model discovery but remain reachable through the indexed route, because the disabled state is never re-checked at request time. ## Impact A verified, non-admin user with read access to any single model can: - route requests to internal / higher-capability / restricted Ollama backends in multi-backend deployments, bypassing backend-level isolation; - reach backends the admin has explicitly disabled; - have those requests authenticated with the target backend's configured API key (the key is used server-side; it is not returned to the attacker); - consume the restricted backend's compute. There is no cross-user data disclosure and no exfiltration of the backend credential itself; the impact is unauthorized access to, and use of, restricted backend resources. ## Affected / Patched - Affected: `<= 0.9.5` - Patched: `>= 0.9.6` ## Fix 0.9.6 adds `validate_ollama_backend_idx()`, invoked on every indexed route (directly and via `get_ollama_url()`), which returns 403 for any non-admin caller-supplied `url_idx` that is not in the requested model's allowed `urls`. Because disabled backends are absent from every model's `urls`, the same check also blocks routing to disabled backends.
Weaknesses (CWE)
CWE-863 — Incorrect Authorization: The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.
- [Architecture and Design] Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
- [Architecture and Design] Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L References
Timeline
Related Vulnerabilities
CVE-2026-44551 9.1 open-webui: LDAP auth bypass — full account takeover
Same package: open-webui CVE-2026-45672 8.8 open-webui: code exec gate bypass via API endpoint
Same package: open-webui CVE-2026-44552 8.7 open-webui: Redis cache poisoning enables cross-instance tool hijack
Same package: open-webui CVE-2025-64495 8.7 Open WebUI: XSS-to-RCE via malicious prompt injection
Same package: open-webui CVE-2026-45315 8.7 open-webui: stored XSS → JWT theft and admin takeover
Same package: open-webui