{"id":"CVE-2026-109295","kind":"vulnerability","aliases":["CVE-2026-109295","GHSA-gfjp-5hc9-852r"],"related":[],"title":"Any authenticated user can repeatedly stall a worker via file-search regex on the event loop","description":"# Any authenticated user can repeatedly stall a worker via file-search regex on the event loop\r\n\r\n## Summary\r\nThe built-in file search tools let a chat participant choose the pattern used to grep files. Since 0.11.0 each search has been capped at 2 seconds of matching time, but the matching itself still ran directly on the server's event loop. A crafted pattern that backtracks until the cap is hit therefore froze the whole worker for about 2 seconds on every call, and nothing stopped the calls from being repeated.\r\n\r\n## Preconditions\r\n- Default configuration. The knowledge builtin tool group is enabled by default, and with `ENABLE_KB_EXEC` at its default of `False` the model is offered `grep_knowledge_files`, which accepts a file id.\r\n- Any authenticated user, no elevated role and no workspace permission.\r\n- One file the attacker can read. `USER_PERMISSIONS_CHAT_FILE_UPLOAD` defaults to true and a user can always read their own upload.\r\n- A model willing to call the tool with the attacker's literal pattern. This is reliable in practice by instructing the model in your own chat, but not guaranteed on a given turn.\r\n- The chat file tool `grep_chat_files` is affected the same way, but it is only offered when a model's File Context capability has been turned off.\r\n- Deployments running with `UVICORN_WORKERS` at its default of 1 stall the whole instance; multi-worker deployments stall one worker per call.\r\n\r\n## Impact\r\nAvailability, against every other user of the affected worker. Each call held the event loop for the full 2 second budget, during which the worker handled no other request, and every further call from the same or another chat held it again. The same file searched with a literal pattern finished in a few milliseconds. There is no confidentiality or integrity effect, and no data is read or altered.\r\n\r\n## Fix\r\nFixed in 0.11.4. https://github.com/open-webui/open-webui/pull/29621 moved the built-in chat and knowledge file searches off the event loop into a worker thread, the knowledge filesystem search was moved off the event loop the same way, and pattern matching switched to the RE2 engine, which runs in linear time and cannot backtrack catastrophically. Upgrading is sufficient; there is nothing an operator has to configure.\r\n\r\n## Root cause\r\n- `backend/open_webui/tools/builtin.py`, `grep_knowledge_files` and `grep_chat_files`: called the synchronous file search directly from the async tool.\r\n- `backend/open_webui/tools/knowledge_fs.py`, `build_matcher`: compiled the caller's pattern with a backtracking engine under a 2 second timeout.\r\n- Affected builds: 0.11.0 through 0.11.3. Earlier versions had no time limit at all and are covered by GHSA-2f54-p244-32q6.\r\n\r\nThe fix for GHSA-2f54-p244-32q6 bounded how long one search could run, but a time limit on a synchronous call does not give the event loop back while the call is running. The search still executed on the loop thread, so for the whole budget the worker could not serve anyone else, and the budget reset on every tool call.\r\n\r\n## Proof of concept\r\nAgainst the tool code of 0.11.3 as an ordinary user:\r\n\r\n1. Upload a text file whose content is a single line of 28 `a` characters followed by `!`.\r\n2. In a chat, instruct the model to call `grep_knowledge_files` with the pattern `(a|a)+$` and that file's id.\r\n3. The tool returns `Search exceeded 2s, narrow the pattern` after about 2 seconds. A task scheduled every 50 ms on the same event loop does not run for 2.06 seconds while the search is in progress. Repeating the call repeats the stall.\r\n\r\nMeasured by running the real tool functions of each release with a concurrent 50 ms event-loop heartbeat (file lookup seeded directly with the file above):\r\n\r\n| version | tool | call time | longest heartbeat gap |\r\n| ------- | ---- | --------- | --------------------- |\r\n| 0.11.3 | grep_knowledge_files | 2.007s | 2.057s |\r\n| 0.11.3 | grep_chat_files | 2.009s | 2.059s |\r\n| 0.11.4 | grep_knowledge_files | 0.004s | 0.051s |\r\n| 0.11.4 | grep_chat_files | 0.005s | 0.051s |\r\n\r\n## Credits\r\n@yousif-IQ, for the finding.\r\n@tahahassan773, analysis.","summary":"Any logged-in user can submit a crafted regex through Open WebUI's built-in file search tools, which runs on the server's event loop and freezes the worker for about 2 seconds per call. Repeated calls can stall the worker again and again, denying service to other users.","severity":"medium","cvss":5.3,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"open-webui","fixed":["0.11.4"],"affected":">= 0.11.0, < 0.11.4","ecosystem":"pypi"}],"ecosystems":["pypi"],"tags":["ai-tooling","cwe-1333","open-webui","python","self-hosted"],"not_affected_if":["managed-hosting","version-0.11.4-or-later"],"how_to_check":"- Check the installed version with `pip show open-webui` and treat `0.11.0` through `0.11.3` as affected.\n- Confirm `UVICORN_WORKERS` and whether `ENABLE_KB_EXEC` is still at its default of `False`.","fix":"- `open-webui` `0.11.4`","status":"open","published_at":"2026-09-27T19:30:44+00:00","first_seen_at":"2026-11-09T22:53:27+00:00","triaged_at":"2026-11-09T23:01:18+00:00","updated_at":"2026-11-09T23:10:12+00:00","category":"ai-tooling","confidence":0.85,"triage":{"at":"2026-11-09T23:01:18Z","model":"claude-haiku-5-5","output":{"fix":"- `open-webui` `0.11.4`","reach":"network","title":"Open WebUI: file-search regex lets any user stall the server worker","impact":"low","summary":"Any logged-in user can submit a crafted regex through Open WebUI's built-in file search tools, which runs on the server's event loop and freezes the worker for about 2 seconds per call. Repeated calls can stall the worker again and again, denying service to other users.","audience":"businesses","category":"ai-tooling","nicknames":[],"who_cares":["open-webui","self-hosted","python"],"confidence":0.85,"fix_status":"available","needs_auth":"yes","worst_case":"Repeated requests freeze the server worker, denying service to other users.","analyst_note":"","how_to_check":"- Check the installed version with `pip show open-webui` and treat `0.11.0` through `0.11.3` as affected.\n- Confirm `UVICORN_WORKERS` and whether `ENABLE_KB_EXEC` is still at its default of `False`.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["version-0.11.4-or-later","managed-hosting"],"who_is_affected":"Self-hosted Open WebUI deployments on versions 0.11.0 through 0.11.3 where users can chat and use the built-in knowledge or chat file search tools. The default configuration is affected because the knowledge builtin tool group is enabled by default. Deployments on 0.11.4 or later, or where these tools are not offered to the model, can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"unknown"},"cost_usd":0.000888,"input_tokens":6004,"output_tokens":575,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-109295':20A,28A '-1333':36B '-2026':19A,27A '/open-webui/open-webui/pull/29621':415C '0.004':746C '0.051':748C '0.11.0':133C,514C '0.11.3':516C,605C,726C,734C '0.11.4':412C,742C,750C '1':325C,610C '2':78B,140C,175C,358C,509C,627C,661C '2.007':730C '2.009':738C '2.057':732C '2.059':740C '2.06':678C '28':622C '2f54':531C,539C '2s':655C '3':649C '32q6':533C,541C '50':667C,705C '5hc9':24A '852r':25A 'accept':218C 'affect':296C,347C,512C 'ai':33B 'ai-tool':32B 'alter':408C 'alway':250C 'anoth':377C 'anyon':587C 'async':493C 'attack':235C,264C 'authent':2A,97C,223C 'avail':340C 'back':563C 'backend/open_webui/tools/builtin.py':477C 'backend/open_webui/tools/knowledge_fs.py':495C 'backtrack':162C,462C,505C 'bound':542C 'budget':360C,581C,591C 'build':496C,513C 'built':59B,116C,419C 'built-in':58B,115C,418C 'builtin':193C 'call':81B,83B,179C,184C,259C,338C,350C,372C,485C,556C,566C,596C,635C,688C,721C 'caller':500C 'cannot':461C 'cap':138C,165C 'capabl':311C 'catastroph':463C 'caus':476C 'charact':624C 'chat':123C,240C,280C,289C,293C,378C,421C,483C,630C,736C 'choos':125C 'code':603C 'compil':498C 'concept':599C 'concurr':704C 'confidenti':398C 'configur':190C,474C 'content':616C 'context':310C 'could':547C,584C 'cover':527C 'craft':52B,159C 'cve':18A,26A 'cwe':35B 'data':404C 'default':189C,199C,207C,243C,323C 'deni':91B 'deploy':316C,333C 'direct':151C,490C,714C 'earlier':517C 'effect':401C 'elev':226C 'els':588C 'enabl':197C,202C 'engin':454C,506C 'event':16A,70B,111C,156C,353C,428C,442C,561C,672C,708C 'event-loop':707C 'everi':178C,342C,370C,594C,666C 'exceed':654C 'exec':204C 'execut':572C 'fals':209C 'file':11A,61B,106C,118C,131C,216C,220C,233C,241C,290C,294C,309C,384C,424C,480C,484C,488C,614C,638C,646C,711C,717C,729C,737C,745C 'file-search':10A,105C 'filesystem':436C 'finish':390C 'fix':409C,410C,535C 'follow':625C 'freez':73B 'froze':169C 'full':357C 'function':698C 'g':751C 'gap':725C 'gfjp':23A 'ghsa':22A,530C,538C 'ghsa-2f54-p244-32q6':529C,537C 'ghsa-gfjp-5hc9-852r':21A 'github.com':414C 'github.com/open-webui/open-webui/pull/29621':413C 'give':559C 'given':286C 'grep':130C,214C,292C,478C,482C,636C,727C,735C,743C 'group':195C 'guarante':283C 'handl':365C 'heartbeat':710C,724C 'held':351C,379C 'hit':167C 'host':43B 'id':221C,648C 'impact':339C 'instanc':329C 'instruct':274C,631C 'integr':400C 'kb':203C 'knowledg':192C,215C,423C,435C,479C,637C,728C,744C 'let':121C 'limit':522C,552C 'line':620C 'linear':458C 'liter':266C,388C 'log':46B 'logged-in':45B 'long':544C 'longest':723C 'lookup':712C 'loop':17A,71B,112C,157C,354C,429C,443C,562C,575C,673C,709C 'match':143C,147C,449C 'matcher':497C 'measur':692C 'millisecond':394C 'model':211C,256C,276C,307C,633C 'move':416C,439C 'ms':668C,706C 'multi':331C 'multi-work':330C 'narrow':656C 'noth':181C,469C 'offer':213C,304C 'one':232C,335C,545C 'open':30A,38B,55B 'open-webui':29A,37B 'oper':471C 'ordinari':608C 'p244':532C,540C 'particip':124C 'pattern':127C,160C,267C,389C,448C,502C,641C,658C 'per':80B,337C 'permiss':231C,239C 'practic':272C 'precondit':188C 'progress':685C 'proof':597C 'python':40B 'ran':150C 're2':453C 'read':237C,251C,406C 'real':696C 'regex':13A,53B,108C 'releas':701C 'reliabl':270C 'repeat':5A,82B,100C,187C,686C,689C 'request':368C 'reset':592C 'return':652C 'role':227C 'root':475C 'run':65B,317C,456C,548C,568C,676C,694C 'schedul':665C 'search':12A,62B,107C,119C,135C,385C,425C,437C,489C,546C,570C,653C,682C 'second':79B,141C,176C,359C,510C,662C,679C 'seed':713C 'self':42B 'self-host':41B 'serv':586C 'server':68B,154C 'servic':92B 'sinc':132C 'singl':619C 'stall':6A,85B,101C,326C,334C,691C 'still':149C,571C 'stop':182C 'submit':50B 'suffici':466C 'summari':113C 'switch':450C 'synchron':487C,555C 'task':664C 'text':613C 'therefor':168C 'thread':433C,576C 'time':144C,459C,521C,551C,722C 'timeout':511C 'tool':34B,63B,120C,194C,261C,291C,494C,595C,602C,651C,697C,720C 'true':245C 'turn':287C,314C 'upgrad':464C 'upload':242C,254C,611C 'use':128C 'user':3A,48B,95B,98C,224C,238C,248C,344C,609C 'uvicorn':319C 'version':518C,719C 'via':9A,104C 'way':299C,446C 'webui':31A,39B,56B 'whole':171C,328C,580C 'whose':615C 'will':257C 'worker':8A,75B,87B,103C,172C,320C,332C,336C,348C,364C,432C,583C 'workspac':230C","nicknames":[],"mitigations":[],"who_affected":"Self-hosted Open WebUI deployments on versions 0.11.0 through 0.11.3 where users can chat and use the built-in knowledge or chat file search tools. The default configuration is affected because the knowledge builtin tool group is enabled by default. Deployments on 0.11.4 or later, or where these tools are not offered to the model, can skip it.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["openwebui"],"ptokens":["open","webui"],"labels":["aitooling","cwe1333","medium","openwebui","pypi","python","selfhosted"],"campaign_type":null,"search_a":"'-109295':20A,28A '-2026':19A,27A '5hc9':24A '852r':25A 'authent':2A 'cve':18A,26A 'event':16A 'file':11A 'file-search':10A 'gfjp':23A 'ghsa':22A 'ghsa-gfjp-5hc9-852r':21A 'loop':17A 'open':30A 'open-webui':29A 'regex':13A 'repeat':5A 'search':12A 'stall':6A 'user':3A 'via':9A 'webui':31A 'worker':8A","search_b":"'-1333':36B '2':78B 'ai':33B 'ai-tool':32B 'built':59B 'built-in':58B 'call':81B,83B 'craft':52B 'cwe':35B 'deni':91B 'event':70B 'file':61B 'freez':73B 'host':43B 'log':46B 'logged-in':45B 'loop':71B 'open':38B,55B 'open-webui':37B 'per':80B 'python':40B 'regex':53B 'repeat':82B 'run':65B 'search':62B 'second':79B 'self':42B 'self-host':41B 'server':68B 'servic':92B 'stall':85B 'submit':50B 'tool':34B,63B 'user':48B,95B 'webui':39B,56B 'worker':75B,87B","search_c":"'/open-webui/open-webui/pull/29621':415C '0.004':746C '0.051':748C '0.11.0':133C,514C '0.11.3':516C,605C,726C,734C '0.11.4':412C,742C,750C '1':325C,610C '2':140C,175C,358C,509C,627C,661C '2.007':730C '2.009':738C '2.057':732C '2.059':740C '2.06':678C '28':622C '2f54':531C,539C '2s':655C '3':649C '32q6':533C,541C '50':667C,705C 'accept':218C 'affect':296C,347C,512C 'alter':408C 'alway':250C 'anoth':377C 'anyon':587C 'async':493C 'attack':235C,264C 'authent':97C,223C 'avail':340C 'back':563C 'backend/open_webui/tools/builtin.py':477C 'backend/open_webui/tools/knowledge_fs.py':495C 'backtrack':162C,462C,505C 'bound':542C 'budget':360C,581C,591C 'build':496C,513C 'built':116C,419C 'built-in':115C,418C 'builtin':193C 'call':179C,184C,259C,338C,350C,372C,485C,556C,566C,596C,635C,688C,721C 'caller':500C 'cannot':461C 'cap':138C,165C 'capabl':311C 'catastroph':463C 'caus':476C 'charact':624C 'chat':123C,240C,280C,289C,293C,378C,421C,483C,630C,736C 'choos':125C 'code':603C 'compil':498C 'concept':599C 'concurr':704C 'confidenti':398C 'configur':190C,474C 'content':616C 'context':310C 'could':547C,584C 'cover':527C 'craft':159C 'data':404C 'default':189C,199C,207C,243C,323C 'deploy':316C,333C 'direct':151C,490C,714C 'earlier':517C 'effect':401C 'elev':226C 'els':588C 'enabl':197C,202C 'engin':454C,506C 'event':111C,156C,353C,428C,442C,561C,672C,708C 'event-loop':707C 'everi':178C,342C,370C,594C,666C 'exceed':654C 'exec':204C 'execut':572C 'fals':209C 'file':106C,118C,131C,216C,220C,233C,241C,290C,294C,309C,384C,424C,480C,484C,488C,614C,638C,646C,711C,717C,729C,737C,745C 'file-search':105C 'filesystem':436C 'finish':390C 'fix':409C,410C,535C 'follow':625C 'froze':169C 'full':357C 'function':698C 'g':751C 'gap':725C 'ghsa':530C,538C 'ghsa-2f54-p244-32q6':529C,537C 'github.com':414C 'github.com/open-webui/open-webui/pull/29621':413C 'give':559C 'given':286C 'grep':130C,214C,292C,478C,482C,636C,727C,735C,743C 'group':195C 'guarante':283C 'handl':365C 'heartbeat':710C,724C 'held':351C,379C 'hit':167C 'id':221C,648C 'impact':339C 'instanc':329C 'instruct':274C,631C 'integr':400C 'kb':203C 'knowledg':192C,215C,423C,435C,479C,637C,728C,744C 'let':121C 'limit':522C,552C 'line':620C 'linear':458C 'liter':266C,388C 'long':544C 'longest':723C 'lookup':712C 'loop':112C,157C,354C,429C,443C,562C,575C,673C,709C 'match':143C,147C,449C 'matcher':497C 'measur':692C 'millisecond':394C 'model':211C,256C,276C,307C,633C 'move':416C,439C 'ms':668C,706C 'multi':331C 'multi-work':330C 'narrow':656C 'noth':181C,469C 'offer':213C,304C 'one':232C,335C,545C 'oper':471C 'ordinari':608C 'p244':532C,540C 'particip':124C 'pattern':127C,160C,267C,389C,448C,502C,641C,658C 'per':337C 'permiss':231C,239C 'practic':272C 'precondit':188C 'progress':685C 'proof':597C 'ran':150C 're2':453C 'read':237C,251C,406C 'real':696C 'regex':108C 'releas':701C 'reliabl':270C 'repeat':100C,187C,686C,689C 'request':368C 'reset':592C 'return':652C 'role':227C 'root':475C 'run':317C,456C,548C,568C,676C,694C 'schedul':665C 'search':107C,119C,135C,385C,425C,437C,489C,546C,570C,653C,682C 'second':141C,176C,359C,510C,662C,679C 'seed':713C 'serv':586C 'server':154C 'sinc':132C 'singl':619C 'stall':101C,326C,334C,691C 'still':149C,571C 'stop':182C 'suffici':466C 'summari':113C 'switch':450C 'synchron':487C,555C 'task':664C 'text':613C 'therefor':168C 'thread':433C,576C 'time':144C,459C,521C,551C,722C 'timeout':511C 'tool':120C,194C,261C,291C,494C,595C,602C,651C,697C,720C 'true':245C 'turn':287C,314C 'upgrad':464C 'upload':242C,254C,611C 'use':128C 'user':98C,224C,238C,248C,344C,609C 'uvicorn':319C 'version':518C,719C 'via':104C 'way':299C,446C 'whole':171C,328C,580C 'whose':615C 'will':257C 'worker':103C,172C,320C,332C,336C,348C,364C,432C,583C 'workspac':230C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-09-27T19:30:44+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:N/VA:L/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","cvss_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-gfjp-5hc9-852r","url":"https://github.com/open-webui/open-webui/security/advisories/GHSA-gfjp-5hc9-852r","severity":"medium","published_at":"2026-09-27T19:30:44+00:00","modified_at":"2026-10-28T20:47:09+00:00","first_seen_at":"2026-11-09T22:53:27+00:00","fetched_at":"2026-11-09T22:53:27+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-109295","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-109295","severity":null,"published_at":"2026-10-12T17:17:22+00:00","modified_at":"2026-10-23T22:16:54+00:00","first_seen_at":"2026-11-09T23:10:12+00:00","fetched_at":"2026-11-09T23:10:12+00:00","note":null}],"documents":[{"id":110650,"url":"https://github.com/open-webui/open-webui/security/advisories/GHSA-gfjp-5hc9-852r","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":"2026-09-27T19:30:44+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":111032,"url":"https://www.vulncheck.com/advisories/open-webui-0.11.0-before-0.11.4-redos-via-grep-knowledge-files-event-loop","title":"Third-party advisory: www.vulncheck.com","kind":"advisory","source":"nvd","publisher":"research","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Third-party advisory: www.vulncheck.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}