CVE-2026-44553: open-webui: stale Socket.IO role allows cross-user note R/W

GHSA-45m8-cpm2-3v65 HIGH
Published May 8, 2026
CISO Take

Open-webui snapshots a user's admin role into an in-memory session pool at Socket.IO connect time and never refreshes it, meaning a user whose privileges have been formally revoked continues to hold admin rights on their live socket connection indefinitely. Any org running open-webui ≤ 0.8.12 in a multi-user deployment is exposed: the attacker only needs to keep a browser tab open after demotion to silently read and overwrite any colleague's notes through the Yjs real-time collaboration handlers, with no public exploit or KEV entry yet but an exploitability that is trivial for any demoted insider aware of the flaw. Standard IT remediation — role demotion via the admin API — gives a false sense of security because HTTP access is correctly cut while the socket-based attack channel remains silently open, a gap that will not appear in access reviews or standard audit logs. Upgrade to open-webui 0.9.0 immediately; as a short-term workaround, restart the server process to flush SESSION_POOL and force Socket.IO re-authentication after any role change or user deletion.

Sources: GitHub Advisory NVD ATLAS

What is the risk?

CVSS 8.1 High is well-calibrated. The attack requires Low Privileges (prior admin access) and No User Interaction, delivering High Confidentiality and High Integrity impact with Network access vector. The key risk amplifier is the deceptive remediation gap: administrators who demote a user believe access is fully revoked, but the socket attack channel remains open for as long as the attacker sustains heartbeats — which is automatic in any browser session. In enterprise shared LLM workspace deployments, this is a trust boundary violation with insider threat and compromised admin account scenarios being the most realistic vectors. The 52 prior CVEs in the same package signal an active security research focus on open-webui, increasing the likelihood this class of vulnerability receives public exploit tooling.

How does the attack unfold?

Pre-position
Attacker holds an active browser Socket.IO session to open-webui while they still have admin privileges; SESSION_POOL[sid].role is snapshotted as 'admin' at connection time.
AML.T0012
Stale Role Persistence
Administrator demotes the attacker via HTTP API updating the DB role to 'user', but no SESSION_POOL invalidation or socket disconnect is triggered; attacker's client continues sending automatic heartbeats that only refresh last_seen_at, indefinitely extending the privileged session.
AML.T0049
Authorization Bypass
Attacker emits ydoc:document:join with a target victim note ID; the handler at line 538 reads SESSION_POOL, finds role='admin', and bypasses the has_access() check, granting full document room access.
AML.T0107
Data Access and Injection
Attacker reads complete note content via Yjs document state synchronization and optionally emits ydoc:document:update to overwrite victim note content, persisted via Notes.update_note_by_id with no post-demotion audit attribution.
AML.T0025

What systems are affected?

Package Ecosystem Vulnerable Range Patched
Open WebUI pip <= 0.8.12 0.9.0
142.4K Pushed 5d ago 77% patched ~5d to patch Full package profile →

Do you use Open WebUI? You're affected.

How severe is it?

CVSS 3.1
8.1 / 10
EPSS
0.3%
chance of exploitation in 30 days
Higher than 20% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Moderate

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR Low
UI None
S Unchanged
C High
I High
A None

What should I do?

5 steps
  1. Patch: Upgrade to open-webui 0.9.0 which resolves SESSION_POOL role caching in the Socket.IO handlers.

  2. Immediate workaround (pre-patch): Restart the open-webui server process to flush the in-memory SESSION_POOL after any admin demotion or user deletion — this forces all clients to re-authenticate via Socket.IO on reconnect.

  3. Process control: Implement a runbook step requiring server restart (or targeted SESSION_POOL invalidation if available in 0.9.0) as part of the user offboarding and privilege revocation procedure.

  4. Detection: Audit Socket.IO event logs for ydoc:document:join and ydoc:document:update events where the joining user's ID does not match the document owner and the timestamp postdates a role change event — flag these for incident review.

  5. Defense in depth: Restrict access to the collaborative notes feature to a minimum-privilege group and consider disabling real-time collaboration for high-sensitivity deployments until patched.

What does CISA's SSVC say?

Decision Track
Exploitation none
Automatable No
Technical Impact total

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Art. 15 - Accuracy, robustness and cybersecurity
ISO 42001
A.9.1 - Information security for AI systems
NIST AI RMF
GOVERN 6.1 - Policies and procedures for AI system security MANAGE 2.2 - Mechanisms to monitor and respond to AI risk

