Skip to main content
Kill -9 Club
Sign in

X-Forwarded-For

Web

A request header listing the addresses a request has passed through, appended to by each hop: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for takes whatever arrived and adds $remote_addr, the address nginx actually saw. That is the whole trust model, and the mistake lives there. The header is not evidence of who the visitor is: everything before the entry your own proxy wrote came from someone you do not control, and nothing stops a client sending X-Forwarded-For: 203.0.113.7 on its very first request. Only the last value, the one your proxy appended, can be believed. Rate limiting or a ban list keyed on the first value blocks nobody — the attacker changes the string per request, and your counters count fiction. In Express, app.set('trust proxy', 1) says exactly that: trust one hop, the one you own.

Also written: XFF, $proxy_add_x_forwarded_for