The vulnerability is a classic Server-Side Request Forgery (SSRF) in the webfinger.js library. The root cause lies in insufficient validation of user-provided addresses within the lookup function. The function would extract the host from an address string (e.g., user@host) by simply taking the substring after the '@' symbol. This allowed an attacker to include a path and query parameters in the host portion (e.g., user@internal-server/admin/delete?user=victim), causing the library to make a request to an arbitrary internal endpoint.
The patch addresses this in multiple layers:
- Host Sanitization: A new
validateHost function is introduced to strip any path components (/, ?, #) from the extracted host, ensuring only a valid hostname or IP address is used.
- Private Address Blocking: A new
isPrivateAddress function checks the sanitized host against a comprehensive blocklist of private, local, and reserved IP ranges (both IPv4 and IPv6). This is the primary defense against SSRF.
- DNS-based SSRF Protection: For Node.js environments, a
validateDNSResolution function was added. It resolves hostnames to their IP addresses and checks if any of them are in the private address blocklist. This prevents attacks where a public domain resolves to a private IP (e.g., localtest.me resolving to 127.0.0.1).
- Redirect Validation: The
fetchJRD function was modified to handle redirects manually. It now validates the Location header of any redirect response to ensure it does not point to a private address, closing another potential SSRF vector.
The primary vulnerable function is WebFinger.lookup, as it's the entry point that consumes the malicious input. The WebFinger.fetchJRD function was also vulnerable due to its handling of redirects. The new functions (validateHost, isPrivateAddress, validateDNSResolution) represent the security controls that were missing.