Frequently Asked Questions

What is CVE-2026-44553?

Open-webui snapshots a user's admin role into an in-memory session pool at Socket.IO connect time and never refreshes it, meaning a user whose privileges have been formally revoked continues to hold admin rights on their live socket connection indefinitely. Any org running open-webui ≤ 0.8.12 in a multi-user deployment is exposed: the attacker only needs to keep a browser tab open after demotion to silently read and overwrite any colleague's notes through the Yjs real-time collaboration handlers, with no public exploit or KEV entry yet but an exploitability that is trivial for any demoted insider aware of the flaw. Standard IT remediation — role demotion via the admin API — gives a false sense of security because HTTP access is correctly cut while the socket-based attack channel remains silently open, a gap that will not appear in access reviews or standard audit logs. Upgrade to open-webui 0.9.0 immediately; as a short-term workaround, restart the server process to flush SESSION_POOL and force Socket.IO re-authentication after any role change or user deletion.

Is CVE-2026-44553 actively exploited?

No confirmed active exploitation of CVE-2026-44553 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-44553?

1. Patch: Upgrade to open-webui 0.9.0 which resolves SESSION_POOL role caching in the Socket.IO handlers. 2. Immediate workaround (pre-patch): Restart the open-webui server process to flush the in-memory SESSION_POOL after any admin demotion or user deletion — this forces all clients to re-authenticate via Socket.IO on reconnect. 3. Process control: Implement a runbook step requiring server restart (or targeted SESSION_POOL invalidation if available in 0.9.0) as part of the user offboarding and privilege revocation procedure. 4. Detection: Audit Socket.IO event logs for `ydoc:document:join` and `ydoc:document:update` events where the joining user's ID does not match the document owner and the timestamp postdates a role change event — flag these for incident review. 5. Defense in depth: Restrict access to the collaborative notes feature to a minimum-privilege group and consider disabling real-time collaboration for high-sensitivity deployments until patched.

What systems are affected by CVE-2026-44553?

This vulnerability affects the following AI/ML architecture patterns: Multi-user AI chat platforms, Collaborative AI workspaces, Shared LLM frontends, AI note-taking and knowledge management tools.

What is the CVSS score for CVE-2026-44553?

CVE-2026-44553 has a CVSS v3.1 base score of 8.1 (HIGH). The EPSS exploitation probability is 0.28%.

What is the AI security impact?

Affected AI Architectures

Multi-user AI chat platformsCollaborative AI workspacesShared LLM frontendsAI note-taking and knowledge management tools

MITRE ATLAS Techniques

AML.T0012 Valid Accounts
AML.T0025 Exfiltration via Cyber Means
AML.T0036 Data from Information Repositories
AML.T0049 Exploit Public-Facing Application
AML.T0107 Exploitation for Defense Evasion

Compliance Controls Affected

EU AI Act: Art. 15
ISO 42001: A.9.1
NIST AI RMF: GOVERN 6.1, MANAGE 2.2

What are the technical details?

Original Advisory

