Supporting the Forwarded header (RFC 7239)

Vasiliy Faronov vfaronov at
Sun Aug 6 18:11:03 UTC 2017

Hi nginx developers,

As you know, RFC 7239 defines a Forwarded header to replace the zoo of
X-Forwarded-* with a single extensible syntax.

There seems to be growing interest in deploying Forwarded. For
example, aiohttp, a popular Python library, recently started reading
Forwarded by default.

I'd like to see a $proxy_add_forwarded variable in nginx -- similar in
essence to $proxy_add_x_forwarded_for -- and I'd like to try and
contribute a patch.

Can you tell me if this sounds like a good idea to you, and if yes,
which of the following approaches you prefer? (I'm sorry for the wall
of text)

1. $proxy_add_forwarded blindly appends a "for=..." after a comma,
just like $proxy_add_x_forwarded_for does. (This cannot be emulated in
config because of ticket #1316; also, nginx's $remote_addr is not
quite in the format required by RFC 7239.)

The problem here: suppose an external user sends:

    Forwarded: for=injected;by="

If you just append to this, you get:

    Forwarded: for=injected;by=", for=real

This puts the burden on the receiving application to parse this
robustly and recover "for=real". They can't just split on comma
(because comma can occur inside a valid quoted-string), they need more
logic. It's doable, they just have to be aware of the problem and
actively mitigate it.

2. Parse any incoming Forwarded headers into an internal
representation, then re-serialize it with an added element.

This is obviously more expensive. But, if you think that supporting
Forwarded is a good idea, then eventually you want to support it in
ngx_http_realip_module and wherever else nginx looks at X-Forwarded-*.
Then you need to parse anyway.

3. Validate the syntax of any incoming Forwarded headers with a regex.
If they are valid, append to them. If they are invalid, replace them
with a single "for=unknown" (explicitly allowed by RFC 7239), and
append to that.

4. Do any of the above, but in a third-party module, where one could
experiment more freely.

I think requiring a third-party module to support Forwarded will just
lead to everybody sticking with X-Forwarded-*, or else trying to
emulate it in config with poor results. It's just not enough of a
feature on its own.

Then again, maybe RFC 7239 was a bad idea and everybody *should* just
stick to X-Forwarded-*.

Any thoughts on this would be appreciated. Thank you!


More information about the nginx-devel mailing list