From 043784c2d0e1b36a74a12f8d091c83a9bb22027b Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 20 Sep 2026 00:03:15 +0200 Subject: [PATCH] fix: route external webhook avatar URLs through the profile image endpoint (#29892) The channel webhooks modal rendered a webhook's stored profile_image_url straight into an img tag, so opening it sent every viewer's browser to whatever external host that URL named, leaking client IP, User-Agent and Referer no matter how the server was configured. External URLs now render through the same webhook profile image endpoint the message list already uses, leaving it to the server to decide whether the browser is sent to that host. Locally picked images and the paths Open WebUI assigns itself still render inline, so previewing an upload before saving is unchanged, and the value written back on save is untouched. This only takes effect together with the companion backend change that gates the endpoint on ENABLE_PROFILE_IMAGE_URL_FORWARDING. Until that lands the endpoint still redirects and the browser still reaches the external host. Also worth knowing: the endpoint matches the scheme case-sensitively, so a URL stored as HTTPS:// falls back to the default image here, which is already what the message list shows for it. Verified in a browser against a local origin standing in for the external host: with forwarding on the avatar still renders through the endpoint in both places it appears, with forwarding off the browser makes no request to that origin, and picking a new file still previews immediately before saving. --- src/lib/components/channel/WebhookItem.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib/components/channel/WebhookItem.svelte b/src/lib/components/channel/WebhookItem.svelte index 04394c5ed5..6ccda8ce9c 100644 --- a/src/lib/components/channel/WebhookItem.svelte +++ b/src/lib/components/channel/WebhookItem.svelte @@ -22,6 +22,11 @@ let name = webhook.name; let image = webhook.profile_image_url || ''; + // The server decides whether an external avatar host is fetched. + $: imageSrc = image.toLowerCase().startsWith('http') + ? `${WEBUI_API_BASE_URL}/channels/webhooks/${webhook.id}/profile/image` + : image; + // Notify parent when changes occur $: if (name !== webhook.name || image !== (webhook.profile_image_url || '')) { onUpdate({ name: name.trim() || webhook.name, profile_image_url: image }); @@ -93,7 +98,7 @@ Do not alter, remove, obscure, or replace it except as LICENSE permits: https://docs.openwebui.com/license. --> @@ -130,7 +135,7 @@ Do not alter, remove, obscure, or replace it except as LICENSE permits: https://docs.openwebui.com/license. -->