[Django] #19517: Add support for X-Forwarded-Port to HttpRequest.get_host when USE_X_FORWARDED_HOST is in use

27 views
Skip to first unread message

Django

unread,
Dec 24, 2012, 3:30:23 PM12/24/12
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------+-------------------------------------------------
Reporter: | Owner: nobody
david_k_hess@… | Status: new
Type: | Version: 1.4
Uncategorized | Keywords: httprequest, get_host, X-Forwarded-
Component: HTTP | Host, USE_X_FORWARDED_HOST
handling | Has patch: 0
Severity: Normal | UI/UX: 0
Triage Stage: |
Unreviewed |
Easy pickings: 0 |
-------------------------+-------------------------------------------------
The use case is an app served on ports 80, 443 (SSL) and 444 (SSL) served
by gunicorn behind nginx. I'm sending X-Forwarded-Host and X-Forwarded-
Port from nginx to gunicorn. Port 80 is open solely to redirect to 443 and
both are open to the public internet. 444 is firewalled and reserved for
the admin interface which is protected by this middleware component:

{{{
class ProtectAdminMiddleware(object):
def process_request(self, request):
if request.path.startswith("/admin") and
request.META["HTTP_X_FORWARDED_PORT"] != "444":
raise Http404
}}}

When turning on USE_X_FORWARDED_HOST, the code in HttpRequest.get_host
does not take port into account:

{{{
[...]
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST']
[...]
}}}

Because of this, at least two things in the admin interface on port 444
don't function correctly; the CSRF token breaks saying there is a problem
between referrer on 444 and token on 443 and you can't login. Also,
redirects from say "/admin" on port 444 redirect to "/admin/" on 443
instead of staying on 444. That's just what I was able to reach with
logins broken.

I monkey-patched HttpRequest.get_host to add support for X-Forwarded-Port
when USE_X_FORWARDED_HOST is specified and it appears to have corrected
these issues:

{{{
[...]
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
if 'HTTP_X_FORWARDED_PORT' in self.META:
server_port = str(self.META['HTTP_X_FORWARDED_PORT'])
if server_port != (self.is_secure() and '443' or '80'):
host = '%s:%s' % (host, server_port)
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST']
[...]
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/19517>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 27, 2012, 6:23:33 AM12/27/12
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution:
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------
Changes (by cyphase):

* needs_better_patch: => 0
* needs_tests: => 0
* easy: 0 => 1
* needs_docs: => 0
* type: Uncategorized => Bug
* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:1>

Django

unread,
Jan 15, 2013, 10:43:58 PM1/15/13
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution:
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 0 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------

Comment (by hirokiky):

I found pull-request for this ticket here
https://github.com/django/django/pull/619 written by mattrobenolt.

--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:2>

Django

unread,
Jan 15, 2013, 10:44:08 PM1/15/13
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution:
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0

Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------
Changes (by hirokiky):

* has_patch: 0 => 1


--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:3>

Django

unread,
Jan 15, 2013, 10:44:53 PM1/15/13
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: new
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution:
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------
Changes (by hirokiky):

* cc: hirokiky@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:4>

Django

unread,
Feb 23, 2013, 7:22:16 AM2/23/13
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution: wontfix

Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------
Changes (by jezdez):

* status: new => closed
* resolution: => wontfix


Comment:

I'm rejecting this after a discussion during the 2013 sprint:

- The use case of handing a SSL request with a load balancer is handled
already by the `SECURE_PROXY_SSL_HEADER` setting.

- `HTTP_X_FORWARDED_PORT` is not a standard header and this ticket hasn't
produced compelling evidence that Django is breaking any spec.

- Adding a new setting pair of `HTTP_X_FORWARDED_PORT` and
`USE_X_FORWARDED_PORT` just for this edge case is a no-go, too.

In other words, the issue is an edge case that can be solved by a custom
middleware in your application (e.g. by setting `HTTP_HOST`).

--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:5>

Django

unread,
Sep 9, 2014, 7:32:44 PM9/9/14
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: closed
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution: wontfix
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------

Comment (by mattlong):

To be fair, `X-Forwarded-Host` is also not in any spec or standard that I
can find. It's added automatically by Apache's mod_proxy, but that seems
to be the only place. Having special handling for one custom header
without the other seems incorrect as there is currently no way (besides
middleware to change `HTTP_HOST` as jezdez suggests) to accurately get the
original request's host/port combo as the OP describes.

It seems reasonable to me to expect that `HTTP_X_FORWARDED_PORT` would
also be respected by HttpRequest.get_host if `USE_X_FORWARDED_HOST` is
enabled. Currently, I will also be opting to monkey patch get_host rather
than add the (admittedly small) overhead of an additional middleware on
all requests.

--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:6>

Django

unread,
Sep 9, 2014, 7:50:12 PM9/9/14
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: closed
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution: wontfix
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------
Changes (by mattlong):

* cc: matt@… (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:7>

Django

unread,
Sep 10, 2014, 1:09:55 PM9/10/14
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: closed
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution: wontfix
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, | Needs documentation: 0
USE_X_FORWARDED_HOST | Patch needs improvement: 0
Has patch: 1 | UI/UX: 0
Needs tests: 0 |
Easy pickings: 1 |
-------------------------------------+-------------------------------------

Comment (by collinanderson):

There's a new `Forwarded:` header that standardizes `for`, `proto`,
`host`, and `by`, but not `port`. http://tools.ietf.org/html/rfc7239

If you want to discuss it further, please use the
https://groups.google.com/d/forum/django-developers mailing list, as this
is a closed ticket.

--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:8>

Django

unread,
Dec 28, 2014, 12:02:05 PM12/28/14
to django-...@googlegroups.com
#19517: Add support for X-Forwarded-Port to HttpRequest.get_host when
USE_X_FORWARDED_HOST is in use
-------------------------------------+-------------------------------------
Reporter: david_k_hess@… | Owner: nobody
Type: Bug | Status: closed
Component: HTTP handling | Version: 1.4
Severity: Normal | Resolution: wontfix
Keywords: httprequest, | Triage Stage: Accepted
get_host, X-Forwarded-Host, |
USE_X_FORWARDED_HOST |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by hgdeoro):

I have the same problem with bad redirects on the testing environment
(where the non-standar 8443 port is used). I found a workaround for Nginx.
Just add:

{{{
error_page 497 https://$host:8443$request_uri;
}}}

With that configuration, instead of the error message `The plain HTTP
request was sent to HTTPS port`, your browser receives a redirect to the
real URL. This is NOT a solution, this introduces an extra redirect, but
worked for me (and it's better than modifying the aplication, since this
is a problem I have in the testing environment only).

--
Ticket URL: <https://code.djangoproject.com/ticket/19517#comment:9>

Reply all
Reply to author
Forward
0 new messages