High severity8.1GHSA Advisory· Published May 15, 2026· Updated May 15, 2026
CVE-2026-45675
CVE-2026-45675
Description
Open WebUI is a self-hosted artificial intelligence platform designed to operate entirely offline. Prior to 0.9.0, he LDAP and OAuth authentication flows use a TOCTOU (Time-of-Check-Time-of-Use) pattern for first-user admin role assignment. The regular signup handler (signup_handler in auths.py, line 663) was explicitly patched to prevent this race with the comment "Insert with default role first to avoid TOCTOU race", but the LDAP and OAuth code paths were never updated with the same fix. This vulnerability is fixed in 0.9.0.
Affected products
1- Range: <= 0.8.12
Patches
196a0b3239b1afix: prevent first-user admin race in LDAP and OAuth registration (#23626)
2 files changed · +25 −6
backend/open_webui/routers/auths.py+9 −3 modified@@ -479,19 +479,25 @@ async def ldap_auth( user = Users.get_user_by_email(email, db=db) if not user: try: - role = 'admin' if not Users.has_users(db=db) else request.app.state.config.DEFAULT_USER_ROLE - + # Insert with default role first to avoid TOCTOU race on + # first-user registration. Matches signup_handler pattern. user = Auths.insert_new_auth( email=email, password=str(uuid.uuid4()), name=cn, - role=role, + role=request.app.state.config.DEFAULT_USER_ROLE, db=db, ) if not user: raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + # Atomically check if this is the only user *after* the + # insert. Only the single user present should become admin. + if Users.get_num_users(db=db) == 1: + Users.update_user_role_by_id(user.id, 'admin', db=db) + user = Users.get_user_by_id(user.id, db=db) + apply_default_group_assignment( request.app.state.config.DEFAULT_GROUP_ID, user.id,
backend/open_webui/utils/oauth.py+16 −3 modified@@ -1109,9 +1109,12 @@ def get_user_role(self, user, user_data): log.debug('Assigning the only user the admin role') return 'admin' if not user and user_count == 0: - # If there are no users, assign the role "admin", as the first user will be an admin - log.debug('Assigning the first user the admin role') - return 'admin' + # First-user bootstrap: skip role management gating so the + # instance can be initialized. We intentionally return the + # default role here (not 'admin') — admin promotion happens + # race-safely *after* insert via get_num_users() == 1. + log.debug('First user bootstrap: using default role (admin promotion deferred to post-insert)') + return auth_manager_config.DEFAULT_USER_ROLE if auth_manager_config.ENABLE_OAUTH_ROLE_MANAGEMENT: log.debug('Running OAUTH Role management') @@ -1577,6 +1580,16 @@ async def handle_callback(self, request, provider, response, db=None): db=db, ) + if not user: + raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR) + + # Atomically check if this is the only user *after* the + # insert to avoid TOCTOU race on first-user registration. + # Matches signup_handler pattern. + if Users.get_num_users(db=db) == 1: + Users.update_user_role_by_id(user.id, 'admin', db=db) + user = Users.get_user_by_id(user.id, db=db) + if auth_manager_config.WEBHOOK_URL: await post_webhook( WEBUI_NAME,
Vulnerability mechanics
AI mechanics synthesis has not run for this CVE yet.
References
6- github.com/advisories/GHSA-h3ww-q6xx-w7x3ghsaADVISORY
- github.com/open-webui/open-webui/commit/96a0b3239b1aadb23fc359bf10849c9ba12fd6ecnvd
- github.com/open-webui/open-webui/pull/23626nvd
- github.com/open-webui/open-webui/releases/tag/v0.9.0ghsa
- github.com/open-webui/open-webui/security/advisories/GHSA-h3ww-q6xx-w7x3nvd
- nvd.nist.gov/vuln/detail/CVE-2026-45675ghsa
News mentions
0No linked articles in our index yet.