NewApp Monitoring is liveSign up free
AgentbeamBeta
AI agent vulnerability · Open WebUI

CVE-2026-87014: Open WebUI: Admin demoted through SSO role sync keeps read and write access to all users' notes

mediumCVSS 3.1 6.5GHSA-wjwr-xfp9-r66p

In Open WebUI 0.9.0 up to 0.11.0, an admin demoted through SSO role sync keeps admin access to every user's notes on any Socket.IO connection that was already open. The role is cached on the socket, and the two SSO sync paths never closed it. Fixed in Open WebUI 0.11.1.

Published Sep 10, 2026 · Analysis Oct 24, 2026

What an attacker can do

Open WebUI caches the user record, including the role, on the Socket.IO connection when it opens. The admin user-management endpoints disconnected a user's sockets on a role change. The trusted-header sync in routers/auths.py and the OAuth role sync in utils/oauth.py changed the role in the database and did not. The socket keep-alive also rewrites the cached record and preserves the stale role, so an active connection is never reaped.

The collaborative-notes handlers in socket/main.py authorize against that cached copy and give admins access to every note. A demoted admin who keeps a browser tab open can therefore join and edit any user's private notes until the connection drops. This is insufficient session expiration (CWE-613) and incorrect authorization (CWE-863).

The scope is narrow. HTTP endpoints read the role fresh on each request, so the demoted account gets no REST admin access, no user management and no settings. Closing the tab, reloading, signing out or a network break ends the exposure.

The condition is a role-sync SSO mode: trusted-header auth with WEBUI_AUTH_TRUSTED_ROLE_HEADER set, or OAuth role mapping. Both are off by default. The advisory's realistic case is off-boarding or a downgrade done in the identity provider. It says the flaw was established by source inspection, not by an executed exploit.

Who is affected

Affected: open-webui from 0.9.0 up to but not including 0.11.1, when WEBUI_AUTH_TRUSTED_ROLE_HEADER is set or OAuth role mapping is enabled. Deployments that change roles only in the admin panel are not affected. Check the version:

pip show open-webui

For Docker installs, check the image tag or the version in the Open WebUI About page.

open-webui

Ecosystem
PyPI
Affected
>= 0.9.0, < 0.11.1
Fixed in
0.11.1
Check
pip show open-webui

How to fix it

Upgrade to 0.11.1:

pip install --upgrade open-webui==0.11.1

The fix (commit ce3c175) publishes a USER_ROLE_UPDATED event from the trusted-header, OAuth, SCIM and admin paths. A session handler then disconnects that user's Socket.IO connections. No configuration change is needed. The sources give no other workaround. After upgrading, restarting Open WebUI also drops any socket that predates the fix. A restart is also worth doing after an IdP-driven demotion if you cannot upgrade.

How to tell if you were hit

Look at who was demoted from admin through the identity provider recently. Review note access and edits by those accounts after the demotion time, through the collaborative-notes socket handlers. Compare note edit history with the demotion timestamp. The advisory gives no log line for this, and the connection leaves no sign other than the notes activity itself.

Original advisory

From the GitHub Advisory Database (CC BY 4.0).

Summary

A user who is demoted from admin by an identity provider keeps admin-level read and write access to every user's notes, over any Socket.IO connection that was already open when the demotion happened. Open WebUI caches the user's role on the socket at connection time, and the two SSO role-sync paths, the reverse-proxy trusted role header and OAuth role mapping, changed the role in the database without tearing that cached session down. Only the admin user-management endpoints invalidated sessions, so a demotion driven by the identity provider left the old privileges live on the socket.

Preconditions

A role-sync SSO mode has to be enabled. Either trusted-header authentication with WEBUI_AUTH_TRUSTED_ROLE_HEADER set, which is unset by default, or OAuth with role mapping enabled, which is off by default. Deployments that change roles only through the admin panel are not affected, because that path already invalidated the user's sockets.

The account has to be an admin at the moment it opens a Socket.IO connection, has to keep that connection open across the demotion, and has to be demoted through the SSO path rather than through the admin panel. Signing out, reloading the page, or any network interruption ends the exposure, because the reconnect reads a fresh role from the database.

Impact

Until the socket closes, the demoted account can open and edit any user's note through the collaborative-notes socket handlers, which grant admins access to every note. That is read and write access to other users' private notes, held by someone the operator has already removed from the admin role.

The rest of the product is not affected. Every HTTP endpoint reads the role fresh from the database on each request, so the demoted account has no admin access to the REST API, no user management, no settings and no model or connection configuration. The exposure ends the moment the connection drops, and the account controls that only by keeping the browser tab open.

The realistic case is off-boarding or a least-privilege downgrade performed in the identity provider, which is a normal administrative action rather than a misconfiguration.

Fix

Fixed in 0.11.1 by commit ce3c175e260709f359d7e6cbb3132f0572098b95. Role changes and user deletions now publish an internal event, and a session handler tears down that user's Socket.IO connections whenever the event fires, so every path that can change a role invalidates cached sessions instead of only the admin endpoints. Upgrading is sufficient, no configuration change is needed.

Root cause

Affected components:

  • backend/open_webui/routers/auths.py, the trusted-header role sync in the sign-in handler.
  • backend/open_webui/utils/oauth.py, the OAuth role sync run on login.
  • backend/open_webui/socket/main.py, which caches the user record on the socket and authorizes the collaborative-notes handlers against that cached copy.

Session invalidation on role change was added as an explicit call, made at the call sites that changed a role rather than inside the role-change itself. The admin user-management endpoints made that call, the two SSO sync paths did not, and nothing else refreshed the role cached on an open socket. The socket keep-alive rewrites the cached record to reset the idle timer and preserves the stale role while doing so, so a connection that stays active is never reaped. Because the notes handlers grant full access to any note when the cached role reads admin, the gap turned into read and write access over all notes for as long as the connection lived.

Proof of concept

Deploy Open WebUI with trusted-header authentication and WEBUI_AUTH_TRUSTED_ROLE_HEADER set, or with OAuth role mapping enabled. Sign in as an admin and leave the browser open on a page holding a Socket.IO connection. Demote the account through the identity provider, meaning the next sign-in carries the role header set to user, or the account's group is changed at the OAuth provider. The database role is now user.

Over the connection that is still open, join and edit another user's note by its id. Both are granted, because the role cached on that socket still reads admin. Performing the same demotion through the admin panel instead drops the connection and revokes the access, which is the behaviour the SSO paths were missing.

This was established by source inspection against 0.11.0 rather than by an executed exploit.

Credits

Reported by @mtholmquist.

Credited to mtholmquist, Classic298.

Questions

Does CVE-2026-87014 give a demoted admin full admin access?

No. Only the open Socket.IO connection is stale, which exposes read and write access to all notes. HTTP endpoints read the role fresh, so there is no REST admin access, user management or settings access.

Am I affected if I demote admins in the admin panel?

No. The admin panel path already dropped the user's sockets. The flaw applies to demotions made through trusted-header role sync or OAuth role mapping.

How long does the exposure last?

Until the socket closes. Signing out, reloading or a network interruption ends it, because the reconnect reads a fresh role. A tab left open can keep it alive.

Which version fixes it?

0.11.1. Versions from 0.9.0 are affected.

References

How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology

More Open WebUI vulnerabilities

All Open WebUI entries