{"id":"CVE-2026-109298","kind":"vulnerability","aliases":["CVE-2026-109298","GHSA-gww9-mhgj-pfqh"],"related":[],"title":"Any authenticated user can exhaust worker memory via a nested-repetition knowledge-search pattern","description":"# Any authenticated user can exhaust worker memory via a nested-repetition knowledge-search pattern\r\n\r\n## Summary\r\nThe built-in knowledge search tools let a chat participant choose the pattern used to grep knowledge files. That pattern is compiled before any of the limits on the search apply, and the regular expression engine expands counted repetition as it compiles, so a pattern that nests repetition counts forces it to build a structure vastly larger than the pattern itself. A pattern of a couple of dozen characters makes one worker allocate hundreds of megabytes, and because compiled patterns are cached for the life of the process, that memory is never returned. Neither the size of that work nor the number of times it can be repeated is bounded.\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 handed the knowledge grep tool, which is the affected path. The chat file grep tool and the `kb_exec` grep command share the same pattern compiler and are affected the same way.\r\n- Any authenticated user, no elevated role and no workspace permission.\r\n- One file the attacker can read. The tool returns early when no readable file is in scope, so a file is required, and `USER_PERMISSIONS_CHAT_FILE_UPLOAD` defaults to true so the attacker can supply their own.\r\n- A model willing to call the tool with the attacker's literal pattern. This is the one non-deterministic step: reliable in practice by instructing the model in your own chat, but not guaranteed on a given turn.\r\n- Only releases 0.11.0 through 0.11.3 carry the code. Earlier releases compiled with Python's standard library engine, which does not expand repetition this way and is unaffected. Releases 0.11.1 to 0.11.3 added a check on repetition counts, but it could be sidestepped with an escaped character or inline verbose mode, so those releases remain affected.\r\n- Deployments running with `UVICORN_WORKERS` at its default of 1 lose the whole instance; multi-worker deployments lose one worker per request.\r\n\r\n## Impact\r\nAvailability, against every other user of the affected worker. Peak allocation grows with the fourth power of the repetition count while the pattern stays the same length, so the attacker chooses the cost by editing two digits, and the compiled result is then retained in the engine's pattern cache, which holds up to 500 entries before it evicts anything. Each distinct pattern is therefore a permanent bite out of the worker rather than a spike that unwinds: measured directly, one pattern at a repetition count of 40 retained about 740 MB, six distinct patterns at counts of 30 to 35 retained 1.38 GB together, and under a 2 GB memory limit the next compile failed with the process out of memory. A modest sequence of requests walks the process into memory exhaustion with no recovery short of a restart, and a deployment whose container memory limit sits below the peak loses the worker outright. While each compile runs, the work happens synchronously on the event loop, so the worker serves nobody else for its duration. 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 by https://github.com/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da. Search patterns are now compiled with RE2, which refuses oversized repetition and runs under a fixed 1 MiB memory limit for the compiled pattern, and search patterns are also capped in length. Ordinary search patterns are unaffected, though regex searches now follow RE2 syntax (no lookarounds or backreferences). Upgrading is sufficient; there is nothing an operator has to configure.\r\n\r\n## Root cause\r\n- `backend/open_webui/tools/knowledge_fs.py`, `build_matcher`: compiled the caller's pattern with no limit on the result.\r\n- `backend/open_webui/tools/builtin.py`, `grep_knowledge_files`: the default-configuration caller that passes an unvalidated pattern to it; `grep_chat_files` and the `kb_exec` grep command reach the same function.\r\n- Affected setup: releases 0.11.0 through 0.11.3.\r\n\r\nThe earlier fix for catastrophic backtracking moved matching to an engine that supports a per-search timeout and placed every search under a shared time budget. That budget is acquired after the pattern has been compiled, so by construction it governs matching only. The replacement engine materialises counted repetition at compile time, which the previous one did not, so the migration introduced a new cost on a step that had never needed a limit before and that the budget was never positioned to cover. The pattern reached the compiler with no check beyond being non-empty. The count check added in 0.11.1 scanned the raw pattern text for repetition counts, so any spelling the engine reads as a count but the scan did not recognise went through unchecked.\r\n\r\n## Proof of concept\r\nAgainst a running instance, as a user with the default `user` role and no workspace permissions:\r\n\r\n1. Upload any small text file.\r\n2. In a chat on a model with the knowledge tools available, have the model grep that file for `((((a{40}){40}){40}){40})|x`.\r\n3. The worker allocates several hundred megabytes inside the compile, and requests arriving from other connections during that window are delayed by the full duration. Repeating the request with different repetition counts adds to the total rather than reusing it.\r\n\r\nObserved on the vulnerable code, with the tool call driven by a stub upstream so the model's choice to call the tool is deterministic. Everything from the tool call onward is unmodified Open WebUI code. Worker memory growth and the delay seen by a concurrent request on a second connection:\r\n\r\n| repetition count | worker memory | concurrent request delayed by |\r\n| ---------------- | ------------- | ----------------------------- |\r\n| literal pattern  | 0.1 MB        | 20 ms                         |\r\n| 32               | 273 MB        | 219 ms                        |\r\n| 40               | 612 MB        | 513 ms                        |\r\n\r\nThe pattern is 27 bytes at every row, so limiting the length of the input does not bound the cost. The engine used before 0.11.0 compiles all of these in under a millisecond with no measurable allocation, and 0.11.4 rejects them outright.\r\n\r\n## Credits\r\n@baeseungwon1010, for identifying that compilation runs outside the matching budget.","summary":"Open WebUI's built-in knowledge grep tool compiles a user-supplied regular expression that can expand into hundreds of megabytes of memory, and the compiled pattern stays cached for the life of the process. An authenticated user can repeatedly send such patterns to make the worker run out of memory and stall other users.","severity":"high","cvss":7.1,"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-400","cwe-770","open-webui","python","self-hosted"],"not_affected_if":["0.11.4-or-later","no-authenticated-users-outside-admins","pre-0.11.0-release"],"how_to_check":"- Check the installed Open WebUI version with `pip show open-webui` and see whether it is between `0.11.0` and `0.11.3`.\n- Confirm whether the knowledge builtin tools are enabled and `ENABLE_KB_EXEC` is left at its default `False`.","fix":"- Open WebUI: upgrade to `0.11.4` or later.","status":"open","published_at":"2026-09-27T19:32:16+00:00","first_seen_at":"2026-11-09T22:53:27+00:00","triaged_at":"2026-11-09T23:00:48+00:00","updated_at":"2026-11-09T23:10:12+00:00","category":"ai-tooling","confidence":0.9,"triage":{"at":"2026-11-09T23:00:48Z","model":"claude-haiku-5-5","output":{"fix":"- Open WebUI: upgrade to `0.11.4` or later.","reach":"internet","title":"Open WebUI: knowledge search pattern lets any user exhaust worker memory","impact":"medium","summary":"Open WebUI's built-in knowledge grep tool compiles a user-supplied regular expression that can expand into hundreds of megabytes of memory, and the compiled pattern stays cached for the life of the process. An authenticated user can repeatedly send such patterns to make the worker run out of memory and stall other users.","audience":"businesses","category":"ai-tooling","nicknames":[],"who_cares":["open-webui","self-hosted","python"],"confidence":0.9,"fix_status":"available","needs_auth":"yes","worst_case":"A user exhausts worker memory and knocks the service offline for others.","analyst_note":"","how_to_check":"- Check the installed Open WebUI version with `pip show open-webui` and see whether it is between `0.11.0` and `0.11.3`.\n- Confirm whether the knowledge builtin tools are enabled and `ENABLE_KB_EXEC` is left at its default `False`.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["pre-0.11.0-release","0.11.4-or-later","no-authenticated-users-outside-admins"],"who_is_affected":"Teams running Open WebUI releases 0.11.0 through 0.11.3 with the default knowledge tools, where any signed-in user can upload a file and have the model grep it with a crafted pattern. Deployments on earlier releases, or on 0.11.4 and later, are not affected. Multi-worker deployments lose one worker per request, while a single-worker default instance can lose everything.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"medium"},"cost_usd":0.000986,"input_tokens":6652,"output_tokens":641,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-109298':19A,27A '-2026':18A,26A '-400':35B '-770':37B '/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da.':650C '0.11.0':376C '0.11.1':402C '0.11.3':378C,404C '0.11.4':646C '1':438C,667C '1.38':555C '2':561C '30':551C '35':553C '40':540C '500':507C '740':543C 'add':405C 'affect':263C,283C,428C,460C 'ai':32B 'ai-tool':31B 'alloc':192C,463C 'also':679C 'alter':642C 'anyth':512C 'appli':150C 'attack':300C,330C,344C,482C 'authent':2A,83B,103C,288C 'avail':453C 'backend/open_webui/tools/builtin.py':726C 'backend/open_webui/tools/knowledge_fs.py':712C 'backrefer':698C 'bite':520C 'bound':229C 'build':172C,713C 'built':49B,121C 'built-in':48B,120C 'builtin':235C 'cach':75B,201C,502C 'call':339C 'caller':717C,734C 'cap':680C 'carri':379C 'caus':711C 'charact':188C,419C 'chat':128C,266C,322C,366C 'check':407C 'choos':130C,483C 'code':381C 'command':275C 'compil':54B,72B,141C,161C,198C,280C,384C,492C,567C,610C,655C,673C,715C 'confidenti':632C 'configur':232C,709C,733C 'contain':597C 'cost':485C 'could':413C 'count':157C,168C,410C,472C,538C,549C 'coupl':185C 'cve':17A,25A 'cwe':34B,36B 'data':638C 'default':231C,241C,249C,325C,436C,732C 'default-configur':731C 'deploy':429C,446C,595C 'determinist':354C 'digit':489C 'direct':532C 'distinct':514C,546C 'dozen':187C 'durat':628C 'earli':306C 'earlier':382C 'edit':487C 'effect':635C 'elev':291C 'els':625C 'enabl':239C,244C 'engin':155C,390C,499C 'entri':508C 'escap':418C 'event':618C 'everi':455C 'evict':511C 'exec':246C,273C 'exhaust':5A,106C,585C 'expand':63B,156C,394C 'express':60B,154C 'fail':568C 'fals':251C 'file':137C,267C,298C,310C,316C,323C,729C 'fix':643C,644C,666C 'follow':692C 'forc':169C 'fourth':467C 'gb':556C,562C 'ghsa':21A 'ghsa-gww9-mhgj-pfqh':20A 'github.com':649C 'github.com/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da.':648C 'given':372C 'grep':52B,135C,258C,268C,274C,727C 'group':237C 'grow':464C 'guarante':369C 'gww9':22A 'hand':255C 'happen':614C 'hold':504C 'host':44B 'hundr':65B,193C 'impact':452C 'inlin':421C 'instanc':442C 'instruct':360C 'integr':634C 'kb':245C,272C 'knowledg':14A,51B,115C,123C,136C,234C,257C,728C 'knowledge-search':13A,114C 'larger':176C 'length':479C,682C 'let':126C 'librari':389C 'life':78B,204C 'limit':146C,564C,599C,670C,722C 'liter':346C 'lookaround':696C 'loop':619C 'lose':439C,447C,604C 'make':91B,189C 'matcher':714C 'mb':544C 'measur':531C 'megabyt':67B,195C 'memori':7A,69B,97B,108C,209C,563C,574C,584C,598C,669C 'mhgj':23A 'mib':668C 'mode':423C 'model':253C,336C,362C 'modest':576C 'multi':444C 'multi-work':443C 'neither':213C 'nest':11A,112C,166C 'nested-repetit':10A,111C 'never':211C 'next':566C 'nobodi':624C 'non':353C 'non-determinist':352C 'noth':704C 'number':221C 'one':190C,297C,351C,448C,533C 'open':29A,39B,45B 'open-webui':28A,38B 'oper':706C 'ordinari':683C 'outright':607C 'overs':660C 'particip':129C 'pass':736C 'pat':739C 'path':264C 'pattern':16A,73B,89B,117C,132C,139C,164C,179C,182C,199C,279C,347C,475C,501C,515C,534C,547C,652C,674C,677C,685C,719C 'peak':462C,603C 'per':450C 'perman':519C 'permiss':296C,321C 'pfqh':24A 'power':468C 'practic':358C 'precondit':230C 'process':81B,207C,571C,582C 'python':41B,386C 'rather':525C 're2':657C,693C 'read':302C,640C 'readabl':309C 'recoveri':588C 'refus':659C 'regex':689C 'regular':59B,153C 'releas':375C,383C,401C,426C 'reliabl':356C 'remain':427C 'repeat':86B,227C 'repetit':12A,113C,158C,167C,395C,409C,471C,537C,661C 'request':451C,579C 'requir':318C 'restart':592C 'result':493C,725C 'retain':496C,541C,554C 'return':212C,305C 'role':292C 'root':710C 'run':94B,430C,611C,663C 'scope':313C 'search':15A,116C,124C,149C,651C,676C,684C,690C 'self':43B 'self-host':42B 'send':87B 'sequenc':577C 'serv':623C 'share':276C 'short':589C 'sidestep':415C 'sit':600C 'six':545C 'size':215C 'spike':528C 'stall':99B 'standard':388C 'stay':74B,476C 'step':355C 'structur':174C 'suffici':701C 'summari':118C 'suppli':58B,332C 'synchron':615C 'syntax':694C 'therefor':517C 'though':688C 'time':223C 'togeth':557C 'tool':33B,53B,125C,236C,259C,269C,304C,341C 'true':327C 'turn':373C 'two':488C 'unaffect':400C,687C 'unvalid':738C 'unwind':530C 'upgrad':699C 'upload':324C 'use':133C 'user':3A,57B,84B,101B,104C,289C,320C,457C 'user-suppli':56B 'uvicorn':432C 'vast':175C 'verbos':422C 'via':8A,109C 'walk':580C 'way':286C,397C 'webui':30A,40B,46B 'whole':441C 'whose':596C 'will':337C 'work':218C,613C 'worker':6A,93B,107C,191C,433C,445C,449C,461C,524C,606C,622C 'workspac':295C","nicknames":[],"mitigations":[],"who_affected":"Teams running Open WebUI releases 0.11.0 through 0.11.3 with the default knowledge tools, where any signed-in user can upload a file and have the model grep it with a crafted pattern. Deployments on earlier releases, or on 0.11.4 and later, are not affected. Multi-worker deployments lose one worker per request, while a single-worker default instance can lose everything.","tier":"B","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"businesses","plain_action":null,"pkeys":["openwebui"],"ptokens":["open","webui"],"labels":["aitooling","cwe400","cwe770","high","openwebui","pypi","python","selfhosted"],"campaign_type":null,"search_a":"'-109298':19A,27A '-2026':18A,26A 'authent':2A 'cve':17A,25A 'exhaust':5A 'ghsa':21A 'ghsa-gww9-mhgj-pfqh':20A 'gww9':22A 'knowledg':14A 'knowledge-search':13A 'memori':7A 'mhgj':23A 'nest':11A 'nested-repetit':10A 'open':29A 'open-webui':28A 'pattern':16A 'pfqh':24A 'repetit':12A 'search':15A 'user':3A 'via':8A 'webui':30A 'worker':6A","search_b":"'-400':35B '-770':37B 'ai':32B 'ai-tool':31B 'authent':83B 'built':49B 'built-in':48B 'cach':75B 'compil':54B,72B 'cwe':34B,36B 'expand':63B 'express':60B 'grep':52B 'host':44B 'hundr':65B 'knowledg':51B 'life':78B 'make':91B 'megabyt':67B 'memori':69B,97B 'open':39B,45B 'open-webui':38B 'pattern':73B,89B 'process':81B 'python':41B 'regular':59B 'repeat':86B 'run':94B 'self':43B 'self-host':42B 'send':87B 'stall':99B 'stay':74B 'suppli':58B 'tool':33B,53B 'user':57B,84B,101B 'user-suppli':56B 'webui':40B,46B 'worker':93B","search_c":"'/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da.':650C '0.11.0':376C '0.11.1':402C '0.11.3':378C,404C '0.11.4':646C '1':438C,667C '1.38':555C '2':561C '30':551C '35':553C '40':540C '500':507C '740':543C 'add':405C 'affect':263C,283C,428C,460C 'alloc':192C,463C 'also':679C 'alter':642C 'anyth':512C 'appli':150C 'attack':300C,330C,344C,482C 'authent':103C,288C 'avail':453C 'backend/open_webui/tools/builtin.py':726C 'backend/open_webui/tools/knowledge_fs.py':712C 'backrefer':698C 'bite':520C 'bound':229C 'build':172C,713C 'built':121C 'built-in':120C 'builtin':235C 'cach':201C,502C 'call':339C 'caller':717C,734C 'cap':680C 'carri':379C 'caus':711C 'charact':188C,419C 'chat':128C,266C,322C,366C 'check':407C 'choos':130C,483C 'code':381C 'command':275C 'compil':141C,161C,198C,280C,384C,492C,567C,610C,655C,673C,715C 'confidenti':632C 'configur':232C,709C,733C 'contain':597C 'cost':485C 'could':413C 'count':157C,168C,410C,472C,538C,549C 'coupl':185C 'data':638C 'default':231C,241C,249C,325C,436C,732C 'default-configur':731C 'deploy':429C,446C,595C 'determinist':354C 'digit':489C 'direct':532C 'distinct':514C,546C 'dozen':187C 'durat':628C 'earli':306C 'earlier':382C 'edit':487C 'effect':635C 'elev':291C 'els':625C 'enabl':239C,244C 'engin':155C,390C,499C 'entri':508C 'escap':418C 'event':618C 'everi':455C 'evict':511C 'exec':246C,273C 'exhaust':106C,585C 'expand':156C,394C 'express':154C 'fail':568C 'fals':251C 'file':137C,267C,298C,310C,316C,323C,729C 'fix':643C,644C,666C 'follow':692C 'forc':169C 'fourth':467C 'gb':556C,562C 'github.com':649C 'github.com/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da.':648C 'given':372C 'grep':135C,258C,268C,274C,727C 'group':237C 'grow':464C 'guarante':369C 'hand':255C 'happen':614C 'hold':504C 'hundr':193C 'impact':452C 'inlin':421C 'instanc':442C 'instruct':360C 'integr':634C 'kb':245C,272C 'knowledg':115C,123C,136C,234C,257C,728C 'knowledge-search':114C 'larger':176C 'length':479C,682C 'let':126C 'librari':389C 'life':204C 'limit':146C,564C,599C,670C,722C 'liter':346C 'lookaround':696C 'loop':619C 'lose':439C,447C,604C 'make':189C 'matcher':714C 'mb':544C 'measur':531C 'megabyt':195C 'memori':108C,209C,563C,574C,584C,598C,669C 'mib':668C 'mode':423C 'model':253C,336C,362C 'modest':576C 'multi':444C 'multi-work':443C 'neither':213C 'nest':112C,166C 'nested-repetit':111C 'never':211C 'next':566C 'nobodi':624C 'non':353C 'non-determinist':352C 'noth':704C 'number':221C 'one':190C,297C,351C,448C,533C 'oper':706C 'ordinari':683C 'outright':607C 'overs':660C 'particip':129C 'pass':736C 'pat':739C 'path':264C 'pattern':117C,132C,139C,164C,179C,182C,199C,279C,347C,475C,501C,515C,534C,547C,652C,674C,677C,685C,719C 'peak':462C,603C 'per':450C 'perman':519C 'permiss':296C,321C 'power':468C 'practic':358C 'precondit':230C 'process':207C,571C,582C 'python':386C 'rather':525C 're2':657C,693C 'read':302C,640C 'readabl':309C 'recoveri':588C 'refus':659C 'regex':689C 'regular':153C 'releas':375C,383C,401C,426C 'reliabl':356C 'remain':427C 'repeat':227C 'repetit':113C,158C,167C,395C,409C,471C,537C,661C 'request':451C,579C 'requir':318C 'restart':592C 'result':493C,725C 'retain':496C,541C,554C 'return':212C,305C 'role':292C 'root':710C 'run':430C,611C,663C 'scope':313C 'search':116C,124C,149C,651C,676C,684C,690C 'sequenc':577C 'serv':623C 'share':276C 'short':589C 'sidestep':415C 'sit':600C 'six':545C 'size':215C 'spike':528C 'standard':388C 'stay':476C 'step':355C 'structur':174C 'suffici':701C 'summari':118C 'suppli':332C 'synchron':615C 'syntax':694C 'therefor':517C 'though':688C 'time':223C 'togeth':557C 'tool':125C,236C,259C,269C,304C,341C 'true':327C 'turn':373C 'two':488C 'unaffect':400C,687C 'unvalid':738C 'unwind':530C 'upgrad':699C 'upload':324C 'use':133C 'user':104C,289C,320C,457C 'uvicorn':432C 'vast':175C 'verbos':422C 'via':109C 'walk':580C 'way':286C,397C 'whole':441C 'whose':596C 'will':337C 'work':218C,613C 'worker':107C,191C,433C,445C,449C,461C,524C,606C,622C 'workspac':295C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-09-27T19:32:16+00:00","kev":null,"cvss_vector":"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","cvss_by":"disclosure@vulncheck.com","poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-gww9-mhgj-pfqh","url":"https://github.com/open-webui/open-webui/security/advisories/GHSA-gww9-mhgj-pfqh","severity":"medium","published_at":"2026-09-27T19:32:16+00:00","modified_at":"2026-10-28T20:47:14+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-109298","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-109298","severity":null,"published_at":"2026-10-12T17:17:23+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":110647,"url":"https://github.com/open-webui/open-webui/security/advisories/GHSA-gww9-mhgj-pfqh","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":"2026-09-27T19:32:16+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":111037,"url":"https://github.com/open-webui/open-webui/commit/97e013a66169c4fcd7f26ab9e41a4ff260ffd4da","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":111039,"url":"https://www.vulncheck.com/advisories/open-webui-0.11.0-before-0.11.4-memory-exhaustion-via-knowledge-search-regex","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"}