我正在尝试将我的Django + Heroku应用程序从http
重定向到https
,但我很惊讶我没有找到任何安全且直截了当的方式。
问题
您已配置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')
,所以我猜它在潜在的安全漏洞方面没有什么区别。如果这个假设是错误的,请纠正我。
答案 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,但我不得不多次阅读才能将所有内容整理在一起。