# Stale Admin Role in Socket.IO Session Pool Enables Post-Demotion Cross-User Note Access ## Affected Component Socket.IO session state and role-check callsites: - `backend/open_webui/socket/main.py` (lines 330-351, `connect` handler — role snapshotted into SESSION_POOL) - `backend/open_webui/socket/main.py` (lines 393-398, `heartbeat` handler — does not refresh role) - `backend/open_webui/socket/main.py` (line 538, `ydoc:document:join` — uses cached role for admin check) - `backend/open_webui/socket/main.py` (line 611, `document_save_handler` — uses cached role for admin check) - `backend/open_webui/routers/users.py` (lines 557-633, role update — does not invalidate SESSION_POOL) - `backend/open_webui/routers/users.py` (line 641, user delete — does not invalidate SESSION_POOL) ## Affected Versions Current main branch (commit `6fdd19bf1`) and likely all versions with the collaborative document (Yjs) Socket.IO handlers. ## Description When a user connects via Socket.IO, the `connect` handler authenticates them via JWT and stores their user record (including `role`) in the in-memory `SESSION_POOL` dictionary keyed by session ID. The `heartbeat` handler keeps the session alive indefinitely but only refreshes the `last_seen_at` timestamp — never the role. Role checks in the Yjs collaborative document handlers (`ydoc:document:join`, `document_save_handler`) consult the cached `SESSION_POOL` role rather than the database. Meanwhile, administrative role changes and user deletions do not iterate `SESSION_POOL` to disconnect affected sessions. As a result, a user whose admin role has been revoked retains admin privileges within their existing Socket.IO session for as long as they keep the connection alive (via automatic heartbeats). HTTP endpoints are not affected — `get_current_user` at [utils/auth.py](backend/open_webui/utils/auth.py) refetches the user record from the database on every request. The gap is exclusive to the Socket.IO session cache. ```python # socket/main.py:330-351 — role snapshotted at connect time async def connect(sid, environ, auth): user = None if auth and 'token' in auth: data = decode_token(auth['token']) if data is not None and 'id' in data: user = Users.get_user_by_id(data['id']) if user: SESSION_POOL[sid] = { 'id': user.id, 'role': user.role, # ← snapshotted, never refreshed ... } # socket/main.py:393-398 — heartbeat refreshes last_seen_at only async def heartbeat(sid, data): user = SESSION_POOL.get(sid) if user: SESSION_POOL[sid] = {**user, 'last_seen_at': int(time.time())} # role is carried forward unchanged # socket/main.py:538 — admin check against cached role if user.get('role') != 'admin' and not has_access(user_id, 'note', note_id, 'read', db=db): return ``` ## Attack Scenario 1. User B is an admin and has an active browser session with a live Socket.IO connection. `SESSION_POOL[sid]` records `role='admin'`. 2. Admin A demotes User B to a regular user via `POST /api/v1/users/{B_id}/update`. The DB `user.role` becomes `'user'`. 3. No Socket.IO disconnect, no SESSION_POOL update, no token revocation event is triggered by the role change. 4. User B's client continues sending `heartbeat` events every few seconds; these are accepted and only refresh `last_seen_at`. 5. User B emits `ydoc:document:join` with `document_id = 'note:<victim_note_id>'` for any note they do not own. 6. The handler at line 538 evaluates `user.get('role') != 'admin'` — returns `False` because `SESSION_POOL` still holds the stale `admin` role. Access check is bypassed, User B joins the document room, receives full document state and live updates. 7. User B emits `ydoc:document:update` for the same note. The handler at line 611 performs the same cached-admin check, bypasses authorization, and persists attacker-controlled content to the victim's note via `Notes.update_note_by_id`. The same bypass occurs if the user is deleted entirely (`delete_user_by_id`) — the deleted user retains admin privileges on their live socket until disconnection. ## Impact - Read access to any user's notes after admin privileges have been revoked - Write access (content injection, overwrite) to any user's notes under the same conditions - The stale privilege is bounded only by the attacker's willingness to keep the Socket.IO connection alive; heartbeats extend the session indefinitely - Official admin demotion or user deletion gives a false sense of security — HTTP access is correctly revoked, but real-time collaborative access silently continues ## Preconditions - Attacker must have an active Socket.IO connection established while they held admin role - Attacker must retain the Socket.IO session after demotion/deletion (trivial — just don't close the browser)

Exploitation Scenario

An insider threat scenario: a DevOps admin at an enterprise using open-webui as their shared LLM workspace is demoted to standard user after a security incident. The admin keeps their browser tab open and knows about the stale SESSION_POOL vulnerability. Despite the IT team believing access is revoked and HTTP API calls confirming the demotion, the admin's Socket.IO session still carries role='admin' in SESSION_POOL. They enumerate note IDs from the application URL structure or prior knowledge, then emit `ydoc:document:join` events targeting the CISO's confidential AI research notes. The Yjs handler at line 538 evaluates the cached admin role, bypasses has_access(), and streams the full document state. The attacker then emits `ydoc:document:update` to inject false strategic information, with changes appearing as legitimate real-time edits and no post-demotion access log entry attributing them to the demoted user.

Weaknesses (CWE)

CWE-384 — Session Fixation: Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.

  • [Architecture and Design] Invalidate any existing session identifiers prior to authorizing a new user session.
  • [Architecture and Design] For platforms such as ASP that do not generate new values for sessionid cookies, utilize a secondary cookie. In this approach, set a secondary cookie on the user's browser to a random value and set a session variable to the same value. If the session variable and the cookie value ever don't match, invalidate the session, and force the user to log on again.

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

Timeline

Published
May 8, 2026
Last Modified
May 8, 2026
First Seen
May 8, 2026

Related Vulnerabilities