IP lookup essentials
X-Forwarded-For Header: How to Get the Real Client IP Behind a Proxy
X-Forwarded-For carries the client address through proxies and CDNs, and anyone can forge it. How to read it safely from a trusted hop and get the real client IP.
- Author
- Mojahid Ul Haque
- Updated
- Reading time
- 3 min read
Header format and order
The `X-Forwarded-For` header is a comma-separated list of IPs added by proxies, often shaped like `client, proxy1, proxy2`. Many apps use the leftmost value as the original client IP, but that is safe only when the header chain is controlled by trusted infrastructure.
If any public client can send requests directly to your app, it can also send a fake `X-Forwarded-For` header. Your server must know which proxy added or sanitized the header before using it for rate limits, logging, or security decisions.
Trusted proxy pattern
A safer pattern is to maintain a trusted proxy list and walk the forwarded chain from right to left until you reach the first untrusted address. In TypeScript, that means parsing the header into IP strings, validating each item, and comparing proxy hops against your known load balancer or CDN ranges.
Cloudflare users should prefer `CF-Connecting-IP` when requests are guaranteed to come through Cloudflare. Vercel and many load balancers expose `x-real-ip` or normalized forwarded headers, but you should still confirm the deployment behavior.
Use the result responsibly
Once extracted, normalize the IP and store the original header only if you have a clear debugging or security need. Be careful with private, loopback, malformed, or reserved addresses because they should not be treated as public user locations.
For high-risk decisions, combine the extracted client IP with account history, request velocity, authentication state, and lookup results. Crafzo is useful for checking whether the chosen IP belongs to the expected country, ISP, or proxy type.
Validate the value before you look it up or store it. Accept both address families: a growing share of real clients, especially on mobile carriers, arrive over IPv6, and a check that only understands dotted-decimal IPv4 will reject or mishandle them. Normalize the address (IPv6 has several equivalent spellings) and treat empty, malformed, and private-only inputs as errors when a public location is what you need.
Frequently asked questions
Keep reading
Related guides
- ISP, ASN and network ownership5 min read
Why a Website Shows Cloudflare IP Addresses Instead of the Origin Server
A site behind Cloudflare or another CDN resolves to the CDN's addresses, not its own server. What that hides, what it does not, and how to read the lookup.
Updated
- For developers2 min read
How to Get the User IP Address in Next.js App Router
A developer guide to reading the real client IP in Next.js 14 App Router using headers(), middleware, and edge runtime considerations.
Updated
- IP lookup essentials8 min read
Residential Proxy Detection for Login Risk: How to Spot and Block Suspicious IPs
Residential proxies make attack traffic look like home users. The signals that still give them away, and how to use them in login risk decisions without false positives.
Updated
- IP location and accuracy4 min read
How to Track Public IP Geolocation Safely and Clearly
What public IP geolocation can and cannot show, how to read the result responsibly, and where it helps in security investigations and troubleshooting.
Updated