简体   繁体   中英

Django: redirect http to https safely for Heroku app

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.

According to Heroku :

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 to True .

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 the SecurityMiddleware :

 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.

I'm late to this party, but I think the key here is to simply understand what you are doing. I hope I understand what I am doing, but honestly am not 100% sure. I think HTTP_X_FORWARDED_PROTO is dangerous if you use it blindly because it makes Django think you are receiving an HTTPS request (even if HTTP_X_FORWARDED_PROTO is, in fact, spoofed).

But, if you are behind a properly functioning load balance/proxy (like AWS) then you can be confident that HTTP_X_FORWARDED_PROTO is being set correctly. In this case, HTTP_X_FORWARDED_PROTO serves to tell Django that it's fine, don't worry about it (because you are trusting the proxy to not allow through a spoofed header), and stop trying to continuously redirect to SSL.

Finally, HTTP_X_FORWARDED_PROTO behind a proxy/load balancer is necessary even if you aren't using SECURE_SSL_REDIRECT = True (eg if the redirection is happening in a properly configured web server before getting to Django), because it also affects the is_secure() function on the request, which would always be false if your proxy is swallowing the original request (eg it's common to go from HTTPS between the client and your proxy/load balancer to HTTP between your proxy/load balancer and a web server).

Source: https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER but I had to read it multiple time to put this all together in my head.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM