diff --git a/src/lib/components/chat/Messages/Markdown/MarkdownInlineTokens.svelte b/src/lib/components/chat/Messages/Markdown/MarkdownInlineTokens.svelte
index 0daf389eec..01536a7bef 100644
--- a/src/lib/components/chat/Messages/Markdown/MarkdownInlineTokens.svelte
+++ b/src/lib/components/chat/Messages/Markdown/MarkdownInlineTokens.svelte
@@ -96,7 +96,7 @@
>
{/if}
{:else if token.type === 'image'}
-
+
{:else if token.type === 'strong'}
{:else if token.type === 'em'}
diff --git a/src/lib/components/common/Image.svelte b/src/lib/components/common/Image.svelte
index 3007d70caa..76cc6ccd1e 100644
--- a/src/lib/components/common/Image.svelte
+++ b/src/lib/components/common/Image.svelte
@@ -9,6 +9,7 @@
export let src = '';
export let alt = '';
+ export let allowExternal = false;
export let className = ` w-full ${($settings?.highContrastMode ?? false) ? '' : 'outline-hidden focus:outline-hidden'}`;
@@ -20,7 +21,7 @@
const i18n = getContext('i18n');
let _src = '';
- $: _src = safeImageUrl(src.startsWith('/') ? `${WEBUI_BASE_URL}${src}` : src);
+ $: _src = safeImageUrl(src.startsWith('/') ? `${WEBUI_BASE_URL}${src}` : src, allowExternal);
let showImagePreview = false;
diff --git a/src/lib/utils/safeImageUrl.ts b/src/lib/utils/safeImageUrl.ts
index 82a834ca07..1f63410fb0 100644
--- a/src/lib/utils/safeImageUrl.ts
+++ b/src/lib/utils/safeImageUrl.ts
@@ -11,18 +11,20 @@ const PLACEHOLDER_IMAGE = '/favicon.png';
* - data:image/* URIs
* - Same-origin URLs (starting with WEBUI_BASE_URL)
* - Gravatar URLs (https://www.gravatar.com/avatar/)
+ * - External HTTP(S) URLs when allowExternal is true
*
- * All other URLs (including arbitrary http(s):// origins) are rejected to
- * prevent client-side IP/UA/Referer leaks to attacker-controlled servers.
+ * All other URLs (including arbitrary http(s):// origins by default) are
+ * rejected to prevent client-side IP/UA/Referer leaks to attacker-controlled servers.
*/
-export function safeImageUrl(url: string): string {
+export function safeImageUrl(url: string, allowExternal = false): string {
if (!url || url === '') {
return `${WEBUI_BASE_URL}${PLACEHOLDER_IMAGE}`;
}
if (
- url.startsWith(WEBUI_BASE_URL) ||
+ (WEBUI_BASE_URL && url.startsWith(WEBUI_BASE_URL)) ||
url.startsWith('https://www.gravatar.com/avatar/') ||
+ (allowExternal && /^https?:\/\//i.test(url)) ||
url.startsWith('data:') ||
url.startsWith('/')
) {