@@ -402,8 +402,8 @@ else (if take 1 s == c then 1 else 0) + countChar c (drop 1 s)
402402
403403-- Block private/reserved/internal hostnames (SSRF defense). Skips obscure encoding
404404-- tricks (octal, hex, percent-encoding) but covers the high-value cases:
405−-- `localhost`, RFC1918 ranges (10/8, 192.168/16, 169.254/16), the IPv4 zero
406−-- net, bare IPv6 literals (any string with more than one `:` — covers loopback
405+-- `localhost`, RFC1918 ranges (10/8, 172.16/12, 192.168/16) plus link-local
406+-- 169.254/16, the IPv4 zero net, bare IPv6 literals (any string with more than one `:` — covers loopback
407407-- `::`/`::1`, link-local `fe80::/10`, ULA `fc00::/7`, globals like `2001:db8::1`),
408408-- bracketed IPv6 literals, and the `.local` / `.internal` / `.arpa` / `.onion`
409409-- suffixes. Called at federation egress (so we never `fetch` a peer pubkey from
@@ -419,7 +419,23 @@ isBadServerName = \sn -> sn == "" || sn == "localhost" || any (\c -> not contain
419419 "10.",
420420 "192.168.",
421421 "169.254.",
422− "0."
422+ "0.",
423+ "172.16.",
424+ "172.17.",
425+ "172.18.",
426+ "172.19.",
427+ "172.20.",
428+ "172.21.",
429+ "172.22.",
430+ "172.23.",
431+ "172.24.",
432+ "172.25.",
433+ "172.26.",
434+ "172.27.",
435+ "172.28.",
436+ "172.29.",
437+ "172.30.",
438+ "172.31."
423439] || any (\s -> hasSuffix s sn) [".localhost", ".local", ".internal", ".arpa", ".onion"]
424440
425441-- ============================================