Hacker News new | ask | show | jobs
by francislavoie 323 days ago
A very in-depth article on the topic: https://adam-p.ca/blog/2022/03/x-forwarded-for/

I implemented those recommendations in Caddy to enable a "trusted proxies" system which informs the proxy, logging, request matching etc to safely use the client IP taken from proxy headers.

2 comments

The article you cited was very informative.

For example it reminds that standards & intermediaries you trust might still allow multiple unconcatenated XFF headers though and the XFF unpeel by right to left heuristic fails if you only look at the e.g. the first such header.

This reminded me that there always seems to be a past or future pitfall case lurking, such as using old code/library honoring a X-HTTP-Method-Override header (e.g. historically used to ~convert POST to PUT bypassing client CORS restrictions).

Many holes I've noticed over the years seem to spring from legacy preservation of well intended endruns of restrictions, for example I can presently in Safari exploit a bug to get a crypto digest calculated for me within an insecure context ... I find this quite usefully locally (e.g. lan http: , data: , ~bookmarklets that I control) but nonetheless I reported the bug and am trying not to rely on it.

This was the only article that opened my eyes; it's a lot better than the Wikipedia article on the topic. It covers the XFF header, also related headers, clearly from both defense and offense perspectives.

Two things it failed to advise for defense are:

(1) I can simply just reject requests that provide multiple keys of this header. In Go, I will use `http.Header.Values(headerName)` to check the count. There is no good reason for having multiple keys of it. Any misconfiguration in setting them is the client's problem.

(2) I can and I must reject large requests that have too many header bytes. In Go, when initializing `http.Server`, I can give it the `MaxHeaderBytes` argument. Sending megabytes of headers stops here.

If I understood correctly, when wanting the rightmost-ish XFF value, I can use the rightmost value that is not in a list of trusted subnets, assuming there is at least one remaining value left of it.