isSafeDeploymentUrl is the guard that keeps the runtime proxy — which carries
langsmithApiKey (route.ts:19) — from being redirected at internal hosts
(copilotkit-runtime-route-convention).
It used to reject private targets purely by inspecting the URL's hostname string
(localhost, 127., 10., 169.254., …) and never resolved DNS, so a public hostname
(evil.example) whose A record pointed at 169.254.169.254 or an internal 10.x address
passed the check and the server then forwarded the LangSmith key to that address.
The Python resource downloader guarded the same SSRF class correctly — _is_safe_url
resolves via socket.getaddrinfo (download.py:41) and rejects if any resolved IP is
private/loopback/link-local. The asymmetry was the finding: the proxy's guard was weaker than
the backend's for the identical threat, on an opt-in path (?lgcDeploymentUrl=), hence P2.
Resolution (2026-07-26)
The proxy guard now matches the Python pattern. isSafeDeploymentUrl (route.ts:59-84) is
async and:
POST awaits it and 400s on rejection (route.ts:93-101). Verified against the current
source this pass. The guard is now stricter than the original finding asked for (the IPv6
and multicast cases were not in the proposed fix); don't "simplify" it back to a hostname
string check — that is the exact regression this row records.