Previously assertSafeProxyTarget resolved the target hostname and validated
the IPs, but safeProxyFetch then passed the raw URL to node-fetch, which
performed its own DNS lookup. In the window between the two resolutions an
attacker who controls the domain's TTL could flip the record to
169.254.169.254 (cloud-metadata), causing fetch() to connect to the instance-
metadata service even though the block-list check passed.
Fix: assertSafeProxyTarget now returns the validated IP addresses. On each
hop of safeProxyFetch we call createPinnedAgent() to build an http/https.Agent
whose lookup hook unconditionally returns the pre-validated IP. node-fetch
uses that hook instead of the OS resolver, closing the TOCTOU window entirely.
Refactoring: isBlockedProxyAddress, assertSafeProxyTarget, and the new
createPinnedAgent are extracted to server/src/proxy-security.ts so they can
be unit-tested in isolation. A vitest suite is added to the server package
(the first unit tests for this package) with 26 cases covering the block-list,
DNS validation, IP-pinning, and the TOCTOU guarantee itself.