[PR #23972] [CLOSED] fix(auth): don't crash session/signout on missing bearer; preserve primary-admin 403s #66316

Closed
opened 2026-05-06 12:36:23 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/23972
Author: @crbender
Created: 4/22/2026
Status: Closed

Base: devHead: fix/auth-session-signout-and-primary-admin-guard


📝 Commits (10+)

📊 Changes

2 files changed (+22 additions, -5 deletions)

View changed files

📝 backend/open_webui/routers/auths.py (+16 -5)
📝 backend/open_webui/routers/users.py (+6 -0)

📄 Description

Summary

Three small, related bug fixes in the auth and user-admin routers. No API
contract changes; only affected error paths change behavior.

Bugs fixed

  1. GET /api/v1/auths/ crashes for cookie-only sessions / malformed headers.
    get_current_user accepts a JWT from the Authorization header, the
    token cookie, or request.state.token (set by middleware, e.g. for
    x-api-key). The handler, however, unconditionally did:

    auth_token = get_http_authorization_cred(request.headers.get('Authorization'))
    token = auth_token.credentials
    

    get_http_authorization_cred returns None when the header is missing
    or malformed, so an authenticated request that reached the endpoint via
    cookie (or with a malformed Authorization header) raised
    AttributeError → HTTP 500 instead of returning the session payload.

    Fix: mirror the token-resolution order used by get_current_user
    (header → cookie → request.state.token) and only decode when a token
    is available.

  2. GET /api/v1/auths/signout crashes on a malformed Authorization header.
    The handler assumed that a present Authorization header always yielded
    credentials and did token = auth_cred.credentials without checking
    auth_cred is not None. A malformed header (e.g. Authorization: Bearer
    with no token, or any value that doesn't split into two parts) caused a
    500 and prevented cookie clearing / token revocation.

    Fix: guard the None return and fall back to the cookie token, the
    same way the other branch already does.

  3. Primary-admin protection returns 500 instead of 403.
    update_user_by_id and delete_user_by_id both wrap their primary-admin
    guard in try/except Exception. Because HTTPException is an
    Exception subclass, the intentional
    raise HTTPException(status_code=403, detail=ACTION_PROHIBITED) was
    caught and rewritten as
    HTTPException(500, "Could not verify primary admin status.").
    Clients saw a generic server error for what is actually an authorization
    decision.

    Fix: re-raise HTTPException before the generic catch (same pattern
    already used in signup).

Files changed

  • backend/open_webui/routers/auths.py
  • backend/open_webui/routers/users.py

Risk / compatibility

  • No API contract changes. Response shapes for /auths/, /auths/signout,
    and the affected user routes are unchanged on the existing happy paths.
  • Error responses become more correct: affected error cases now return 200
    (cookie-auth session), a clean signout, or 403 (primary-admin protection)
    instead of 500.

Tests

Existing integration tests in
backend/open_webui/test/apps/webui/routers/test_auths.py and
test_users.py only exercise the header-auth happy paths and already
pass. Happy to add tests covering the three affected error paths as a
follow-up if maintainers prefer them in this PR — the AbstractPostgresTest
fixture makes it a slightly larger change than the fixes themselves.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/open-webui/open-webui/pull/23972 **Author:** [@crbender](https://github.com/crbender) **Created:** 4/22/2026 **Status:** ❌ Closed **Base:** `dev` ← **Head:** `fix/auth-session-signout-and-primary-admin-guard` --- ### 📝 Commits (10+) - [`fe6783c`](https://github.com/open-webui/open-webui/commit/fe6783c16699911c7be17392596d579333fb110c) Merge pull request #19030 from open-webui/dev - [`fc05e0a`](https://github.com/open-webui/open-webui/commit/fc05e0a6c5d39da60b603b4d520f800d6e36f748) Merge pull request #19405 from open-webui/dev - [`e3faec6`](https://github.com/open-webui/open-webui/commit/e3faec62c58e3a83d89aa3df539feacefa125e0c) Merge pull request #19416 from open-webui/dev - [`9899293`](https://github.com/open-webui/open-webui/commit/9899293f050ad50ae12024cbebee7e018acd851e) Merge pull request #19448 from open-webui/dev - [`140605e`](https://github.com/open-webui/open-webui/commit/140605e660b8186a7d5c79fb3be6ffb147a2f498) Merge pull request #19462 from open-webui/dev - [`6f1486f`](https://github.com/open-webui/open-webui/commit/6f1486ffd0cb288d0e21f41845361924e0d742b3) Merge pull request #19466 from open-webui/dev - [`d95f533`](https://github.com/open-webui/open-webui/commit/d95f533214e3fe5beb5e41ec1f349940bc4c7043) Merge pull request #19729 from open-webui/dev - [`a727153`](https://github.com/open-webui/open-webui/commit/a7271532f8a38da46785afcaa7e65f9a45e7d753) 0.6.43 (#20093) - [`6adde20`](https://github.com/open-webui/open-webui/commit/6adde203cd292a9e3af9c64a2ae36b603fed096a) Merge pull request #20394 from open-webui/dev - [`f9b0534`](https://github.com/open-webui/open-webui/commit/f9b0534e0c442631d1cb7205169588b9b6204179) Merge pull request #20522 from open-webui/dev ### 📊 Changes **2 files changed** (+22 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `backend/open_webui/routers/auths.py` (+16 -5) 📝 `backend/open_webui/routers/users.py` (+6 -0) </details> ### 📄 Description ### Summary Three small, related bug fixes in the auth and user-admin routers. No API contract changes; only affected error paths change behavior. ### Bugs fixed 1. **`GET /api/v1/auths/` crashes for cookie-only sessions / malformed headers.** `get_current_user` accepts a JWT from the `Authorization` header, the `token` cookie, or `request.state.token` (set by middleware, e.g. for `x-api-key`). The handler, however, unconditionally did: ```python auth_token = get_http_authorization_cred(request.headers.get('Authorization')) token = auth_token.credentials ``` `get_http_authorization_cred` returns `None` when the header is missing or malformed, so an authenticated request that reached the endpoint via cookie (or with a malformed `Authorization` header) raised `AttributeError` → HTTP 500 instead of returning the session payload. Fix: mirror the token-resolution order used by `get_current_user` (header → cookie → `request.state.token`) and only decode when a token is available. 2. **`GET /api/v1/auths/signout` crashes on a malformed `Authorization` header.** The handler assumed that a present `Authorization` header always yielded credentials and did `token = auth_cred.credentials` without checking `auth_cred is not None`. A malformed header (e.g. `Authorization: Bearer` with no token, or any value that doesn't split into two parts) caused a 500 and prevented cookie clearing / token revocation. Fix: guard the `None` return and fall back to the cookie token, the same way the other branch already does. 3. **Primary-admin protection returns 500 instead of 403.** `update_user_by_id` and `delete_user_by_id` both wrap their primary-admin guard in `try/except Exception`. Because `HTTPException` is an `Exception` subclass, the intentional `raise HTTPException(status_code=403, detail=ACTION_PROHIBITED)` was caught and rewritten as `HTTPException(500, "Could not verify primary admin status.")`. Clients saw a generic server error for what is actually an authorization decision. Fix: re-raise `HTTPException` before the generic catch (same pattern already used in `signup`). ### Files changed - `backend/open_webui/routers/auths.py` - `backend/open_webui/routers/users.py` ### Risk / compatibility - No API contract changes. Response shapes for `/auths/`, `/auths/signout`, and the affected user routes are unchanged on the existing happy paths. - Error responses become more correct: affected error cases now return 200 (cookie-auth session), a clean signout, or 403 (primary-admin protection) instead of 500. ### Tests Existing integration tests in `backend/open_webui/test/apps/webui/routers/test_auths.py` and `test_users.py` only exercise the header-auth happy paths and already pass. Happy to add tests covering the three affected error paths as a follow-up if maintainers prefer them in this PR — the `AbstractPostgresTest` fixture makes it a slightly larger change than the fixes themselves. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-06 12:36:23 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#66316