From 4f751fdcc6393c5dbc3b700d4d0c9f153dd752dd Mon Sep 17 00:00:00 2001 From: user <70670632+stuxf@users.noreply.github.com> Date: Wed, 29 Apr 2026 21:18:07 +0000 Subject: [PATCH] fix(proxy): also accept LITELLM_ASSETS_PATH for /get_favicon local path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Align ``/get_favicon``'s allowed-root list with ``/get_image``'s. Both endpoints now accept paths under any of: * ``LITELLM_ASSETS_PATH`` (or its default — ``/var/lib/litellm/assets`` for non-root, the package dir otherwise) * the package's bundled-asset dir (``proxy/_experimental/out`` for the default favicon, ``proxy/`` for the default logo) * the proxy package dir (``current_dir``) as a final fallback Without this, an admin who put a custom favicon under ``LITELLM_ASSETS_PATH`` (e.g. mounted into the container at ``/var/lib/litellm/assets/favicon.ico``) would have the favicon endpoint silently fall back to the default after the previous commit's path-containment guard. The logo endpoint already accepted this root. Co-Authored-By: Claude Opus 4.7 (1M context) --- litellm/proxy/proxy_server.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index ead8e8f6b9d..ef17aab73e6 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -12339,7 +12339,13 @@ async def get_favicon(): current_dir = os.path.dirname(os.path.abspath(__file__)) default_favicon = os.path.join(current_dir, "_experimental", "out", "favicon.ico") - favicon_assets_dir = os.path.dirname(default_favicon) + favicon_default_dir = os.path.dirname(default_favicon) + + # Admin-managed asset directory (parallels ``/get_image``). Custom + # favicons placed here remain readable post-fix. + is_non_root = os.getenv("LITELLM_NON_ROOT", "").lower() == "true" + default_assets_dir = "/var/lib/litellm/assets" if is_non_root else current_dir + assets_dir = os.getenv("LITELLM_ASSETS_PATH", default_assets_dir) favicon_url = os.getenv("LITELLM_FAVICON_URL", "") @@ -12364,7 +12370,7 @@ async def get_favicon(): # ``/get_favicon`` is unauthenticated. Validate any admin-configured # local path against an allowlist of asset roots — see ``/get_image`` # for the LFI threat-model rationale. - allowed_local_roots = [favicon_assets_dir, current_dir] + allowed_local_roots = [assets_dir, favicon_default_dir, current_dir] safe_favicon = resolve_local_asset_path(favicon_url, allowed_local_roots) if safe_favicon is not None: return FileResponse(safe_favicon, media_type="image/x-icon")