OPEN-WEBUI · CVE-2026-109299 · AI agents & MCP
FIX → 0.11.4
Open WebUI's automation create and update endpoints check recurrence rules synchronously on the shared event loop, and a rule that can never occur forces a long search. A single authenticated user who has the automations feature can repeat such requests and keep the whole instance unresponsive.
first public Sep 27, 2026 · 2 sources
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Any Open WebUI deployment from 0.9.0 up to but not including 0.11.4 that ships automations is exposed. Exposure needs an account allowed to create or update automations, which is off by default, so instances where only administrators can use automations are reachable only by admins. Deployments on 0.11.4 or later, or that do not enable the automations feature for users, can skip this.
Not affected if automations-admin-only, default-config, fixed-version
Who cares automations, open-webui, python, self-hosted
pip show open-webui and see whether it is between 0.9.0 and 0.11.3.USER_PERMISSIONS_FEATURES_AUTOMATIONS is enabled for ordinary users.UVICORN_WORKERS is 1 (the default), which means one blocked event loop stalls the whole instance.A recurrence rule whose date filters can never be satisfied, for example February 30th, has no occurrence at any point in time. Computing its next run walked the whole search horizon of the calendar library before reporting that there is none, synchronously on the shared event loop. One automation create or update request from one account therefore held up the entire deployment for seconds, and the request could be repeated indefinitely. Nothing bounded that search by time, by iteration count or by how far ahead it looked.
An account permitted to create or update automations. USER_PERMISSIONS_FEATURES_AUTOMATIONS defaults to False, so out of the box only an administrator can reach it. It becomes reachable by ordinary users on any deployment that has granted the automations feature, which is the normal way to make the shipped feature usable. No other configuration matters, and no knowledge of other users, ids or tokens is required. UVICORN_WORKERS defaults to 1, so a single blocked event loop is the whole instance.
Availability, against every other user of the instance. The stall lasts as long as the search, and the attacker picks the duration through the rule's shape: a minutely rule on February 30th costs about 4 seconds, and adding a full BYSECOND list raises the same single request to over 30 seconds. The rule is rejected once the search finishes, so nothing is stored and nothing shows up in the automation list, but the cost has already been paid. The per-user automation limits are checked after validation, so they do not reduce it. Requests are cheap and can be repeated or pipelined, so one account in a loop keeps the instance unresponsive for as long as it continues. There is no confidentiality or integrity impact, and no data is written.
Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
Upgrade to 0.11.4
0.11.4 (fixed in commit 5fb869db221d9599a576e8e2eea9c3314947d25e); no configuration change is required.Fixed in commit 5fb869db221d9599a576e8e2eea9c3314947d25e. All recurrence evaluation now runs in a separate worker process with a two-second limit, so the event loop stays free while a rule is evaluated. A rule that cannot be settled within that limit is rejected on write, and the scheduler skips it. Upgrading fully resolves the issue; no configuration change is required.
Affected component: the recurrence-rule validator (validate_rrule and _parse_rule in backend/open_webui/utils/automations.py), reached from POST /api/v1/automations/create and POST /api/v1/automations/{id}/update in backend/open_webui/routers/automations.py.
Affected setup: every build that ships automations, from 0.9.0 up to the fix.
The validator checked that a rule has a future occurrence by asking the calendar library for the next one and treating an empty answer as invalid. For a rule that can never match, the library can only give that empty answer after exhausting its entire search space, and the validator put no limit on that search. Both routes are async handlers and called the validator directly, so the search ran on the event loop and blocked every other request for its full duration. The earlier fix for sub-daily rules anchored in the year 2000 did not help here: that fix moves the starting point of the search, and a rule with no occurrence is walked to the end of the representable range wherever the search starts.
A single next-occurrence computation on the released code path, one call each, measured on 0.11.0 with the sub-daily fix in place:
| rule | cost |
|---|---|
RRULE:FREQ=MINUTELY;BYMONTH=2;BYMONTHDAY=30 | 3.85 s |
RRULE:FREQ=SECONDLY;BYMONTH=2;BYMONTHDAY=30 | 5.73 s |
RRULE:FREQ=HOURLY;BYMONTH=2;BYMONTHDAY=30 | 4.39 s |
RRULE:FREQ=DAILY;BYMONTH=2;BYMONTHDAY=30 | 1.81 s |
RRULE:FREQ=MINUTELY;BYMONTH=2;BYMONTHDAY=30;BYSECOND=0,1,...,59 | 31.45 s |
A variant combining full BYMINUTE and BYSECOND lists at hourly frequency did not return within 10 minutes.
Reaching this over HTTP requires nothing beyond the rule itself:
curl -X POST $BASE/api/v1/automations/create -H "Authorization: Bearer $ATK" \
-H 'Content-Type: application/json' \
-d '{"name":"x","data":{"rrule":"RRULE:FREQ=MINUTELY;BYMONTH=2;BYMONTHDAY=30;BYSECOND=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59","prompt":"x"}}'
The measurements were taken at function level against the released validator, with a concurrent task on the same event loop recording how long it was starved. On 0.9.0, 0.10.2 and 0.11.3 the February 30th minutely rule blocked the event loop for 3.6 to 4.0 seconds per call. On 0.11.4 the same rule, and the full BYSECOND variant, are rejected after two seconds, and the event loop is never blocked for longer than its normal scheduling interval. Both automation routes call the validator directly inside their async handlers, so a request to either one blocks the instance for the same duration.
@Classic298
This page as .md · .json · CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
NVD data is provided by NIST and is public domain. Posts quoted belong to their authors.