对 Django 的请求中缺少自定义标头

问题描述:

上下文:我编写了一个 Django 应用程序,现在已将其部署到 Elastic Beanstalk (AWS).

Context: I've written a Django app which I have now deployed to Elastic Beanstalk (AWS).

在本地开发中,我一直在使用自定义请求标头 SESSION_TOKEN,然后我可以使用 request.META.get('HTTP_SESSION_TOKEN') 访问它.在生产中,我看到错误,因为该标头不可访问(也就是我的 Django 服务器看到的所有请求中都缺少它).

In local development I've been using a custom request header SESSION_TOKEN which I can then access using request.META.get('HTTP_SESSION_TOKEN'). In production I'm seeing errors because that header is not accessible (aka it is simply missing in all requests my Django server is seeing).

此外,我的其他标准标头工作正常,只是缺少自定义标头.注意我没有设置 HTTP_AUTHORIZATION,这与 django rest_framework 中缺少授权标头,是 apache 的错吗?.

Additionally my other standard headers are working fine, it is only the custom header that is missing. Note I'm not setting HTTP_AUTHORIZATION, this is not the same issue as Authorization header missing in django rest_framework, is apache to blame?.

怎么了?如何在生产中访问后端的自定义标头?

What is going wrong? How can I access custom headers on my backend in production?

很可能 SESSION_TOKEN 标头被某些东西剥离了.来自 Django 安全公告:

Most likely SESSION_TOKEN header is stripped by something. From Django security advisory:

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

When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django's request.META dictionary).

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

Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection.

以及最重要的信息:

为了防止此类攻击,默认情况下,Nginx 和 Apache 2.4+ 都会从传入请求中去除所有包含下划线的标头.Django 的内置开发服务器现在也做同样的事情.不建议将 Django 的开发服务器用于生产用途,但匹配常见生产服务器的行为可以减少部署期间行为更改的表面积.

In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django's built-in development server now does the same. Django's development server is not recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment.

如果您有任何自定义标题,则应改用连字符.

If you have any custom headers you should use hyphen instead.