New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore: changed behavior for request.host when multiple X-Forwarded-Host are used #1832
Restore: changed behavior for request.host when multiple X-Forwarded-Host are used #1832
Conversation
I don't have a strong opinion either way, but is there an RFC which explains the best value to use? I assume the earlier forwarded for details are closer to the client while later ones are more likely to be proxies. |
Ah, we've also had this issue.
as a workaround. |
We strictly must use the last (and thus nearest-to-us proxy) details for X-Forwarded-For, because any nominally-further value cannot be trusted: any originating client can claim to be proxying on behalf of anyone they like (including things like private IPs, or localhost). That doesn't directly map here, but IMO does alone provide some basis for justifying parallel behaviour. (Especially viewed in light of a #1423-style far future.) On the particular matter of host, I think it also makes sense to go with the nearest proxy's provided value. That's the proxy that said "oh, a request for |
Would it make sense to add an interface so that users can ask for all forwarded hosts and then can select either the first or last as is useful to their own use case? |
My quick thought would be to push the "clean up something that's nominally a list of IP/host entries" behaviour into a public Rack::Util method, and then say that if someone has a more complex need they can read the header themselves [and we've supplied that cleanup help]. My theory there is that ... again, all of that applies less strongly to forwarded host in particular, but I guess I'm reluctant to add a list-of-hosts feature because of the precedent it would create for a matching list-of-client-IPs, and that feels like leaving a foot-gun on the table, where I'd rather just note that there is one kept in the safe. |
I think the value in standardising an interface here, apart from the ones discussed already, is that internally HTTP has got a defacto standard of |
The Request.forwarded_priority accessor sets the priority. Default to considering Forwarded first, since it is now the official standard. Also allow configuring whether X-Forwarded-Proto or X-Forwarded-Scheme has priority, using the Request.x_forwarded_proto_priority accessor. Allowing configurable priorities for these headers is necessary, because which headers should be checked depends on the environment the application runs in. Make Request#forwarded_authority use the last forwarded authority instead of the first forwarded authority, since earlier forwarded authorities can be forged by the client. Fixes rack#1809 Fixes rack#1829 Implements rack#1423 Implements rack#1832
Based on discussion here, it sounds like it would be a security issue to change this behaviour. Thus we will close it. Thanks for your ideas and contributions. |
Sorry, I may have mis-understood the advice here.
This means we should apply this PR. @matthewd do you mind confirming and approving this PR? |
I fixed this as part of #1834, can you please review that instead?: https://github.com/rack/rack/pull/1834/files#diff-7ce97931f18a63a4d028696a6f4ba81991644dbc2d70eaa664285264e9a5cd64L360 |
The Request.forwarded_priority accessor sets the priority. Default to considering Forwarded first, since it is now the official standard. Also allow configuring whether X-Forwarded-Proto or X-Forwarded-Scheme has priority, using the Request.x_forwarded_proto_priority accessor. Allowing configurable priorities for these headers is necessary, because which headers should be checked depends on the environment the application runs in. Make Request#forwarded_authority use the last forwarded authority instead of the first forwarded authority, since earlier forwarded authorities can be forged by the client. Fixes #1809 Fixes #1829 Implements #1423 Implements #1832
Implemented by #1834 |
As explained in #1829 commit 290523f changed the behavior of request.host when multiple X-Forwarded-Host are used. This PR restores the previous behavior.
I don't know which behavior is the correct one, but this is a breaking change. If we really want to change from
last
tofirst
we should issue the proper deprecation warning and include the change in the v3 release. I didn't update the changelog yet because I think it would be best to have this fix in 2.2.4 though I'd prefer to have your insight.Here is the before after:
Before:
After
Also it should be noted that rails is also using last https://github.com/rails/rails/blob/main/actionpack/lib/action_dispatch/http/url.rb#L216 so for consistency if one is changed the other should be changed too.
cc @ioquatix as you are the author of the initial commit and maybe cc @tenderlove for the rails note above.