PT-2026-59350 · Pypi · Open-Webui

Published

2026-07-13

·

Updated

2026-07-13

CVSS v3.1

5.3

Medium

VectorAV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Vulnerability Type: Information Disclosure / Missing Authentication Severity: Medium Component: backend/open webui/routers/retrieval.pyget status() (GET /) Affected Endpoint: GET /api/v1/retrieval/ Affected Version: Open WebUI main branch — confirmed unpatched through v0.9.2 Authentication Required: None — internet-facing with zero credentials CVSSv3.1 Score: 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Summary

GET /api/v1/retrieval/ returns live RAG pipeline configuration to any unauthenticated HTTP client. No Authorization header, cookie, or API key is required. Every adjacent endpoint on the same router (/embedding, /config) is correctly guarded by get admin user making this a targeted omission.

Root Cause

backend/open webui/routers/retrieval.py:262
python
@router.get('/')
async def get status(request: Request):  # ← no Depends(get verified user)
  return {
    'status': True,
    'CHUNK SIZE': request.app.state.config.CHUNK SIZE,
    'CHUNK OVERLAP': request.app.state.config.CHUNK OVERLAP,
    'RAG TEMPLATE': request.app.state.config.RAG TEMPLATE,
    'RAG EMBEDDING ENGINE': request.app.state.config.RAG EMBEDDING ENGINE,
    'RAG EMBEDDING MODEL': request.app.state.config.RAG EMBEDDING MODEL,
    'RAG RERANKING MODEL': request.app.state.config.RAG RERANKING MODEL,
    'RAG EMBEDDING BATCH SIZE': request.app.state.config.RAG EMBEDDING BATCH SIZE,
    'ENABLE ASYNC EMBEDDING': request.app.state.config.ENABLE ASYNC EMBEDDING,
    'RAG EMBEDDING CONCURRENT REQUESTS': request.app.state.config.RAG EMBEDDING CONCURRENT REQUESTS,
  }
Compare with every adjacent endpoint on the same router:
python
@router.get('/embedding')
async def get embedding config(request: Request, user=Depends(get admin user)): # ✅

@router.get('/config')
async def get rag config(request: Request, user=Depends(get admin user)):    # ✅

Proof Of Concept — No Token Required

bash
curl -s http://TARGET/api/v1/retrieval/
json
{
 "status": true,
 "CHUNK SIZE": 1000,
 "CHUNK OVERLAP": 100,
 "RAG TEMPLATE": "### Task:
Respond to the user query using the provided context...
<context>
{{CONTEXT}}
</context>",
 "RAG EMBEDDING ENGINE": "",
 "RAG EMBEDDING MODEL": "sentence-transformers/all-MiniLM-L6-v2",
 "RAG RERANKING MODEL": "",
 "RAG EMBEDDING BATCH SIZE": 1,
 "ENABLE ASYNC EMBEDDING": true,
 "RAG EMBEDDING CONCURRENT REQUESTS": 0
}

Disclosed Information and Its Value to an Attacker

FieldWhat it reveals
RAG EMBEDDING ENGINEBackend type (OpenAI, Ollama, Azure, etc.)
RAG EMBEDDING MODELExact model name — reveals embedding model
RAG RERANKING MODELReranker in use — reveals reranker
RAG TEMPLATERAG template — exposes the RAG template
CHUNK SIZE / CHUNK OVERLAPChunking parameters — enables exact reconstruction of how documents are split and retrieved

Attack Scenario

  1. Attacker sends one unauthenticated HTTP GET to /api/v1/retrieval/.
  2. Response reveals the embedding model and chunking parameters.
  3. Attacker uses the exact chunk size/overlap to craft RAG poisoning payloads that are guaranteed to be retrieved.

Impact

  1. RAG template disclosure
  2. Infrastructure fingerprinting — embedding engine and model name reveal the AI stack to an internet scanner
  3. RAG attack surface mapping — chunk parameters enable precise calculation of retrieval boundaries
  4. Zero-effort recon — no brute force, no credentials, no rate-limit concern. Single request from any IP.

Recommended Fix

Add get verified user dependency (or get admin user for stricter control):
python
# BEFORE (vulnerable)
@router.get('/')
async def get status(request: Request):


# AFTER
@router.get('/')
async def get status(request: Request, user=Depends(get verified user)):

Fix

Found an issue in the description? Have something to add? Feel free to write us 👾

Related Identifiers

PYSEC-2026-2706

Affected Products

Open-Webui