mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-18 05:05:09 +02:00
fix: enforce message ownership in group/DM channel update + delete endpoints (#24506)
* fix: enforce message ownership in group/DM channel update + delete endpoints `update_message_by_id` (channels.py:1348) and `delete_message_by_id` (channels.py:1550) branch on `channel.type`. The `else` branch (standard channels) correctly enforces `message.user_id != user.id` ownership before mutating, but the `if channel.type in ['group', 'dm']` branch only checked `is_user_channel_member` — channel membership alone, with no message ownership verification. Effect on group/DM channels: any verified member of the conversation could: - overwrite another member's message content while the server preserved `user_id=victim`, producing tampered content that renders to other members as the original author's authentic post (integrity + authenticity); - silently delete another member's messages, removing them from conversation history without trace (integrity). Reproduced end-to-end against v0.9.4 with three users (attacker, victim, viewer) sharing a group channel: attacker overwrites victim's message and deletes another, viewer reads the tampered content as victim-authored. Two patches, identical shape, mirror the `else` branch's existing ownership semantics: - `update_message_by_id` group/DM branch: add `if user.role != 'admin' and message.user_id != user.id: raise 403` immediately after the `is_user_channel_member` check. - `delete_message_by_id` group/DM branch: same. The standard-channel branch is unchanged (it already enforced ownership). Admins remain able to moderate any message, matching the existing semantic in the standard-channel branch. Reports consolidated under GHSA-wwhq-cx22-f7vv (earliest live filing of the group/DM-specific variant). Same gap previously surfaced and partially fixed under GHSA-jxwr-g6r6-j3fx (which addressed the standard-channel branch only) — this completes the cohort. * chore: trim comments
This commit is contained in:
@@ -1369,6 +1369,9 @@ async def update_message_by_id(
|
||||
if channel.type in ['group', 'dm']:
|
||||
if not await Channels.is_user_channel_member(channel.id, user.id, db=db):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT())
|
||||
# Membership is not authorship — block cross-member edits.
|
||||
if user.role != 'admin' and message.user_id != user.id:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT())
|
||||
else:
|
||||
if (
|
||||
user.role != 'admin'
|
||||
@@ -1570,6 +1573,9 @@ async def delete_message_by_id(
|
||||
if channel.type in ['group', 'dm']:
|
||||
if not await Channels.is_user_channel_member(channel.id, user.id, db=db):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT())
|
||||
# Membership is not authorship — block cross-member deletes.
|
||||
if user.role != 'admin' and message.user_id != user.id:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.DEFAULT())
|
||||
else:
|
||||
if (
|
||||
user.role != 'admin'
|
||||
|
||||
Reference in New Issue
Block a user