Specifies server-side request forgery controls using allowlisted schemes and hosts, resolve-then-recheck DNS, blocking of link-local and cloud metadata destinations, and a ban on using caller URLs as an open proxy.
Package status: reference context ready for human review. The contract and test scenarios are complete, but no claim is made that an adopting implementation has passed them.
Decision
Server-side fetchers that touch the network on behalf of a user operate on an allowlist of schemes and hosts. After DNS resolution, the implementation re-checks every resulting address against deny lists for loopback, RFC1918, link-local, unique-local IPv6, and cloud metadata endpoints. User-supplied URLs are never an open proxy. Redirects are disabled in this profile so a first hop cannot bounce into a blocked range. DNS rebinding is treated as a failed destination.
Scope
- Link previews, webhook callbacks the product initiates, and thumbnail or unfurl generators.
- Scheme, host, IP, metadata, DNS pin, timeout, and response size limits in the adoption profile.
- Error vocabulary
ssrf_destination_blocked.
Outside this block
- Browser-side mixed-content rules.
- Malware scanning of downloaded bytes; see the related upload-gate block.
- Egress controls for operator-initiated admin tools that use a different trust path.
Contract
- Connect is allowed only when scheme is in
allow_schemesand hostname is inallow_hosts. - After resolution, every address must fall outside
deny_ip_cidrsandmetadata_hosts; otherwise the fetch aborts. - If DNS answers change within
pin_ttl_secondsto a denied address, the in-flight fetch is aborted as rebinding. user_url_as_proxyis false: URLs from callers that miss the allowlist are not fetched.follow_maxis zero; a redirect status does not produce a second connect.- Timeouts and
max_response_bytesbound the fetch; exceeding them fails closed without retry to a new host.
Implementation guidance
- Strict URL parsing; reject credentials-in-URL and IPs that bypass the hostname allowlist.
- Resolve with an application-controlled resolver; canonicalize IPv4-mapped IPv6 before deny checks.
- Pair with network policy that still denies metadata and link-local.
Failure handling and safeguards
- DNS failure is a block. Empty
allow_hostsprevents fetcher start. - Oversized bodies are discarded. Connect only to the pinned address and re-verify it.
Verification and operations
- Tests: metadata IPs, CNAME to metadata, http scheme, redirect-to-link-local.
- Recheck allowlisted hosts against deny lists; do not widen to wildcard suffixes.
The executable-looking examples in this package are fixtures and acceptance contracts. Run
python tools/validate.py from the collection root to check package structure and metadata; then
implement and execute the scenarios in the target repository.
Adoption assumptions
- Names and numeric values in
example.yamlare an adoption profile, not universal defaults. - The adopting team must map actors, data classes, error vocabulary, and ownership to its system.