Skip to content

SSRF Protection

SSRF (Server-Side Request Forgery) is an attack where an attacker uses the server to make internal network requests. HTTPC enables SSRF protection by default.

Default Behavior

go
cfg := httpc.DefaultConfig()
// AllowPrivateIPs = false -> blocks all private IPs by default

Blocked IP ranges by default:

RangeCIDRDescription
IPv4 loopback127.0.0.0/8localhost
Class A private10.0.0.0/8Internal network
Class B private172.16.0.0/12Internal network
Class C private192.168.0.0/16Internal network
Link-local169.254.0.0/16Auto-configuration
CGNAT100.64.0.0/10Carrier-grade NAT (includes Alibaba Cloud metadata 100.100.100.200)
Class E reserved240.0.0.0/4Reserved addresses
IPv6 loopback::1/128localhost
IPv6 localfc00::/7Unique local addresses
IPv6 link-localfe80::/10Link-local

The table above lists the main ranges. The full block list also includes 0.0.0.0/8, TEST-NET (192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, etc.), the IPv6 documentation prefix 2001:db8::/32, and NAT64 64:ff9b::/96. See the source isPrivateOrReservedIP for details.

CIDR Exemptions

In microservice environments, you may need to access internal services:

go
cfg := httpc.DefaultConfig()
cfg.Security.SSRFExemptCIDRs = []string{
    "10.0.0.0/8",       // VPC internal
    "100.64.0.0/10",    // Tailscale VPN
    "172.20.0.0/16",    // Kubernetes Service CIDR
}

WARNING

CIDR exemptions should be as precise as possible. Avoid using overly broad ranges (e.g. 0.0.0.0/0) as this effectively disables SSRF protection.

Per-Request Private-IP Exemption

If you only need to allow private IPs for individual requests (for example, calling a localhost health-check endpoint), there is no need to enable AllowPrivateIPs globally. Use the WithAllowPrivateIPs request option to allow it for that single request only:

go
// Default client blocks private IPs; this call allows it per request
result, err := httpc.Get("http://localhost:8080/health",
    httpc.WithAllowPrivateIPs(true),
)

WARNING

Enable this option only for trusted URLs that do not come from user input. SSRF protection exists to stop attackers from tricking your process into reaching internal-network endpoints; disabling it per request reintroduces that risk for that call. If an entire client needs to reach internal services, set Security.AllowPrivateIPs = true on Config.

DNS Rebinding Prevention

HTTPC uses a "resolve-validate-dial" pattern to prevent DNS rebinding attacks:

  1. Resolve domain to IP addresses
  2. Validate all resolved IPs against private address lists
  3. Dial directly to the validated IP (instead of re-resolving the domain)
go
// Attack scenario:
// 1. Attacker controls DNS for evil.com
// 2. First resolution returns a public IP (passes validation)
// 3. Actual connection resolves to 127.0.0.1 (bypasses validation)
//
// HTTPC defense: after validation, dials directly using the validated IP, never re-resolves

Redirect SSRF Checking

Redirect targets also undergo SSRF validation:

go
// Suppose a request to public-api.com returns 302 redirect to http://169.254.169.254/
// HTTPC validates the redirect target's IP, blocking access to metadata services

Redirect Domain Whitelist

go
cfg := httpc.DefaultConfig()
cfg.Security.RedirectWhitelist = []string{
    "api.example.com",
    "auth.example.com",
    "*.cdn.example.com",  // Wildcard support
}

// Redirects to non-whitelisted domains are blocked

Cloud Environment Metadata Protection

Metadata service addresses for major cloud platforms:

PlatformAddressDescription
AWS169.254.169.254Instance metadata
GCPmetadata.google.internalMetadata service
Azure169.254.169.254Instance metadata
Alibaba Cloud100.100.100.200Metadata service

HTTPC blocks AWS/Azure metadata access by default (169.254.169.254 is in the 169.254.0.0/16 block list). GCP metadata (metadata.google.internal) is blocked through DNS resolution validation.

WARNING

Alibaba Cloud metadata (100.100.100.200) is in the CGNAT range (100.64.0.0/10), which HTTPC blocks by default, so Alibaba Cloud metadata access is blocked by default. If you need to reach this range for VPNs like Tailscale/WireGuard or internal routing, you must explicitly exempt it via SSRFExemptCIDRs: []string{"100.64.0.0/10"} -- once exempted, Alibaba Cloud metadata in that range also becomes reachable, so evaluate the risk accordingly.

Completely Disabling SSRF Protection

Only use in testing environments:

go
// TestingConfig disables SSRF protection
client, _ := httpc.New(httpc.TestingConfig())

// Or manual configuration
cfg := httpc.DefaultConfig()
cfg.Security.AllowPrivateIPs = true

DANGER

Never set AllowPrivateIPs = true in production.

Best Practices

  1. Use SecureConfig() as a security baseline
  2. Only exempt necessary CIDR ranges
  3. Configure RedirectWhitelist to limit redirect destinations
  4. Regularly audit SSRFExemptCIDRs configuration
  5. Use audit middleware to record all requests

Next Steps