- Author:
- spookylukey
- Posted:
- August 28, 2009
- Language:
- Python
- Version:
- 1.1
- Score:
- 8 (after 8 ratings)
On WebFaction, each host has it's own Apache instance, with WebFaction's main Apache instance forwarding requests. This is very useful but means that some of the original information is lost. This middleware should be installed at the top of your list to restore this lost info.
It includes the functionality that used to be in SetRemoteAddrFromForwardedFor before it was removed from Django.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | class WebFactionFixes(object):
"""
Middleware that applies some fixes for people using
the WebFaction hosting provider. In particular:
* sets 'REMOTE_ADDR' based on 'HTTP_X_FORWARDED_FOR', if the
latter is set.
* Monkey patches request.is_secure() to respect HTTP_X_FORWARDED_SSL.
***PLEASE NOTE*** that this is not secure, since a user or an
active network attacker could set X-Forwarded-SSL manually and the
main WebFaction Apache/nginx instance does not remove it, so it will
appear to be a secure request when it is not.
For some applications, this could be a critical security flaw. For
example, if users typical type in yourdomain.com into browsers, which
will be HTTP by default and your app is supposed to redirect this to
HTTPS, an active MITM attacher could add the X-Forwarded-Ssl header,
causing the connection to procede over HTTP, leaking all your
sensitive information.
In this scenario, this middleware will be useful in protecting against
passive network attackers, but not active network attackers.
WebFaction currently have no work-around for this flaw, AFAIK.
"""
def process_request(self, request):
# Fix REMOTE_ADDR
try:
real_ip = request.META['HTTP_X_FORWARDED_FOR']
except KeyError:
pass
else:
# HTTP_X_FORWARDED_FOR can be a comma-separated list of IPs. The
# client's IP will be the first one.
real_ip = real_ip.split(",")[0].strip()
request.META['REMOTE_ADDR'] = real_ip
# Fix HTTPS
if 'HTTP_X_FORWARDED_SSL' in request.META:
request.is_secure = lambda: request.META['HTTP_X_FORWARDED_SSL'] == 'on'
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 6 months ago
Comments
Spookylukey,
thanks for the patch. It works! I would think WF should post this as part of their installation/setup instruction for django. After all, https and django are not such a rare combination. Have you considered alerting the webfaction folks?
thanks again.
#
Cheers pingyip, I've done so now.
#
It's worth noting that WebFaction recommmends mod_wsgi for Django deployment, and our current mod_wsgi based installers set the HTTPS environment variable properly so the
HTTP_X_FORWARDED_SSL
bit isn't required.#
Please login first before commenting.