From 58cba88c9249c0c060fcba77d8f7b7fb444aeaaf Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Wed, 22 Apr 2026 02:42:22 +0300 Subject: [PATCH] docs(immich-ssrf): surface NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS hint in error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Homelab/LAN Immich instances trip the SSRF guard (Host 192.168.x resolves to blocked address). The fix is to set NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1 in the runtime env — call that out directly in the error message so operators don't have to dig through source to find it. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../notify_bridge_core/providers/immich/client.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/notify_bridge_core/providers/immich/client.py b/packages/core/src/notify_bridge_core/providers/immich/client.py index 5a31f37..93b2a86 100644 --- a/packages/core/src/notify_bridge_core/providers/immich/client.py +++ b/packages/core/src/notify_bridge_core/providers/immich/client.py @@ -61,14 +61,15 @@ class ImmichClient: # SSRF guard — admin-set Immich URLs are loaded from provider config # which can be mutated via PATCH /api/providers or imported via # prepare-restore, so we revalidate at construction time rather than - # trusting DB state. ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` bypasses - # for dev against localhost Immich. + # trusting DB state. Homelab deployments pointing at RFC1918 targets + # must set ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` in the runtime env. if self._url: try: validate_outbound_url(self._url) except UnsafeURLError as err: raise UnsafeURLError( - f"Refusing to build ImmichClient for unsafe URL {self._url!r}: {err}" + f"Refusing to build ImmichClient for unsafe URL {self._url!r}: {err}. " + "If this is a LAN/homelab Immich, set NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1." ) from err @property @@ -81,9 +82,8 @@ class ImmichClient: @external_domain.setter def external_domain(self, value: str | None) -> None: - # Mirror the constructor's SSRF guard — external_domain is used to - # build URLs that leak into rendered notifications, but any code path - # that eventually fetches this URL would otherwise bypass the check. + # Mirror the constructor's SSRF guard. Set + # ``NOTIFY_BRIDGE_ALLOW_PRIVATE_URLS=1`` for LAN/homelab targets. if value: try: validate_outbound_url(value)