Open WebUI: Instance-wide stall via automation recurrence rules that force multi-second parsing
Medium6.5CVE-2026-70489 · Published Aug 4, 2026 · updated Aug 19, 2026
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| open-webui PyPI | >= 0.9.0, < 0.11.0 | 0.11.0 |
Details and references
## Summary In every affected release, automation recurrence parsing anchors minutely and hourly rules at a fixed date of 2000-01-01 and then walks forward one interval at a time to find the next run. A single `FREQ=MINUTELY` rule therefore enumerates roughly a quarter-century of occurrences, synchronously, on the event loop that also serves the scheduler, HTTP and WebSocket traffic. Nothing bounds the walk, and nothing moves it off the loop. ## Preconditions Any user who can create an automation. `USER_PERMISSIONS_FEATURES_AUTOMATIONS` defaults to `false`, so on a default deployment only an admin can reach the create path; it becomes reachable by ordinary users on any deployment that has granted the automations feature, which is the normal way to make the feature usable. `UVICORN_WORKERS` defaults to 1, so there is no second worker to absorb the stall. The rule needs no unusual syntax: `FREQ=MINUTELY` with no `DTSTART`, or with a `DTSTART` set well in the past, is enough. ## Impact Availability, against every other user of the instance. One evaluation of `RRULE:FREQ=MINUTELY` takes 18.9 s of blocking CPU; adding a ten-value `BYSECOND` list multiplies the walk and takes 64.2 s. `FREQ=HOURLY` costs 0.34 s and is not materially exploitable on its own. The cost does not stop at creation: once the automation is stored, the scheduler recomputes the next run for every claimed row on each poll, so the same walk repeats on a default 10 s interval and the instance stays wedged rather than recovering. Instances that have not enabled the automations feature for non-admin users are exposed only to an admin doing this. ## Fix Fixed in 0.11.0. Sub-daily rules are now anchored to the current clock instead of the year-2000 date, so the walk starts at the next occurrence rather than a quarter-century behind it. A caller-supplied `DTSTART` is honoured only when the number of occurrences it implies stays under a fixed bound, and is otherwise replaced by the clock-aligned anchor. The same rules that cost 18.9 s and 64.2 s now cost under a millisecond. Upgrading fully resolves the issue, no configuration change is required. ## Root cause Affected component: `backend/open_webui/utils/automations.py`, `_parse_rule`, reached from the automation create, update and toggle handlers in `backend/open_webui/routers/automations.py` and from the scheduler's claim path in `backend/open_webui/models/automations.py`. Affected setup: every build from 0.9.0 onward, since that is when the automations feature shipped. The fixed anchor existed to make sub-daily intervals snap to clock boundaries, so that "every 5 minutes" lands on :00, :05, :10 rather than drifting from whenever the automation happened to be created. Snapping only needs a reference point of the right phase, but the implementation used a literal far-past date as that reference and left the recurrence library to walk forward from it. The distance between the anchor and the present is therefore attacker-influenced work that grows with real time, and it was never treated as a cost that needed a bound or a thread. ## Proof of concept Measured cost of a single next-run computation against the shipped 0.10.2 parser: | rule | cost | | --- | --- | | `RRULE:FREQ=MINUTELY` | 18,880 ms | | `RRULE:FREQ=MINUTELY;BYSECOND=0,1,2,3,4,5,6,7,8,9` | 64,236 ms | | `DTSTART:20000101T000000` + `RRULE:FREQ=MINUTELY` | 26,237 ms | | `RRULE:FREQ=HOURLY` | 339 ms | Measured at function level deliberately. Persisting such an automation has the scheduler repeat the walk on every poll and wedge the instance indefinitely, which is the actual impact but makes a live end-to-end run destructive to the test instance. ## Credits Reported by @Classic298.
More Open WebUI advisories
All Open WebUI| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Aug 4 | Open WebUI: SSRF into internal services via unvalidated sub-resource requests in the Playwright web loader CVE-2026-70479High7.7fixed in 0.11.0 | High7.7 | 0.11.0 |
| Aug 4 | Open WebUI: Any member with write access to a standard channel can edit or delete other members' messages CVE-2026-70481Medium5.4fixed in 0.11.0 | Medium5.4 | 0.11.0 |
| Aug 4 | Open WebUI: Account takeover via OAuth token exchange accepting tokens issued to any client CVE-2026-70482High8.1fixed in 0.11.0 | High8.1 | 0.11.0 |
| Aug 4 | Open WebUI: Any authenticated user can cancel another user's chat generation via the chat delete endpoint CVE-2026-70483Low3.1fixed in 0.11.0 | Low3.1 | 0.11.0 |
| Aug 4 | Open WebUI: Client-side SSRF via unrestricted external resource loading in Vega/Vega-Lite chart rendering CVE-2026-70480Medium4.1fixed in 0.11.0 | Medium4.1 | 0.11.0 |
| Aug 4 | Open WebUI: Users denied the image-generation permission can still generate images via chat completions CVE-2026-70484Medium4.3fixed in 0.11.0 | Medium4.3 | 0.11.0 |