mirror of
https://github.com/open-webui/open-webui.git
synced 2026-05-08 21:09:41 -05:00
[PR #23690] [CLOSED] feat: replace Google favicon API with backend proxy #27317
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/23690
Author: @Algorithm5838
Created: 4/14/2026
Status: ❌ Closed
Base:
dev← Head:feat/favicon-proxy📝 Commits (1)
6554c47feat: replace Google favicon API with backend proxy📊 Changes
3 files changed (+186 additions, -4 deletions)
View changed files
📝
backend/open_webui/routers/utils.py(+177 -1)📝
src/lib/components/chat/Messages/Citations.svelte(+1 -1)📝
src/lib/components/chat/Messages/ResponseMessage/WebSearchResults.svelte(+8 -2)📄 Description
Pull Request Checklist
Note to first-time contributors: Please open a discussion post in Discussions to discuss your idea/fix with the community before creating a pull request, and describe your changes before submitting a pull request.
This is to ensure large feature PRs are discussed with the community first, before starting work on it. If the community does not want this feature or it is not relevant for Open WebUI as a project, it can be identified in the discussion before working on the feature and submitting the PR.
Before submitting, make sure you've checked the following:
devbranch. PRs targetingmainwill be immediately closed.devto ensure no unrelated commits (e.g. frommain) are included. Push updates to the existing PR branch instead of closing and reopening.Changelog Entry
Description
Source icons in RAG citations and web search results were fetched client-side via Google's undocumented favicon service, leaking every cited domain to Google's servers and breaking entirely in offline or air-gapped environments.
This PR adds a backend proxy endpoint (
GET /api/v1/utils/favicon?url=...) that fetches favicons server-side:https://{domain}/favicon.icodirectly.<link rel="icon">tags, picking the best format (SVG > PNG > ICO, larger size preferred)./favicon.png.Results are cached in memory by domain.
Citations.svelteandWebSearchResults.svelteare updated to use the new endpoint.Added
GET /api/v1/utils/favicon?url=<encoded-url>inbackend/open_webui/routers/utils.pyChanged
Citations.svelteandWebSearchResults.svelte: source icon URLs updated from the Google S2 favicon service to the new endpoint.Deprecated
Removed
Fixed
on:errorfallback inWebSearchResults.svelte.Security
_is_safe_host()validates the resolved IP of both the domain and any parsed icon URL usingsocket.getaddrinfo+ipaddress, blocking loopback, private, link-local, and multicast addresses.Breaking Changes
Additional Information
hrefvalues are resolved viaurljoin,data:URIs are skipped, a browserUser-Agentheader is set, and a 5-second timeout is applied per request.DEBUGlevel on failure._is_safe_host()DNS resolution runs viaasyncio.to_threadso the event loop is not blocked.type="image/svg+xml"may not have a file extension, so the scorer checks the file extension first and falls back to the MIME subtype.Screenshots or Videos
Contributor License Agreement
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.