对于不受信任的格式字符串,Python 的字符串 .format() 可以安全吗? [英] Can Python's string .format() be made safe for untrusted format strings?

查看:103
本文介绍了对于不受信任的格式字符串,Python 的字符串 .format() 可以安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 Web 应用程序,用户可以在其中提供字符串,然后服务器会将这些字符串替换为变量.

I'm working on a web app where users will be able to supply strings that the server will then substitute variables into.

我更喜欢使用 PEP 3101 format() 语法,我正在研究在 Formatter 中覆盖方法的可行性,以确保不受信任的输入的安全.

Preferably I'd like to use PEP 3101 format() syntax and I'm looking at the feasibility of overriding methods in Formatter to make it secure for untrusted input.

以下是我可以看到的 .format() 的风险:

Here are the risks I can see with .format() as it stands:

  • Padding 允许您指定任意长度,因此 '{:>9999999999}'.format(..) 可能会导致服务器内存不足并成为 DOS.我需要禁用它.
  • Format 允许您访问对象内部的字段,这很有用,但令人毛骨悚然的是,您可以访问 dunder 变量并开始钻入标准库的各个部分.不知道哪里可能存在具有副作用或返回秘密的 getattr().我会通过覆盖 get_field() 将属性/索引访问列入白名单.
  • 我自然需要捕捉一些异常.

我的假设是:

  • 传统的 C 格式字符串漏洞利用均不适用于 Python,因为指定参数是对集合的边界检查访问,而不是直接从线程堆栈中弹出.
  • 我使用的 Web 框架会转义替换到页面模板中的每个变量,只要它是输出前的最后一站,我就可以避免因反转义而产生的跨站点脚本攻击.

你有什么想法?可能的?不可能的?只是不明智?

What are your thoughts? Possible? Impossible? Merely unwise?

如果您不过滤掉 dunder 变量访问,Armin Ronacher 概述了一个令人讨厌的信息泄漏,但似乎认为保护 format() 是可行的:

Armin Ronacher outlines a nasty information leak if you don't filter out dunder variable access, but seems to regard securing format() as feasible:

{local_foo.__init__.__globals__[secret_global]}

http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/

(就我个人而言,我实际上并没有在我的产品中采用不受信任的 format() 路线,但为了完整性正在更新)

(Personally, I didn't actually go the untrusted format() route in my product, but am updating for the sake of completeness)

推荐答案

良好的直觉.是的,能够提供任意格式字符串的攻击者是python下的一个漏洞.

Good instinct. Yes, an attacker being able to supply arbitrary format string is a vulnerability under python.

  • 拒绝服务可能是最容易解决的问题.在这种情况下,限制字符串的大小或运算符的数量在字符串中将缓解这个问题.应该有一个没有合理的用户需要生成字符串的设置变量比 X 多,而且这个计算量没有风险在 DoS 攻击中被利用.
  • 能够访问对象内的属性可能很危险.但是,我认为 Object 父类没有任何用处信息.提供给格式的对象必须包含敏感的东西.在任何情况下,这种类型的符号都可以限制使用正则表达式.
  • 如果格式字符串是用户提供的,那么用户可能需要知道调试的错误信息.但是,错误消息可以包含敏感信息,例如本地路径或类名.制作确保限制攻击者可以获得的信息.
  • The denial of service is probably the most simple to address. In this case, limiting the size of the string or the number of operators within the string will mitigate this issue. There should be a setting where no reasonable user will need to generate a string with more variables than X, and this amount of computation isn't at risk of being exploited in a DoS attack.
  • Being able to access attributes within an object could be dangerous. However, I don't think that the Object parent class has any useful information. The object supplied to the format would have to contain something sensitive. In any case, this type of notation can limited with a regular expression.
  • If the format strings are user supplied then a user might need to know the error message for debugging. However, error mesages can contain senstive information such as local paths or class names. Make sure to limit the information that an attacker can obtain.

查看 python 格式字符串规范 并禁止您不使用的功能不希望用户使用正则表达式.

Look over the python format string specification and forbid functionality you don't want the user to have with a regex.

这篇关于对于不受信任的格式字符串,Python 的字符串 .format() 可以安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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