Proxy Security¶
When your application is behind a proxy, load balancer, or CDN, properly handling the X-Forwarded-For
header is critical for security. FastAPI Guard implements a secure approach to prevent IP spoofing attacks.
The Problem¶
The X-Forwarded-For
header is sent by proxies to identify the original client IP, but since it can be manipulated by clients, it poses a security risk if trusted blindly.
Common security issues include: - IP spoofing to bypass IP-based access controls - False attribution in security logs - Bypassing rate limiting and IP bans
Secure Configuration¶
FastAPI Guard implements a secure-by-default approach where X-Forwarded-For headers are only trusted from explicitly configured trusted proxies:
config = SecurityConfig(
trusted_proxies=["10.0.0.1", "192.168.1.0/24"], # List of trusted proxy IPs/ranges
trusted_proxy_depth=1, # Number of proxies in the chain (default: 1)
trust_x_forwarded_proto=True, # Whether to trust X-Forwarded-Proto for HTTPS detection
)
How It Works¶
- When a request arrives, FastAPI Guard checks if it's from a trusted proxy
- If not from a trusted proxy, the direct connecting IP is always used
- If from a trusted proxy, the X-Forwarded-For header is parsed to extract the original client IP
- The extracted IP is then used for all security checks
Configuration Options¶
trusted_proxies¶
List of IP addresses or CIDR ranges that are allowed to set X-Forwarded-For headers:
config = SecurityConfig(
trusted_proxies=[
"10.0.0.1", # Single IP
"192.168.1.0/24", # CIDR range
"172.16.0.0/16" # Another CIDR range
]
)
If empty (default), X-Forwarded-For headers will not be trusted at all.
trusted_proxy_depth¶
Controls how the client IP is extracted from the X-Forwarded-For header:
config = SecurityConfig(
trusted_proxies=["10.0.0.1"],
trusted_proxy_depth=2 # Assumes two proxies in the chain
)
The X-Forwarded-For format is: client, proxy1, proxy2, ...
(leftmost is the original client)
- With depth=1 (default): Assumes one proxy in chain, uses leftmost IP as client
- With depth=2: Assumes two proxies in chain, still uses leftmost IP
- Higher values handle more complex proxy chains
trust_x_forwarded_proto¶
Whether to trust the X-Forwarded-Proto header for HTTPS detection:
config = SecurityConfig(
trusted_proxies=["10.0.0.1"],
trust_x_forwarded_proto=True # Trust X-Forwarded-Proto from trusted proxies
)
This only applies when the request comes from a trusted proxy.
Real-World Examples¶
Single Reverse Proxy¶
config = SecurityConfig(
trusted_proxies=["10.0.0.1"], # Your Nginx/HAProxy IP
trusted_proxy_depth=1, # One proxy
trust_x_forwarded_proto=True # Trust HTTPS status from proxy
)
Load Balancer + Proxy¶
config = SecurityConfig(
trusted_proxies=[
"10.0.0.1", # Load balancer IP
"192.168.1.0/24" # Internal proxy subnet
],
trusted_proxy_depth=2, # Two proxies in chain
trust_x_forwarded_proto=True
)
Cloud Provider Load Balancer¶
config = SecurityConfig(
trusted_proxies=[
"10.0.0.0/8" # Cloud provider's internal IP range
],
trusted_proxy_depth=1,
trust_x_forwarded_proto=True
)
Best Practices¶
- Be specific: Only include the exact IPs or ranges of your known proxies
- Use correct depth: Configure based on your actual proxy chain
- Regular audits: Periodically review your trusted proxy list
- Test configuration: Verify correct IP extraction in your environment