Allows proxies which serve mixed HTTP / HTTPS requests to control signal
which are served as HTTPS.
Override 'wdgi.url_scheme' via a request header, 'X_WSGI_URL_SCHEME'.
Removes one more reason to mention / explain Paste. The only question I have is whether waitress should expect the same 'X_Forwarded_Scheme' header as Paste; I chose not, but it would be easy to switch back.
Any reason to avoid prior-art? PasteDeploy's prefix middleware uses X-Forwarded-Proto which lines up pretty well with the commonly used X-Forwarded-For.
Ah and as you mentioned the prefix middleware supports both X-Forwarded-Proto and X-Forwarded-Scheme, both of which are (of course) undocumented.
To be clear the prefix middleware is in PasteDeploy, so mentioning it is not so bad. It's py3k compatible.
Enforce that 'X_WSGI_URL_SCHEME' must be one of 'http' or 'https'.
Switch to using the quasi-standard 'X_FOWRARDED_PROTO' header.
There's a minor typo here: s/ALlows/Allows/
I was thinking: might it be worthwhile ensuring that X-Forwarded-Proto can't be used to override the value explicitly set in waitress.adjustments.Adjustments.url_scheme when waitress is spun up?
@kgaughan: Zope's configuration exposes the notion of a "trusted proxy": if the upstream IP matched, then the headers passed by the proxy would be used unconditionally. Otherwise, the configured defaults would be used. Maybe we need to do the same?
That definitely seems worthwhile.
@tseaver whats holding up the merge of this?
I think it'd be good to support X-Forwarded-For and X-Forwarded-Proto, thpose are the standard headers that things like nginx and gunicorn use. X-Forwarded-For would be the client IP and -Proto would be http/https.
Merge from master.
This should be opt-in, and should also include the X-Forwarded-For support that @sontek mentioned. It'd be unwise to publish this as-is since it's a large vulnerability for any waitress server that is not behind a properly-configured reverse proxy to trust a random HTTP header.
@mmerickel @sontek : 'X-Forwarded-For' isn't relevant to this PR, which is about allowing mixed-mode proxies to signal to the application which scheme was used in the original request, so that they can generate absolute URLs using the same scheme.
But yes, I haven't merged this because of the concern @mmerickel mentions about folks running w/o proxies.
I think the thought process is that both headers are very common in a reverse proxy configuration and may be opted-in by the same option, but of course maybe not.
allow_forwarded_scheme = yes
allow_forwarded_ip = yes
Normalize long kwargs (one per line).
Add 'trusted_proxy' adjustment.
Only allow trustted proxies to overried request.urlscheme.
Document the 'trusted_proxy' bit.
I wish this was done via the allow* options I mentioned rather than this trusted_proxy ip address because now I have to mess with my deployment setup to make my app know about the proxy it's running behind, while previously my wsgi server was completely agnostic and just as secure.
Feel free to update it after I merge the work I've already done.
I'd happily update it, but I don't like to change code without talking about it first. By that, I can't quite tell if you think the concerns are not relevant or you just really wanted to merge this branch?
I would prefer the 'trusted_proxy' approach myself (less convenient, but also less susceptible to being abused if the appserver is accidentally exposed to public requests). I can live with it either way.
Huh, I just followed the latest documentation and hadn't realised that this isn't released yet. Surprised such a feature is so new. What's the best way to configure it before the new release, then?
With respect to the issue at hand, what if there are multiple proxies in a load balancing arrangement? It seems like hard-coding IPs into application configuration files is not the ideal place to do it and that this configuration should really live in the runtime environment architecture or in a firewall. If I was deploying an application I would make it listen on an interface where only trusted proxies could talk to it in the first place.
(I meant to give a shout-out to @mmerickel's allow_* suggestion)