Jul 24, 2026·6 min read·36 visits
Authenticated users can read private messages and channel threads they do not own by exploiting missing channel-binding validation in thread parent-message lookups.
A Broken Object Level Authorization (BOLA) / Insecure Direct Object Reference (IDOR) vulnerability in Open WebUI prior to v0.10.0 allows authenticated users to access and disclose private message contents, thread context, and channel metadata from other restricted private or Direct Message (DM) channels without proper authorization.
Open WebUI is a self-hosted, extensible AI platform designed to provide a rich chat interface for various language models. In versions prior to v0.10.0, the platform contains an Insecure Direct Object Reference (IDOR) vulnerability within its channel-messaging architecture. This vulnerability resides in the thread retrieval and message creation APIs.
An authenticated user can bypass intended logical access controls to view restricted message histories and thread context from other channels. The root of this exposure stems from a disjointed authorization model. The application validates permissions on the channel level but fails to assert logical ownership boundaries for referenced message resources.
Consequently, the vulnerability threatens the confidentiality of direct messages and private group conversations within the application instance. Organizations deploying Open WebUI in multi-tenant or multi-user environments are especially susceptible, as internal users may access sensitive interactions of other personnel.
The root cause of CVE-2026-59215 is a Broken Object Level Authorization (BOLA) flaw in the database lookup routines of backend/open_webui/models/messages.py. The routing layer handles incoming requests to retrieve message threads using the endpoint /api/v1/channels/{id}/messages/{message_id}/thread. At this layer, the server verifies that the requesting user belongs to the channel specified by {id}.
However, once the router completes this check, it executes get_messages_by_parent_id(channel_id, parent_id). The implementation of this function relies entirely on db.get(Message, parent_id) to load the parent message from the database. It fails to verify if the retrieved Message object actually has a channel_id matching the authorized {id} from the API route.
Similarly, on the message creation path, the handler new_message_handler inside backend/open_webui/routers/channels.py accepts parent and reply identifiers from the user request payload. The backend inserts these values into the database without confirming that the target messages are bound to the current channel. This architectural disconnect allows users to query and link data across separate authorization domains.
The vulnerability is fixed in Open WebUI commit a66477b7104c5d141ce7bffaea424b43e7666ef1 by enforcing strict boundary assertions. In the vulnerable code path inside backend/open_webui/models/messages.py, the thread loading routine returned any existing message record regardless of its relationship to the requested channel:
# Vulnerable Implementation
async def get_messages_by_parent_id(channel_id: str, parent_id: str, ...):
async with get_async_db_context(db) as db:
message = await db.get(Message, parent_id)
if not message:
return []The patch addresses this issue by introducing a validation condition that checks whether the parent message is associated with the channel specified in the API path. If the channel IDs do not match, the system rejects the lookup and returns an empty list:
# Patched Implementation
async def get_messages_by_parent_id(
channel_id: str,
parent_id: str,
limit: Optional[int] = None,
db: AsyncSession = None,
) -> list[MessageModel]:
async with get_async_db_context(db) as db:
message = await db.get(Message, parent_id)
# Thread parent must belong to the requested channel; never disclose a foreign-channel message.
if not message or message.channel_id != channel_id:
return []Additionally, the message creation handler in backend/open_webui/routers/channels.py is updated to prevent cross-channel thread binding. The patched code verifies that the referenced message identifiers specified as parent_id or reply_to_id belong to the same channel context:
# Thread parent / reply target must belong to this channel (no cross-channel binding).
for ref_id in (form_data.parent_id, form_data.reply_to_id):
if ref_id:
ref = await Messages.get_message_by_id(ref_id, include_thread_replies=False, db=db)
if not ref or ref.channel_id != channel.id:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.DEFAULT())An attacker must meet specific requirements to exploit this vulnerability. The primary constraint is that the attacker must have valid authenticated access to the target Open WebUI instance. Furthermore, the attacker must have read permissions for at least one channel, which we designate as <Attacker_Channel_ID>.
To retrieve a private message from a restricted channel, the attacker must supply the victim's target message identifier, <Victim_Message_ID>. In installations where message identifiers are sequential, the attacker can systematically sweep the ID space. If the system uses randomized identifiers, exploitation requires a secondary side-channel leak or predictive context.
The attacker issues a crafted HTTP GET request to their own authorized channel endpoint, but specifies the victim's message identifier in the message path. The routing logic passes the permission check because the attacker owns the channel in the path, while the database retrieves and returns the victim's message details.
GET /api/v1/channels/<Attacker_Channel_ID>/messages/<Victim_Message_ID>/thread HTTP/1.1
Host: target-openwebui.local
Authorization: Bearer <Attacker_JWT_Token>The security impact of CVE-2026-59215 is classified as Low on the standard CVSS scale, primarily because of the high attack complexity involved in guessing or acquiring valid target message identifiers. The base score of 3.1 is calculated with the vector CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N. This score reflects low confidentiality impact, with no direct integrity or availability compromise.
Despite the Low severity rating, the real-world impact inside a shared environment can be considerable. An attacker who successfully guesses or extracts active message IDs can reconstruct entire conversation contexts, read sensitive documents, and expose proprietary metadata. This constitutes a direct breakdown of multi-tenant isolation boundaries.
There is no evidence of active exploitation in the wild, and the vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog. The EPSS score is 0.00255, denoting a very low probability of automated exploitation within 30 days. This is common for logic-based authorization bugs that require specific contextual parameters to exploit.
The recommended remediation strategy is to upgrade Open WebUI to version v0.10.0 or later. This release incorporates the official patches that validate channel-binding constraints on both read and write operations, neutralizing both message exposure and cross-channel thread injection.
In scenarios where immediate patching is not feasible, administrators should audit application access logs for anomaly detection. Security teams should monitor for elevated request rates targeting the thread endpoint. Specifically, look for requests to /api/v1/channels/{id}/messages/{message_id}/thread where {id} represents different values for the same authenticated user.
Additionally, developers can configure logging to flag scenarios where the database-resolved channel_id of a message does not match the channel identifier provided in the API route context. This divergence is a strong indicator of unauthorized resource enumeration attempts.
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Open WebUI open-webui | < v0.10.0 | v0.10.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-639 (Authorization Bypass Through User-Controlled Key) |
| Attack Vector | Network (AV:N) |
| CVSS v3.1 Score | 3.1 (Low) |
| Exploit Status | None / Proof-of-Concept |
| Affected Versions | < v0.10.0 |
| Fixed Version | v0.10.0 |
The system fails to restrict access to resources to only authorized users, allowing attackers to access unauthorized resources by modifying the parameter value.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.