Open WebUI CVE-2026-45316
LOWAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
ReconAttacker requests read-only share of target note
-
DeliveryOwner grants read permission via access/update
-
ExploitAttacker authenticates with valid credentials
-
InstallAttacker sends POST request to /api/v1/notes/{id}/pin endpoint
-
C2Permission check reads 'read' instead of 'write'
-
ExecuteToggle operation executes
-
ImpactNote is_pinned state modified
-
Step 8Change visible to all users with access
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Authorization logic validation
MITRE ATT&CK
1 technique across 1 tactic: Privilege Escalation The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires: (1) the target Open WebUI instance must have shared notes functionality enabled (default configuration); (2) the attacker must have been explicitly granted read-only access to a specific note via the access/update endpoint (not a default or guest state); (3) the attacker must possess a valid authentication token for their user account; and (4) the note must exist and be owned by another user (self-owned notes are not affected as the owner has full access). The vulnerability does NOT affect notes that are not explicitly shared, private notes, or systems where notes sharing is disabled. User interaction is required only in the sense that the note owner must have actively shared the note with the attacker; no victim interaction with the attacker's crafted request is needed. |
| Impact | CVSS 3.5 (Low) with vector AV:N/AC:L/PR:L/UI:R reflects limited scope and impact-the vulnerability requires low complexity network access, low privilege (read-only user), user interaction, and results only in integrity impact (is_pinned state modification) with no confidentiality or availability impact. The low CVSS score is justified: exploitation cannot alter note content, title, or access grants, and the modified is_pinned state affects only visual presentation (pin grouping in UI). However, CVSS does not fully capture the violation of authorization semantics-a read-only permission is being used to trigger a state-modifying write operation, breaching the fundamental access control boundary. Exploitation is trivial (single POST request) and requires only network access and read-level sharing, making it easily discoverable and reproducible. The publicly available proof-of-concept with step-by-step HTTP requests confirms practical exploitability. From an SSVC perspective, this is not a critical security risk (no remote code execution, data exfiltration, or service disruption), but it is an authorization logic bug that violates the security model and should be patched to maintain access control integrity. Organizations using shared notes with granular read/write permissions may view this as higher-priority from a governance standpoint, even though technical impact is minimal. |
| Exploit ScenarioDerived | An attacker (UserB) gains read-only access to a shared note through legitimate sharing by the note owner (UserA) via the /api/v1/notes/{id}/access/update endpoint. The attacker then sends a POST request to /api/v1/notes/{id}/pin with their read-only authentication token, which bypasses the insufficient permission check and toggles the is_pinned boolean state. The attacker can repeat this action to toggle the pin status repeatedly, disrupting the note's organization state visible to the note owner and other collaborators. This requires only network access and an existing read-only share relationship. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – May 14, 2026
Open WebUI versions up to 0.9.2 allow users with read-only access to shared notes to toggle the pin status via the POST /api/v1/notes/{id}/pin endpoint, which incorrectly checks for read permission instead of write permission. This privilege escalation enables read-only users to perform a write operation (toggling is_pinned state) that should be restricted to users with explicit write access. The vulnerability is limited to the pin operation and does not permit modification of note content, title, or access grants. Publicly available proof-of-concept demonstrates the bypass across all shared notes with read access.
RemediationAI
Upgrade Open WebUI to version 0.9.3 or later immediately, as the vendor has released a patched version containing the one-line permission string correction (changing permission='read' to permission='write' in the pin_note_by_id endpoint). If upgrade is not immediately possible, a temporary compensating control is to disable note sharing entirely or restrict it to users trusted with write access, though this reduces functionality. The fix is a simple patch in backend/open_webui/routers/notes.py line 437, changing the permission parameter from 'read' to 'write' in the AccessGrants.has_access() call within the pin_note_by_id function, aligning the pin endpoint with update and delete endpoint permission logic. No workaround configuration option exists; patching is the only remediation.
Affected Packages
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
Open WebUI is a Python-based web application framework with an access control system using an AccessGrants model that enforces permission checks (read vs. write) on shared resources. The vulnerability exists in the notes router backend at lines 412-444 of backend/open_webui/routers/notes.py, where the PIN endpoint uses AsyncHTTPException-based permission validation. Unlike the correctly implemented update and delete endpoints that check permission='write', the pin endpoint invokes AccessGrants.has_access() with permission='read', permitting the toggle operation despite the semantic requirement that state-modifying actions demand write authorization. The root cause is a permission string mismatch: the endpoint performs a write operation (Notes.toggle_note_pinned_by_id) but validates only read access, violating the principle of least privilege and failing to enforce role-based access control (RBAC) consistently across the API surface.
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
AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:L/A:N
Primary rating from GitHub Advisory · only source for this CVE.
CVSS VectorGitHub Advisory
DescriptionGitHub Advisory
Summary
The POST /api/v1/notes/{id}/pin endpoint performs a write operation (toggling the is_pinned field) but only checks for read permission. Users with read-only access to a shared note can pin/unpin it, which is a state-modifying action that should require write permission. All other write endpoints (update, delete, access/update) correctly check for write permission.
Details
Affected code: backend/open_webui/routers/notes.py lines 412-444
@router.post('/{id}/pin', response_model=Optional[NoteModel])
async def pin_note_by_id(...):
# ...
if user.role != 'admin' and (
user.id != note.user_id
and not await AccessGrants.has_access(
user_id=user.id,
resource_type='note',
resource_id=note.id,
permission='read',
# BUG: should be 'write'
db=db,
)
):
raise HTTPException(...)
note = await Notes.toggle_note_pinned_by_id(id, db=db)
# write operationCompare with update endpoint (correct, line 318-327):
async def update_note_by_id(...):
# ...
and not await AccessGrants.has_access(
permission='write',
# correctly checks 'write'
)PoC
Environment: Open WebUI v0.9.2, default configuration with notes sharing enabled.
Setup:
- UserA creates a note
- UserA shares note with UserB with
readpermission viaPOST /api/v1/notes/{id}/access/updatewith{"access_grants":[{"principal_type":"user","principal_id":"USERB_ID","permission":"read"}]}
Test:
# Step 1: UserB reads note (READ permission) -> 200 OK, write_access: false
curl -s http://TARGET/api/v1/notes/$NOTE_ID \
-H "Authorization: Bearer $TOKEN_B"
# Result: 200 OK, "write_access": false
# Step 2: UserB updates note (WRITE operation) -> 403 Forbidden (correctly blocked)
curl -s -X POST http://TARGET/api/v1/notes/$NOTE_ID/update \
-H "Authorization: Bearer $TOKEN_B" \
-H "Content-Type: application/json" \
-d '{"title":"HACKED","content":"pwned","data":{"type":"note"}}'
# Result: 403 Forbidden
# Step 3: UserB pins note (WRITE operation, but only checks READ) -> 200 OK (BUG!)
curl -s -X POST http://TARGET/api/v1/notes/$NOTE_ID/pin \
-H "Authorization: Bearer $TOKEN_B"
# Result: 200 OK, "is_pinned": true
# Step 4: UserB can toggle pin repeatedly
curl -s -X POST http://TARGET/api/v1/notes/$NOTE_ID/pin \
-H "Authorization: Bearer $TOKEN_B"
# Result: 200 OK, "is_pinned": false (toggled back)E2E Verified Result:
- Step 1: UserB reads note (READ) -> 200 OK ✓
- Step 2: UserB updates note (WRITE) -> 403 Forbidden ✓ (correctly blocked)
- Step 3: UserB pins note (WRITE via READ) -> 200 OK, is_pinned: true ✗ (BUG)
- Step 4: UserB toggles pin again -> 200 OK, is_pinned: false ✗ (repeated write)
Impact
- A user with only
readaccess to a shared note can toggle itsis_pinnedstatus - This modifies the note's state without write authorization
- The pin status change is visible to the note owner and all other users with access
- Privilege escalation from read to write on the pin operation
Limitations: Only affects the is_pinned boolean field. Cannot modify title, content, or access_grants. Requires at least read access via explicit sharing.
Fix
One-line fix - change permission='read' to permission='write' in pin_note_by_id:
# backend/open_webui/routers/notes.py, line 437
- permission='read',
+ permission='write',This makes the pin endpoint consistent with update and delete endpoints.
Threat Intelligence Overview
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.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.
Privilege escalation occurs when an attacker leverages flaws in access control mechanisms to gain permissions beyond what they were originally granted.
Affected Products (CPE)GitHub Advisory
Wazuh SIEM platform versions 4.4.0 through 4.9.0 contain an unsafe deserialization vulnerability in the DistributedAPI t
BentoML version 1.4.2 and earlier contains an unauthenticated remote code execution vulnerability through insecure deser
pgAdmin 4 contains critical remote code execution vulnerabilities in the Query Tool download and Cloud Deployment endpoi
The renderLocalView function in render/views.py in graphite-web in Graphite 0.9.5 through 0.9.10 uses the pickle Python
BentoML is a Python library for building online serving systems optimized for AI apps and model inference. Rated critica
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
pyLoad download manager version prior to 0.5.0b3.dev77 exposes the Flask SECRET_KEY through an unauthenticated endpoint.
Langflow (a visual LLM pipeline builder) contains a critical unauthenticated code execution vulnerability (CVE-2026-3301
In Mercurial before 4.1.3, "hg serve --stdio" allows remote authenticated users to launch the Python debugger, and conse
Unauthenticated remote code execution affects Kestra OSS (the open-source event-driven orchestration platform) prior to
Unauthenticated remote code execution in Marimo ≤0.20.4 allows attackers to execute arbitrary system commands via the `/
pyLoad is the free and open-source Download Manager written in pure Python. Rated medium severity (CVSS 5.3), this vulne
GHSA-jx2x-j75f-xq3j
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB