CSRF 验证失败 - 当主机安全时,Referer 不安全
Posted
技术标签:
【中文标题】CSRF 验证失败 - 当主机安全时,Referer 不安全【英文标题】:CSRF verification Failed - Referer is insecure while host is secure 【发布时间】:2016-04-12 04:48:43 【问题描述】:我将 Django 从 1.8 升级到 1.9。之后,我在 Django 管理员登录后在本地主机上收到此错误:
Referer checking failed - Referer is insecure while host is secure
.
在生产中一切正常。 下面是我的 settings.py 文件的 sn-p:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
【问题讨论】:
我猜你在开发中使用http
。所以应用程序必须配置为在您的local.py
(或类似)中使用http
。
【参考方案1】:
当我从 ssl setup 切换到 no ssl 并忘记从 nginx 配置中的上游配置中删除最后一行时出现此错误:
location /
proxy_pass http://127.0.0.1:8085;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host; #:8080;
#proxy_set_header X-FORWARDED-PROTO https;
【讨论】:
【参考方案2】:settings.py
文件中的这些行在生产环境中没有问题,因为您使用的是附加到您的域的 SSL 证书。但是,在本地,您可能正在使用 http://localhost:8000
或类似的东西。如果您尝试通过https://localhost:YOUR_PORT_NUMBER
连接,您很可能会收到类似ERR_SSL_PROTOCOL_ERROR
的错误。
问题在django/django/middleware/csrf.py 的第 167-168 行。当您在生产中使用 https
时,request.is_secure()
将返回 True
...这要求 HTTP_REFERER
也为真,否则您将收到您引用的错误。
一个解决方案是adjust your settings.py
file depending on whether you're in your local or production environment。这样,您可以将这三行添加到 settings_production.py
文件中,该文件导入 localhost 和生产服务器共有的其他设置。您的 localhost 将使用一组不包括这些行的不同设置。
【讨论】:
是的。我明白你的意思。在我在问题中指定的那些行之前,有这个条件if not ENVIRONMENT == 'localhost'
。这意味着我在问题中指定的那些行仅在生产中执行。那么我必须在设置中添加什么来防止出现此错误?
只是检查一下,如果您完全删除这三行,该站点是否可以在localhost
上运行?那会发生什么错误?问题是您的HTTP_REFERER
元标记未在localhost
上使用https
。见django/django/middleware/csrf.py
的第167-168行
当我注释掉这三行时,我仍然得到同样的错误。
你必须显示你的 settings.py 文件的其余部分(确保注释掉或删除任何键)。基本解决方案是删除本地 settings.py
中引用 https
的任何内容...所以我只是在寻找强制 https
在本地使用的设置。
我能够解决这个问题。我正在使用的另一个库django-cors-headers
导致了这个问题。我不得不通过添加CORS_REPLACE_HTTPS_REFERER = True
来避免这种情况。问题就解决了。 :) 无论如何谢谢。以上是关于CSRF 验证失败 - 当主机安全时,Referer 不安全的主要内容,如果未能解决你的问题,请参考以下文章