networking http_security ai_generated true

Security warning: X-Forwarded-For header contains untrusted client-supplied value

ID: networking/xff-header-spoofed

Also available as: JSON · Markdown
88%Fix Rate
90%Confidence
50Evidence
2023-06-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
any active

Root Cause

The application trusts the X-Forwarded-For header for client IP identification, but clients can inject arbitrary values in this header. This allows IP-based access control bypass, rate limit evasion, and log forgery. The application must only trust XFF values from known trusted proxies.

generic

Workarounds

  1. 92% success Configure trusted proxy addresses and parse XFF right-to-left, trusting only known proxies
    1. Define the list of trusted proxy IPs or CIDR ranges in the application config
    2. Parse X-Forwarded-For right-to-left, skipping IPs that match trusted proxies
    3. The first non-trusted IP from the right is the real client IP
    4. In nginx: set_real_ip_from 10.0.0.0/8; real_ip_header X-Forwarded-For; real_ip_recursive on;
    5. In Express.js: app.set('trust proxy', ['loopback', '10.0.0.0/8'])
    6. Test by sending a forged XFF header and verifying the application extracts the correct IP
  2. 88% success Use a custom header set by the edge proxy instead of X-Forwarded-For
    1. Configure the edge proxy to set a custom header (e.g., X-Real-Client-IP) with the direct client IP
    2. Strip any client-supplied X-Real-Client-IP at the edge: proxy_set_header X-Real-Client-IP $remote_addr;
    3. Configure the application to use X-Real-Client-IP instead of X-Forwarded-For
    4. This header is set only by the trusted edge proxy and cannot be spoofed by clients
    5. Ensure no downstream proxy overwrites this header

Dead Ends

Common approaches that don't work:

  1. Trust the entire X-Forwarded-For header value without validation 95% fail

    Any client can set X-Forwarded-For to an arbitrary IP address. Without validating which proxies in the chain are trusted, the application may use the attacker-controlled leftmost value as the real client IP.

  2. Strip X-Forwarded-For at the edge proxy but not configure the application to use the correct header 65% fail

    If the edge proxy strips the header but re-adds it with only the direct client IP, the application must be configured to read from this specific proxy's header. Misconfiguration means the application may still read a different header or the wrong position in the chain.

Error Chain

Leads to:
Preceded by:
Frequently confused with: