I am trying to redirect my Django + Heroku app from http
to https
, but I am surprised that I did not find any safe and straightforward way.
Issue
You have configured an SSL endpoint and now you want your application to use https for all requests.
Resolution
Redirects need to be performed at the application level as the Heroku router does not provide this functionality. You should code the redirect logic into your application.
Under the hood, Heroku router (over)writes the X-Forwarded-Proto and the X-Forwarded-Port request headers. The app checks X-Forwarded-Proto and respond with a redirect response when it is not https but http.
...
Django
Set
SECURE_SSL_REDIRECT
toTrue
.
So it must be done at Django. This is the most complete answer I found, and this one is also similar.
Django 1.8 will have core support for non-HTTPS redirect (integrated from django-secure):
SECURE_SSL_REDIRECT = True SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
In order for
SECURE_SSL_REDIRECT
to be handled you have to use theSecurityMiddleware
:MIDDLEWARE = [ ... 'django.middleware.security.SecurityMiddleware', ]
Note that both use
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
It seems that without this setting, it is not working on Heroku. And now comes the interesting/scary part. As explained in the docs:
SECURE_SSL_REDIRECT
...
If turning this to True causes infinite redirects, it probably means your site is running behind a proxy and can’t tell which requests are secure and which are not. Your proxy likely sets a header to indicate secure requests; you can correct the problem by finding out what that header is and configuring the
SECURE_PROXY_SSL_HEADER
setting accordingly.
Then, checking about SECURE_PROXY_SSL_HEADER
:
Warning
You will probably open security holes in your site if you set this without knowing what you’re doing. And if you fail to set it when you should. Seriously.
Which makes me want to find a safer solution... In this other question it says it should be fine, but I don't find it convincing enough to ignore such a warning.
Has Django really not any other solution that is safe to implement?
I am using version 1.11
Update:
I found the django-sslify package, but it also requires setting SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
, so I guess it doesn't make a difference in terms of potential security holes. Please, correct me if this assumption is wrong.