GHSA-8jjp-r2w2-4v22: Open WebUI: Low-privilege authenticated users can enumerate and stop global background tasks, causing system-wide chat disruption
SummaryAny authenticated user with low privileges can enumerate active background tasks across the system and stop tasks belonging to other users via the GET /api/tasks and POST /api/tasks/stop/{task_id} methods. This allows a casual user to disrupt system-wide chat usage by continuously canceling other users' active tasks. This is a real authorization vulnerability affecting integrity and usability in multi-user deployments.DetailsOpen WebUI exposes `GET /api/tasks` and `POST /api/tasks/stop/{task_id}` to any verified user. These endpoints operate on a global task namespace and accept raw `task_id` values without checking whether the task belongs to the current caller.As a result, a normal authenticated user can enumerate active global task IDs and stop tasks belonging to other users.Root cause:Route authorization is too weak.In `backend/open_webui/main.py`, both endpoints only require `get_verified_user`:`get_verified_user` accepts both `user` and `admin` roles in `backend/open_webui/utils/auth.py`.The helper operates on a global namespace.In `backend/open_webui/tasks.py`, task listing is global:In `backend/open_webui/tasks.py`, task stopping is by raw `task_id`:There is no owner check, no `user_id` check, and no mapping from `task_id` back to the current caller before stop or cleanup.This also appears unintended because the codebase already has a scoped route, `GET /api/tasks/chat/{chat_id}`, which checks whether the chat belongs to the current user before returning task IDs.Relevant code references:`backend/open_webui/main.py:1975``backend/open_webui/main.py:1984``backend/open_webui/main.py:1989``backend/open_webui/tasks.py:127``backend/open_webui/tasks.py:145``backend/open_webui/utils/auth.py:415`Suggested remediation:Store task ownership metadata such as `user_id` and `chat_id`, then enforce owner-only access for non-admin usersSuggested implementation locations:`backend/open_webui/main.py`: add authentication checks for `/api/tasks` and `/api/tasks/stop/{task_id}``backend/open_webui/tasks.py`: add support for storing/querying task ownership metadata such as `user_id` and `chat_id`, and support owner-scoped listing/stoppingPoCPreconditions:Default `main` branch deploymentAuthentication enabledTwo normal user accounts, or any multi-user deployment where the attacker has one authenticated non-admin accountAt least one task actively running for another userThis does not require any weakened security settings.PoC objective:Show that a non-admin user can see global active task IDs that are not their ownShow that the same user can stop another user's active taskReproduction steps:Step 1. Victim starts a long-running taskUsing the UI, User A starts a long response generation or another background task and leaves it running.Expected security model:
User B should not be able to see or control User A's task.Step 2. Attacker enumerates global task IDsUsing User B's authenticated token:Expected result:only User B's own task IDs should be returned, orthe endpoint should be admin-onlyActual result:
the response returns the global active task list.Example response shape:This exposes task IDs belonging to other users.Step 3. Attacker stops a foreign taskPick a task ID that belongs to User A and send:Expected result:`403 Forbidden`, or`404 Not Found` for non-owned tasks, oradmin-only accessActual result:
the server accepts the request and attempts to stop the foreign task.Example response shape:Step 4. Observe boundary violationUser A's running task is interrupted or disappears from the active task set even though User B does not own it.What actions become possible that should not be possible:enumerate globally active task IDs across userscancel another user's in-progress generation or background workrepeat this for every returned task ID, causing broad cross-user disruptionCopy-paste PoC summary:Enumerate all active tasks as a normal non-admin userStop a task that does not belong to that userImpactType of vulnerability:
broken object-level authorization affecting a global runtime control-plane endpoint.Who is impacted:all users in a multi-user Open WebUI deploymentany user currently running a background task, especially chat generation tasksadministrators indirectly, because normal users can disrupt system-wide usage without admin privilegesDirect impact:cross-user task ID disclosurecross-user task cancellationPractical impact:interruption of long-running chat responsesinterruption of background indexing or ingestion tasks associated with shared runtime jobsone ordinary authenticated low-privilege user can continuously poll `/api/tasks` and immediately cancel every newly created active taskwith a simple loop or script, this becomes a practical persistent denial-of-service against chat usage for all users on the instancein a multi-user deployment, normal users may be unable to complete any chat generation while the attacker continues polling and cancelling tasksWhy severity is meaningful:privileges required: low, only an authenticated non-admin accountscope: cross-userimpact class: integrity and availabilityexploitation complexity: low once logged inThis is not full account takeover or privilege escalation, but it enables platform-wide operational disruption from a low-privilege account. In practice, sustained exploitation can make chat functionality effectively unusable for other users on the system.ResolutionFixed in commit [e7ff4768f](https://github.com/open-webui/open-webui/commit/e7ff4768f8ffe1924b4576381c9e45e8a64350e4) ([#23454](https://github.com/open-webui/open-webui/pull/23454), "Add ownership checks to global task endpoints"), first released in **v0.9.0** (Apr 2026).The fix takes a simpler approach than per-task ownership tracking, which would have required a schema change to attribute every task to a `user_id`:`GET /api/tasks` and `POST /api/tasks/stop/{task_id}` are restricted to admin-only via `Depends(get_admin_user)`. Cross-user enumeration and termination are no longer reachable from a non-admin account.A new scoped `POST /api/tasks/chat/{chat_id}/stop` endpoint covers the legitimate non-admin use case (a user stopping their own in-progress generation), reusing the same chat-ownership check the existing `GET /api/tasks/chat/{chat_id}` already enforces.CVE-2025-63681 was a prior disclosure of the same authorization gap against v0.6.33; the fix in v0.9.0 also resolves that.Users on `>= 0.9.0` are not affected.
CVSS v3.1: 7.1