X-Forwarded-For: Identify a Trusted Client IP
Choose the right IP to enrich behind proxies by defining trusted relays, then test forged headers, malformed values and direct origin access.

A reputation lookup is of little use if it targets your own reverse proxy’s address or an IP chosen by the client. Before using X-Forwarded-For in a WAF, rate limiter or SIEM, establish who supplied each part of the chain.
The objective is to obtain an address supported by the observed network path. That does not turn the address into a personal identity: a VPN, gateway or shared network can still place several users behind it.
Start with the peer that actually connected
The server receives a connection from an immediate peer. When that peer is your reverse proxy, the server directly knows its address; it does not directly know the browser’s address. The header forwarded by the proxy supplies an additional assertion whose value depends on your architecture.
Inventory every path to the application: CDN, load balancer, ingress, internal proxy, monitoring access and any direct access to the origin. For each path, document the expected peer, treatment of incoming headers and how the relay adds the address it observes.
A standardized header does not settle this question by itself. RFC 7239, section 8.1, explains that intermediaries or the client can modify Forwarded information. Choosing between Forwarded and X-Forwarded-For therefore does not remove the need to define trust.
Define where provenance becomes trustworthy
Choose the entry component responsible for cleaning or reconstructing provenance information. That choice must match its actual configuration. A proxy that blindly preserves a client header does not establish its origin merely by forwarding it.
Subsequent relays must accept this information only from their authorized predecessors. Define trust using controlled addresses or ranges and a protected network path. Trusting every private network can be too broad if other workloads on those networks can reach the application.
In particular, verify that the origin cannot be reached through a path that bypasses the intended entry point. Otherwise, a client can directly supply headers that the application normally attributes to the proxy. This is an architectural problem even when the address parser works correctly.
Read the chain from the known end
In a topology where trusted proxies correctly append the peer they observe, selection starts with the immediate peer and then works through header values from right to left. It stops at the first address that is not a trusted relay. Values farther to the left do not become trustworthy simply because of their position.
The Nginx realip module documentation describes this selection when real_ip_recursive is enabled. After checking the original address against the configured trusted relays, the module uses the last non-trusted address in the chain. The exact configuration must still match the path you verified.
Consider this fictional example, which uses only documentation addresses:
immediate peer: 192.0.2.10 (trusted internal proxy)
X-Forwarded-For: 203.0.113.66, 198.51.100.24, 192.0.2.20
↑ trusted entry proxy
If 192.0.2.20 appended 198.51.100.24 as the peer it actually observed, the latter is the useful candidate. 203.0.113.66, farther to the left, could have been supplied by the client. Always taking the first value would attribute the request using an unverified assertion.
Use a parser suited to the received formats
Do not split every address on : because IPv6 addresses contain colons. Also check repeated headers, whitespace, possible ports and invalid values against the conventions your proxies actually emit. Forwarded has its own syntax and cannot be handled as a simple XFF list.
Define one selection method shared by logging, rate limiting and enrichment. If three components apply three different rules, the same event can be associated with different IPs. An alert then becomes difficult to reproduce even when all the logs are available.
Specify an explicit outcome for unusable values. A failing parser must not invent an address, silently reuse one from an earlier request or select another untrusted header. The log should make it possible to understand why attribution failed.
Test the trust policy as well as the normal path
In an authorized environment, send test requests through every intended path. Use fictional IPs in the headers you control so you can distinguish client input from values added by your infrastructure.
| Test | Result to verify |
|---|---|
| Client without XFF | The address observed at the entry point is selected correctly |
| Client supplies a false first IP | The forged value is not used as a trusted identity |
| Repeated or malformed headers | Handling is defined and logged |
| Origin reached directly | Access is denied or supplied headers are not trusted |
| Shorter alternative path | Selection remains correct with a different number of relays |
The last case exposes configurations that trust a fixed number of hops despite having several possible paths. Repeat these tests after changing a CDN, ingress or route. The trust policy must follow the network as it changes.
Enrich the selected address with its context
Log the network peer, selected address, selection method and a request identifier. Retaining the raw header must follow your access and retention policies because it can contain untrusted or unnecessary data. Keep these fields separate in the SIEM.
You can then apply IP reputation and IP type criteria and consult an IP report when the investigation warrants it. Do not label your CDN’s address as the attacker’s address simply because it appears in a connection log.
Finally, correlate the IP with application events: account, session, requested resource and outcome. The SOC guide to IOC enrichment supplies external context. Evidence of the address’s provenance still has to come from your own proxy chain.
Frequently asked questions
- Can I use the first IP in X-Forwarded-For?
- Only after establishing the proxy chain and how its components handle incoming headers. A value supplied by the client can appear on the left. Selection must start with the network peer and explicitly trusted relays.
- Is Forwarded safer than X-Forwarded-For?
- Its syntax is standardized, but it provides no cryptographic proof of origin. You still need to control authorized relays and the path through which the application is reached.
- Which IP should be sent to a reputation service?
- The address selected using a verified trust policy. Retain the network peer, raw header value and selection method so you can explain the attribution.
Related articles
- IP Blacklisted? Check for a False Positive Before Blocking
Check DNSBL scope, shared IPs, stale evidence and lookup errors to find why an IP was blacklisted and choose a proportionate response.
- STIX/TAXII Threat Feeds: Operational Guide for OpenCTI, MISP, and SIEM Pipelines
How to wire STIX 2.1 and TAXII 2.1 collections into OpenCTI, MISP, or your SIEM — what to poll, how to handle confidence and aging indicators, and where enrichment APIs fit alongside feed ingestion.
Proxy, VPN, Tor, and Datacenter IPs: A Decision Matrix for WAF, Fraud, and SIEM Rules (Without Breaking Real Users)Not every "datacenter" IP is malicious, and not every Tor exit is a fraudster. This matrix-style guide helps you combine IP type signals with reputation and product context for safer, explainable security decisions.
Protect Your Infrastructure
Check any IP or domain against our threat intelligence database with indexed records.
Try the IP / Domain Checker