Sep 11, 2026·7 min read·3 visits
A session desynchronization flaw in Open WebUI lets demoted administrators retain administrative read/write access to all users' collaborative notes via active, uninvalidated Socket.IO connections.
Open WebUI from version 0.9.0 to 0.11.1 is vulnerable to a state desynchronization and privilege persistence flaw. When an administrator is demoted to a standard user via Single Sign-On (SSO) role synchronization, the local database is updated, but their active Socket.IO connection is not invalidated. Because the WebSocket handlers authorize operations using the cached role in the socket context, the demoted user retains administrative read and write access to all collaborative notes.
Open WebUI relies on persistent, real-time communication channels to facilitate features such as streaming completions, system status updates, and collaborative document editing. The underlying architecture integrates a stateful Socket.IO server alongside its standard HTTP REST API endpoints to manage these high-frequency, bidirectional streams. During the initial WebSocket handshake, the backend authenticates the client using their token, resolves their access permissions, and caches their current database role within the memory-resident socket session context. This design is highly efficient for serving rapid real-time updates as it eliminates the overhead of executing relational database queries for every websocket frame.
The vulnerability, designated as CVE-2026-87014, arises from a synchronization failure between the application's relational database and these memory-cached WebSocket connection states. When an administrative user is demoted to a standard user through automated Single Sign-On (SSO) mechanisms—such as reverse-proxy trusted role headers or OAuth group mapping—the role update is written exclusively to the database. The active Socket.IO connection remains open and completely untouched, retaining its stale, cached administrative privilege levels.
This desynchronization bypasses the security boundaries of the platform's authorization model. Since the WebSocket event handlers validate incoming user actions against the cached connection state rather than querying the relational database for each frame, the demoted user retains administrative read and write privileges over restricted resources. Specifically, this allows the demoted user to read, edit, or delete collaborative notes belonging to any other user on the system, completely undermining tenant isolation.
The primary root cause of this security vulnerability lies in the asymmetric implementation of session-management and invalidation routines within the Open WebUI platform. When an administrator manually demotes a user's role via the local administrative HTTP API (located in backend/open_webui/routers/users.py), the controller explicitly invokes the disconnect_user_sessions helper. This helper is designed to forcefully terminate all active Socket.IO connections tied to that user's ID, forcing a client reconnection and re-authentication cycle that synchronizes the privilege states.
However, this termination logic was entirely omitted in the automated, dynamic synchronization pathways used by external Identity Providers (IdPs). Specifically, during SSO reverse-proxy trusted header parsing (handled in backend/open_webui/routers/auths.py) and OAuth group-to-role mappings (handled in backend/open_webui/utils/oauth.py), the application directly executes database update queries. The backend modifies the role field within the database row representing the user, but the existing stateful TCP connections and their memory-cached variables are left intact without any session invalidation.
Because Socket.IO represents a long-lived stateful connection, the handler authorization checks are designed to optimize database performance by reading metadata directly from the connection's session object. The system assumes that any change in user privileges will be pushed to the connection, but the lack of an event framework or direct coupling between the SSO controllers and the Socket.IO subsystem allows this assumption to fail under normal operating conditions. This structural gap allows the in-memory cache to remain privileged while the primary database registry registers the demotion.
Analysis of the vulnerable codebase reveals that the trusted-header and OAuth authentication flows executed isolated database updates. In backend/open_webui/routers/auths.py, the trusted-header authentication routine updated user roles using the following pattern:
if trusted_role in {'admin', 'user', 'pending'}:
if user.role != trusted_role:
await Users.update_user_role_by_id(user.id, trusted_role, db=db)This pattern changed the database row but failed to notify the Socket.IO server. A similar omission was present in backend/open_webui/utils/oauth.py, which updated database records during mapping operations without triggering session invalidations.
The remediation patch introduced an event-driven synchronization architecture by registering SocketSessionEventSink in backend/open_webui/events.py. This sink handles USER_ROLE_UPDATED events globally, ensuring that any component modifying a user's role publishes an event that resolves to a WebSocket disconnection call. The patched auth controller now executes the following sequence:
if trusted_role in {'admin', 'user', 'pending'}:
if user.role != trusted_role:
updated_user = await Users.update_user_role_by_id(user.id, trusted_role, db=db)
if updated_user:
user = updated_user
await publish_event(
request,
EVENTS.USER_ROLE_UPDATED,
actor=updated_user,
subject_id=updated_user.id,
source='trusted_header',
data={'role': updated_user.role},
)Additionally, the session invalidation function disconnect_user_sessions within backend/open_webui/socket/main.py was hardened. The original implementation queried only specific room associations using get_session_ids_from_room(f'user:{user_id}'). The updated logic implements get_session_ids_by_user_id(user_id), which additionally scans the global in-memory SESSION_POOL mapping to ensure no stale connections escape disconnection:
def get_session_ids_by_user_id(user_id: str) -> list[str]:
session_ids = set(get_session_ids_from_room(f'user:{user_id}'))
session_ids.update(sid for sid, entry in SESSION_POOL.items() if entry and entry.get('id') == user_id)
return list(session_ids)To successfully exploit this session desynchronization flaw, an attacker must first obtain administrative privileges on an Open WebUI instance that integrates with an external SSO identity provider. The attacker must establish a stateful, active Socket.IO connection by opening a session in a web browser. This populates the memory-resident cache of the Socket.IO server with an active 'admin' context, mapping the specific WebSocket session ID to the administrative security classification.
While this connection remains active, the attacker's administrative privileges must be revoked or downgraded on the external identity provider side. When the Open WebUI application processes an HTTP request containing the updated SSO headers or handles an OAuth refresh/callback, the backend executes the database write to downgrade the user's role to 'user'. Because the Socket.IO session is not killed, the WebSocket connection remains established.
The attacker can then issue custom Socket.IO events targeted at collaborative notes endpoints. When the server-side handler processes these events, it queries the connection metadata rather than the database. Finding the cached 'admin' string, the handler permits the execution of administrative operations, allowing the attacker to read, modify, or delete collaborative notes across all user accounts on the platform.
The technical impact of CVE-2026-87014 is categorized as a high-severity privilege persistence and authorization bypass. An attacker who has been demoted from an administrative role retains complete read and write access to all collaborative notes in the system. Since these notes can contain sensitive configuration data, prompt templates, proprietary source code, or private user queries, unauthorized access poses a severe risk to data confidentiality and integrity.
The CVSS v3.1 score is calculated as 6.5 (Medium) with the vector CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N. Although the impact on confidentiality and integrity is high, the overall score is mitigated by the requirement for high privileges (PR:H) to establish the initial administrative state. However, in enterprise environments utilizing dynamic group memberships and automated SSO role assignments, this window of vulnerability remains wide if demotions are not enforced in real-time.
The EPSS score is currently estimated at 0.00278, which indicates a low immediate probability of active exploitation in the wild. Additionally, this CVE is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog, and there are no public weaponized exploits or proof-of-concept scripts available, making this a secondary threat vector that must still be addressed to guarantee session integrity.
The primary remediation path is upgrading the Open WebUI deployment to version 0.11.1 or later. This version incorporates the event-driven session-disconnection framework and the hardened session lookup helper. Upgrades can be performed using standard Python package management tools or by pulling the updated Docker images:
pip install --upgrade open-webuiIf an immediate upgrade is not feasible due to change control constraints, administrators should implement a manual mitigation procedure. This involves executing a complete restart of the Open WebUI application service or Docker container immediately following any SSO-driven role changes or user demotions. Restarting the service terminates the in-memory SESSION_POOL and forces all clients to establish new Socket.IO handshakes, which will pull the updated role from the database.
Additionally, security teams should implement logging and monitoring rules to detect anomalous WebSocket behavior. Specifically, monitoring scripts should correlate database user roles against active Socket.IO session IDs and log any actions where a user with a database role of 'user' initiates WebSocket commands that are structurally restricted to administrative accounts.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Open WebUI Open WebUI | >= 0.9.0, < 0.11.1 | 0.11.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-613 / CWE-863 |
| Attack Vector | Network |
| CVSS Score | 6.5 (Medium) |
| EPSS Score | 0.00278 (0.28%) |
| Impact | High (Confidentiality & Integrity) |
| Exploit Status | No public PoC |
| KEV Status | Not listed |
The software does not invalidate a session or cache after a state or privilege change occurs, allowing persistent unauthorized access.
An authenticated denial of service vulnerability exists in Open WebUI versions 0.10.0 through 0.11.0. An attacker can update a folder's parent identifier to establish cyclic folder references, causing recursive tree-walking operations to execute infinitely, leading to CPU exhaustion and localized application denial of service.
Open WebUI is a self-hosted AI platform. Versions 0.9.0 through 0.11.0 contain a denial-of-service vulnerability where an authenticated user can inject non-numeric values into calendar event alert metadata. The shared scheduler process fails to validate the type, leading to an unhandled TypeError that halts the execution of instance-wide alerts, suppressing notifications for all users.
CVE-2026-87011 is a critical vulnerability in Open WebUI versions 0.9.0 through 0.11.0. It allows unauthenticated remote attackers to trigger a Denial of Service (DoS) by sending crafted tokens to the back-channel logout endpoint, causing synchronous network calls that block the single-worker ASGI event loop.
A high-severity Denial of Service (DoS) vulnerability in the S3 compatibility layer of rclone allows unauthenticated remote attackers (or authenticated attackers depending on configuration) to trigger rapid memory exhaustion and process termination. The flaw lies in the handling of S3 multipart uploads, where rclone eagerly allocates buffers based on untrusted size headers and fails to prevent integer overflows in its concurrent request admission control.
CVE-2026-88046 (also tracked via GHSA-38xv-hf3p-h7mq) is a directory traversal and root confinement escape vulnerability residing in the core listing and transfer logic of rclone. Prior to version 1.75.1, raw relative parent-directory sequences returned by flat-keyspace source backends are trusted and processed without proper sanitization, enabling writes outside the designated target root or bucket.
The FTP server implementation of rclone is vulnerable to a cross-session identity and credential confusion flaw when configured with an authentication proxy. Under specific multi-tenant configurations where multiple distinct sessions authenticate with the same username, a global map caches credentials globally instead of isolating them inside the session context. This allows a concurrent attacker to hijack the active session backend of a victim using the same username.