Django:为Heroku app安全地将http重定向到https

时间:2018-04-10 12:28:52

标签: django heroku https http-redirect django-settings

我正在尝试将我的Django + Heroku应用程序从http重定向到https,但我很惊讶我没有找到任何安全且直截了当的方式。

According to Heroku

  

问题

     

您已配置SSL端点,现在您需要应用程序   对所有请求使用https。

     

分辨率

     

重定向需要在应用程序级别执行,如Heroku   路由器不提供此功能。你应该编码   将逻辑重定向到您的应用程序中。

     

在引擎盖下,Heroku路由器(上)写了X-Forwarded-Proto和   X-Forwarded-Port请求标头。该应用程序检查X-Forwarded-Proto   并且当它不是https而是http。

时,使用重定向响应进行响应      

...

     

Django

     

SECURE_SSL_REDIRECT设为True

所以必须在Django完成。 This is the most complete answer我找到了,this one也是类似的。

  

Django 1.8将支持非HTTPS重定向(集成   从   django-secure):

SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
     

为了处理SECURE_SSL_REDIRECT,您必须使用。{   SecurityMiddleware

MIDDLEWARE = [
    ...
    'django.middleware.security.SecurityMiddleware',
]

请注意,两者都使用

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

似乎没有这个设置,它不适用于Heroku。现在是有趣/可怕的部分。正如docs

中所述
  

SECURE_SSL_REDIRECT

     

...

     

如果将此设置为True会导致无限重定向,则可能意味着   您的网站在代理后面运行,无法分辨哪些请求   安全,哪些不安全。您的代理可能会设置标题以指示   安全请求;你可以通过找出那个来纠正问题   标头是并配置SECURE_PROXY_SSL_HEADER设置   相应

然后,检查SECURE_PROXY_SSL_HEADER

  

警告

     

如果设置了此选项,您可能会在您的网站中打开安全漏洞   不知道你在做什么。如果你没有设置它   应该。严重。

这让我想找到一个更安全的解决方案...在this other question它说它应该没问题,但我发现它不足以令人信服地忽略这样一个警告。

Django真的没有其他任何安全的解决方案吗?

我使用的是版本1.11

更新

我找到了django-sslify package,但它还需要设置SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'),所以我猜它在潜在的安全漏洞方面没有什么区别。如果这个假设是错误的,请纠正我。

1 个答案:

答案 0 :(得分:0)

我参加这个聚会很晚,但是我认为这里的关键是简单地了解您在做什么。我希望我了解自己在做什么,但老实说不是100%确定。我认为如果盲目使用HTTP_X_FORWARDED_PROTO是危险的,因为它使Django认为您正在接收HTTPS请求(即使HTTP_X_FORWARDED_PROTO实际上是被欺骗的)。

但是,如果您处于负载平衡/代理正常运行的背后(例如AWS),则可以确信已正确设置了HTTP_X_FORWARDED_PROTO。在这种情况下,HTTP_X_FORWARDED_PROTO可以告诉Django很好,不必担心(因为您信任代理不允许通过欺骗的标头),并停止尝试不断重定向到SSL。

最后,即使您没有使用SECURE_SSL_REDIRECT = True(例如,如果重定向是在正确配置的Web服务器中进行的,然后再到达Django时),代理/负载平衡器后面的HTTP_X_FORWARDED_PROTO还是必要的,因为它也会影响请求上的is_secure()函数,如果您的代理吞下了原始请求,该函数将始终为false(例如,从客户端和代理/负载均衡器之间的HTTPS到代理/负载之间的HTTP,这很常见平衡器和网络服务器。

资料来源:https://docs.djangoproject.com/en/3.0/ref/settings/#std:setting-SECURE_PROXY_SSL_HEADER,但我不得不多次阅读才能将所有内容整理在一起。