Django请求中缺少自定义头信息

9

背景:我编写了一个Django应用程序,现在已经部署到Elastic Beanstalk(AWS)。

在本地开发中,我使用了自定义请求头SESSION_TOKEN,然后可以使用request.META.get('HTTP_SESSION_TOKEN')进行访问。在生产环境中,我看到错误,因为该标头无法访问(即我的Django服务器在接收到的所有请求中都没有这个标头)。

此外,我的其他标准标头都正常工作,只有自定义标头丢失了。请注意,我没有设置HTTP_AUTHORIZATION,这与django rest_framework中缺少授权头,是apache的问题吗? 不同。

出了什么问题?如何在生产环境中访问后端的自定义标头?

1个回答

26

很可能 SESSION_TOKEN 头被某些东西去掉了。从Django安全公告中获取以下信息:

当HTTP头放入WSGI环境中时,它们通过转换为大写字母、将所有破折号转换为下划线并在前面添加HTTP_来进行规范化。例如,标题X-Auth-User在WSGI环境中将变为HTTP_X_AUTH_USER(因此也在Django的request.META字典中)。

不幸的是,这意味着WSGI环境无法区分包含破折号和包含下划线的标头: X-Auth-User和X-Auth_User都会变成HTTP_X_AUTH_USER。这意味着,如果标头以安全敏感方式使用(例如,从前端代理传递身份验证信息),即使代理仔细剥离任何传入的X-Auth-User值,攻击者也可能能够提供一个带有下划线的X-Auth_User标头,并绕过此保护。

最重要的信息是:

为了防止此类攻击,Nginx和Apache 2.4+默认情况下从传入请求中删除所有包含下划线的标头。Django的内置开发服务器现在也是如此。不建议在生产中使用Django的开发服务器,但匹配常见的生产服务器行为可以减少部署期间出现行为变化的风险。

如果您有任何自定义标头,应该使用连字符代替下划线。


1
将请求中的标题设置为 Session-Token,并将其读取为 HTTP_SESSION_TOKEN 解决了这个问题。谢谢! - owencm
你为什么不使用标准的Django会话应用程序,它使用cookie而不是头来传递会话ID。这似乎更安全,因为您可以指定仅在安全连接中使用cookie等(虽然不是100%可靠,但至少有所作为)。 - miki725
我最初使用Django作为本地应用程序的API后端,所以这是显而易见的选择。现在我已经转向构建Web客户端,但担心使用cookie时会出现CSRF问题,但我的当前方法运行良好,所以我保留了它 :) - owencm
如果您正在制作API,我建议使用令牌与会话ID的概念。我喜欢使用DRF开发API,它具有内置的令牌身份验证功能 - http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication - miki725
2
我因为在 Django 中无法显示标题而感到非常苦恼,但第二部分解决了我的问题,原来是名称中有下划线。 - gouravkr
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接