Limits on Trusting Proxy Headers in CakePHP 4.x/5.x
0 reputation · 07 Mar 2021, 01:43 UTC
0 reputation · 07 Mar 2021, 01:43 UTC
Ensure that Request::getClientIp() and Request::is('ssl') return correct values when the application sits behind a reverse proxy such as an AWS ALB or Nginx.
trustProxy => false works.X-Forwarded-For, X-Forwarded-Proto, and X-Forwarded-Host headers that must be interpreted.trustProxy => true without restricting trustedProxies could allow header spoofing.trustedHeaders bitmask configuration; the documentation lists four constants but does not recommend a default for common cloud load balancers.Which combination of trustedHeaders bits should be enabled, and how should trustedProxies be scoped, to achieve accurate client IP and SSL detection while preventing security risks?
trustedHeaders include HEADER_X_FORWARDED_PROTO to correctly detect SSL behind an ALB?X-Forwarded-For values from a single ALB safe, or must trustedProxies be limited to the ALB’s IP ranges?trustedProxies configuration?35275 reputation · 07 Mar 2021, 02:44 UTC
To ensure Request::getClientIp() and Request::is('ssl') return accurate values behind a reverse proxy (like AWS ALB or Nginx), you must enable trustProxy, define the specific trustedHeaders bitmask, and restrict trustedProxies to the known IP ranges of your load balancer.
In your configuration (typically config/app.php or via the ServerRequestFactory), use the following logic:
'trustProxy' => true,
'trustedProxies' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16'], // Replace with your VPC/Subnet CIDRs
'trustedHeaders' => Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PROTO,
CakePHP ignores X-Forwarded-* headers by default. When trustProxy is enabled, the framework only honors these headers if the request originates from an IP address listed in trustedProxies. If the request comes from an untrusted IP, the headers are discarded to prevent spoofing.
HEADER_X_FORWARDED_PROTO. Because ALBs typically terminate TLS and forward requests to the app server via HTTP, is('ssl') will return false unless this header is trusted and parsed.HEADER_X_FORWARDED_FOR allows getClientIp() to extract the original client IP from the proxy chain.HEADER_X_FORWARDED_HOST if your application logic specifically relies on the proxied host header. Avoid this unless necessary to reduce the surface area for host-header injection attacks.Trusting all X-Forwarded-For values without restricting trustedProxies is a security risk; any client can send a fake header to impersonate an IP address.
Because AWS ALB node IPs are dynamic and change as the balancer scales, do not hardcode individual IP addresses. Instead, scope trustedProxies to your VPC or private subnet CIDR ranges. This ensures that only traffic coming from your internal network infrastructure is trusted.
CakePHP 5.x does not automatically detect cloud provider headers. Manual configuration of trustedProxies and trustedHeaders remains required to maintain security and accuracy.
$this->request->getClientIp(). It should match the external client IP, not the ALB's internal IP.$this->request->is('ssl'). It should return true when accessed via HTTPS through the ALB.X-Forwarded-For header. The app should ignore this header and return the actual direct connection IP.Diagnostic Question: Are there multiple proxy hops (e.g., Cloudflare $\rightarrow$ ALB $\rightarrow$ Nginx $\rightarrow$ App)? If so, trustedProxies must include the IP ranges of every hop that directly contacts your application.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.