mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-05 02:41:34 +00:00
fix: scope every channel chat-completion message_id to the channel, not just the first
#24725 added a channel-access + message-scoping gate to the chat_completion `channel:` branch, but it validated only list(message_ids.values())[0]. A multimodel request (message_ids with more than one entry) could pass a permitted-channel id as the first value and a victim-channel message id as a later value; the fan-out then drove _make_channel_emitter to overwrite the victim message in a channel the caller cannot access. Validate every message_ids value against the channel, and make _make_channel_emitter fail closed so it only updates a message whose channel_id matches the channel in chat_id. Co-authored-by: DavidCarliez <271374756+DavidCarliez@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1a97751e37
commit
f8782dd46a
2 changed files with 10 additions and 4 deletions
|
|
@ -1834,8 +1834,10 @@ async def chat_completion(
|
|||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail=ERROR_MESSAGES.DEFAULT(),
|
||||
)
|
||||
target_message_id = list(message_ids.values())[0] if message_ids else None
|
||||
if target_message_id:
|
||||
# Every message_ids value must match the channel; first-only let a multimodel id slip past.
|
||||
for target_message_id in (message_ids or {}).values():
|
||||
if not target_message_id:
|
||||
continue
|
||||
target_message = await Messages.get_message_by_id(target_message_id)
|
||||
if target_message and target_message.channel_id != channel.id:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
|
|
@ -841,11 +841,15 @@ async def _make_channel_emitter(request_info):
|
|||
async def _emit_channel_update(content: str, done: bool = False):
|
||||
from open_webui.models.messages import MessageForm, Messages
|
||||
|
||||
# Fail closed: only update a message that actually belongs to this channel.
|
||||
msg = await Messages.get_message_by_id(message_id)
|
||||
if not msg or msg.channel_id != channel_id:
|
||||
return
|
||||
|
||||
update_form = MessageForm(content=content)
|
||||
if done:
|
||||
# Merge done flag into existing meta (preserve model_id etc.)
|
||||
msg = await Messages.get_message_by_id(message_id)
|
||||
existing_meta = (msg.meta or {}) if msg else {}
|
||||
existing_meta = msg.meta or {}
|
||||
update_form = MessageForm(
|
||||
content=content,
|
||||
meta={**existing_meta, 'done': True},
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue