Django CSRF“Referer Malformed"......但它不是 [英] Django CSRF "Referer Malformed"... but it isn't

查看:43
本文介绍了Django CSRF“Referer Malformed"......但它不是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试测试在开发模式下运行良好的 Django 设置的部署配置.

I'm trying to test a deployment config for a Django setup that works fine in development mode.

我通过负载均衡器上的 Nginx 的 ssl_preread 模块进行基于名称的路由,并且 SSL 在服务器本身的另一个 Nginx 实例处终止,其中请求通过套接字代理到 uwsgi.

I have name-based routing via Nginx's ssl_preread module on a load balancer, and SSL terminates at another Nginx instance on the server itself where the requests are proxied to uwsgi by socket.

server {
    server_name dev.domain.net;
    listen 80 proxy_protocol;
    listen [::]:80 proxy_protocol;
        location / {
            return 301 https://$host$request_uri;
        }
}
server {
    server_name dev.domain.net;
    listen 443 ssl;
    listen [::]:443 ssl;
    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/website.sock;
    }
    location /favicon.ico {
        access_log off; log_not_found off;
    }
}

我已将 uwsgi 设置为记录 %(host)%(referer),它们在日志中匹配.

I have uwsgi set to log %(host) and %(referer), they match in the logs.

在我的 uwsgi_params 中,我像这样传递 $host$referer,因为我使用的是基于名称的路由,所以我选择了 $server_name 触发 Nginx 响应的变量...

In my uwsgi_params I'm passing $host and $referer like so, since I'm using name-based routing I pick up the $server_name variable that triggered the Nginx response...

uwsgi_param  HTTP_REFERER       $server_name;
uwsgi_param  HTTP_HOST          $host;

向这些添加(或删除)协议和端口没有区别.可预见地将它们带走会产生 Django ALLOWED_HOSTS 调试错误.

Adding (or taking away) protocols and ports to these makes no difference. Taking them away predictably generates a Django ALLOWED_HOSTS debug error.

我已确认我的 ALLOWED_HOSTS 包含 $host.我尝试为相同的 $host 变量添加 CSRF_TRUSTED_ORIGINS.我尝试为相同的 $host 变量设置 CSRF_COOKIE_DOMAIN.根据文档建议,我将 CSRF_COOKIE_SECURE 设置为 True.

I've confirmed that my ALLOWED_HOSTS includes the $host. I've tried adding CSRF_TRUSTED_ORIGINS for the same $host variable. I've tried setting CSRF_COOKIE_DOMAIN for the same $host variable. I have CSRF_COOKIE_SECURE set to True per the docs recommendation.

无论使用上述设置的哪种组合,我都得到:

No matter what combination of the above settings are used, I get:

Referer 检查失败 - Referer 格式错误. 在所有 POST 请求中.

Referer checking failed - Referer is malformed. on all POST requests.

推荐答案

Short answer: 不要使用 uwsgi unix socket,而是使用 http-socket 并将代理请求发送到 localhost未加密的 http(在 uwsgi ini 文件中):

Short answer: don't use the uwsgi unix socket, but rather use http-socket and send the proxy request to localhost over unencrypted http (in uwsgi ini file):

http-socket = 127.0.0.1:8001

在 nginx 中,去掉 uwsgi 代理参数,并简单地在 proxy_pass 启用 proxy_protocol 标头:

In nginx, get rid of uwsgi proxy params and simply proxy_pass with proxy_protocol headers enabled:

server {
    server_name dev.domain.net;
    listen 443 ssl proxy_protocol;
    listen [::]:443 ssl proxy_protocol;
    location / {
        proxy_pass http://127.0.0.1:8001;
    }
    location /favicon.ico {
        access_log off; log_not_found off;
    }
}

此时您可以启用 Django 文档中所有推荐的部署设置,明确声明您的 ALLOWED_HOSTS 并且一切正常.

At that point you can enable all of the recommended deployment settings in the Django docs, explicitly declare your ALLOWED_HOSTS and everything works fine.

这些是一系列非常愚蠢的圈套,没有明显正确的答案集,特别是考虑到引用是很容易伪造的客户端标头.

These are a quite silly series of hoops with no apparent correct set of answers, especially considering referers are client headers that are easily forged.

更好的答案是 Django 需要在其 CSRF 机制中摆脱客户端引用检查,它毫无意义且毫无意义......

The better answer is Django needs to get rid of a client referer check in its CSRF mechanism, it's pointless and makes no sense...

这篇关于Django CSRF“Referer Malformed"......但它不是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