fix: use ipaddress stdlib for IPv6 SSRF protection (#23453)
The validators.ipv6(ip, private=True) call always returns a falsy ValidationError because validators==0.35.0 does not support the private kwarg for IPv6. This means any hostname resolving to a private IPv6 address (::1, fd00::*, ::ffff:169.254.169.254) bypasses SSRF protection entirely, circumventing the fix for CVE-2025-65958. Replace both the IPv4 and IPv6 validators-based private checks with Python's stdlib ipaddress module using an allowlist approach (not addr.is_global). This blocks all non-globally-routable addresses — private, loopback, link-local, reserved, multicast, and unspecified — for both IPv4 and IPv6, including IPv4-mapped IPv6 addresses.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
import ipaddress
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
import ssl
|
import ssl
|
||||||
@@ -84,11 +85,9 @@ def validate_url(url: Union[str, Sequence[str]]):
|
|||||||
ipv4_addresses, ipv6_addresses = resolve_hostname(parsed_url.hostname)
|
ipv4_addresses, ipv6_addresses = resolve_hostname(parsed_url.hostname)
|
||||||
# Check if any of the resolved addresses are private
|
# Check if any of the resolved addresses are private
|
||||||
# This is technically still vulnerable to DNS rebinding attacks, as we don't control WebBaseLoader
|
# This is technically still vulnerable to DNS rebinding attacks, as we don't control WebBaseLoader
|
||||||
for ip in ipv4_addresses:
|
for ip in ipv4_addresses + ipv6_addresses:
|
||||||
if validators.ipv4(ip, private=True):
|
addr = ipaddress.ip_address(ip)
|
||||||
raise ValueError(ERROR_MESSAGES.INVALID_URL)
|
if not addr.is_global:
|
||||||
for ip in ipv6_addresses:
|
|
||||||
if validators.ipv6(ip, private=True):
|
|
||||||
raise ValueError(ERROR_MESSAGES.INVALID_URL)
|
raise ValueError(ERROR_MESSAGES.INVALID_URL)
|
||||||
return True
|
return True
|
||||||
elif isinstance(url, Sequence):
|
elif isinstance(url, Sequence):
|
||||||
|
|||||||
Reference in New Issue
Block a user