Werkzeug: Werkzeug 不符合 RFC2616

创建于 2016-05-26  ·  6评论  ·  资料来源: pallets/werkzeug

特别是,Werkzeug 在内部将“Transfer-Encoding”或“X-PoweredBy”类型的标头分别转换为“HTTP_TRANSFER_ENCODING”和“X_POWERED_BY”。 但是,如果两个标头“App-Header-1”和“App_Header_1”都出现在请求中——或者甚至只是“App_Header_1”——两者都将在内部以相同的方式存储,而且 Werkzeug 不区分这两者. 此行为不符合 RFC2616 HTTP 1.1 规范,其中 Header 名称可以是任何没有控制或分隔符的有效标记。 这有很多问题,就好像一个带有“App_Header_1”的请求会被转换为“HTTP_APP_HEADER_1”,现在像 Flask 这样的框架会将它解释为“App-Header-1”,这不一样,并传递这些值在任何合理的比较策略下,依赖于正确行为的系统将失败为 "App_Header_1" != "App-Header-1"。

最有用的评论

如果您指的是 PEP 3333,则该行为不是由 WSGI 规范引起的。
PEP 3333 指出:
HTTP_ 变量
对应于客户端提供的 HTTP 请求标头的变量(即名称以“HTTP_”开头的变量)。 这些变量的存在与否应与请求中相应的 HTTP 标头的存在与否相对应。

规范中没有关于以不同方式处理下划线的内容。 事实上,您不符合 PEP 3333 也是因为我不知道哪个标头存在或不存在,即是否存在“App_H”或“App-H”。

所有6条评论

这种行为是由 WSGI 规范本身引起的,并且 Werkzeug 不可能在仍然遵守 WSGI 规范的同时区分这两个标头。 我不知道在实践中这会成为问题的任何情况。

顺便说一下,R​​FC 2616 已被弃用,但较新的 RFC 无论如何都不会改变这方面的任何内容。

Werkzeug 也不负责在语法级别解析或编写 HTTP 请求或响应。 这是由您选择的任何 WSGI 服务器完成的。 Werkzeug 确实有一个内置服务器,但它只是从标准库扩展了 WSGI 服务器。

如果您指的是 PEP 3333,则该行为不是由 WSGI 规范引起的。
PEP 3333 指出:
HTTP_ 变量
对应于客户端提供的 HTTP 请求标头的变量(即名称以“HTTP_”开头的变量)。 这些变量的存在与否应与请求中相应的 HTTP 标头的存在与否相对应。

规范中没有关于以不同方式处理下划线的内容。 事实上,您不符合 PEP 3333 也是因为我不知道哪个标头存在或不存在,即是否存在“App_H”或“App-H”。

WSGI 是 CGI 的 Python 特定端口。 PEP 0333 引用了 CGI 规范来定义“CGI 环境变量”,其中指出:

The HTTP header field name is converted to upper case, has all occurrences of "-" replaced with "_" and has `HTTP_' prepended to give the meta-variable name.

https://tools.ietf.org/html/rfc3875#section -4.1.18

所有这些都无关紧要,因为 Werkzeug 在大多数情况下不解析原始 HTTP 请求,也不生成 WSGI 环境。 它解析 WSGI 环境。 我不明白你为什么要针对这个特定的实现提交这个问题。 不要射击使者。

基本上这里有很多来自 CGI 的遗产,这些遗产是由 WSGI 继承的,这是 Werkzeug 试图实现的。

我真的不是故意要打架; 但这是一个安全隐患的问题,特别是对于位于“传统”-ish 应用程序网关后面的 Web 服务器,这些网关在包含下划线的标头中传递敏感/特定于应用程序的信息而不过滤其他标头(我有具体的例子,也就是说,这是实际上是实践中的一个问题,您在最初的评论中已将其驳回)。 CGI 已有 20 多年的历史,因此 WSGI 和 HTTP 规范应该优先。

至于原始解析:
https://github.com/pallets/werkzeug/blob/03faf0569861e9d8c8c94785ad5560f735ba72da/werkzeug/serving.py#L123

(我有具体的例子,也就是说,这实际上是实践中的一个问题,您在最初的评论中已经驳回了这一点)

那么我只能说很抱歉你有这样的服务器。 Werkzeug 对此无能为力。 你展示的片段正是我说“大部分”的原因。 Werkzeug 还包括一个可用于开发的简单测试服务器(例如,避免必须设置 Gunicorn + Nginx/Apache)。 但是,如果您将该服务器暴露在 Internet 上,那么您提到的潜在问题将是您的(安全)问题中最少的。

WSGI 旨在最大程度地与 CGI 兼容。 WSGI 不会覆盖或取代 CGI。 WSGI _is_ CGI。 使 WSGI 应用程序成为有效的 CGI 应用程序所涉及的工作很少。 Python CGI 脚本的os.environ看起来很像等效的 WSGI 环境。 对此进行任何更改时,需要考虑很多遗留问题。 Werkzeug 作为一个项目在这方面没有发言权,尤其是我。

同样,这个项目的这个问题毫无意义。 Werkzeug 并不是唯一一个有这种行为的人。 由于整个歧义问题,上次我检查 nginx 默认情况下会阻止带有下划线的 HTTP 标头。 大多数其他工具可能只是将它们混为一谈。 如果大多数工具无法区分破折号和下划线,那么标准说有一个就不再重要了。 每个人都被迫一起玩,最终应该归咎于发出带有下划线的标题的工具。

此页面是否有帮助?
0 / 5 - 0 等级