下面的 Python 示例用于说明校验思路,不应直接替代经过评审的生产网络组件。它做了协议限制、主机规范化、DNS 解析和 IP 范围判断,并关闭了自动重定向:
from urllib.parse import urlparse
import ipaddress
import socket
import requests
ALLOWED_SCHEMES = {"https"}
ALLOWED_HOSTS = {"static.example.com"}
def resolve_addresses(hostname, port):
results = set()
for item in socket.getaddrinfo(hostname, port, type=socket.SOCK_STREAM):
results.add(item[4][0])
return results
def is_public_address(value):
address = ipaddress.ip_address(value)
return not (
address.is_private or
address.is_loopback or
address.is_link_local or
address.is_reserved or
address.is_multicast or
address.is_unspecified
)
def validate_target(raw_url):
parsed = urlparse(raw_url)
if parsed.scheme not in ALLOWED_SCHEMES:
raise ValueError("unsupported scheme")
if not parsed.hostname or parsed.username or parsed.password:
raise ValueError("invalid host form")
hostname = parsed.hostname.rstrip(".").lower()
if hostname not in ALLOWED_HOSTS:
raise ValueError("host is not allowed")
port = parsed.port or 443
addresses = resolve_addresses(hostname, port)
if not addresses or not all(is_public_address(x) for x in addresses):
raise ValueError("resolved address is not allowed")
return parsed.geturl()
def fetch(raw_url):
target = validate_target(raw_url)
response = requests.get(
target,
allow_redirects=False,
timeout=(3, 5),
stream=True,
)
response.raise_for_status()
return response.text[:1024 * 1024]
这个示例仍有工程边界:域名解析结果与底层连接之间的绑定方式取决于 HTTP 客户端实现;连接池、代理、IPv4/IPv6 优先级和容器 DNS 都可能改变实际行为。因此,真正的防护不能只依赖应用代码,还应在网络层建立出站访问控制,例如仅允许访问必要的 DNS、代理和目标网段。
推荐意见