本文共 4419 字,大约阅读时间需要 14 分钟。
This should have been obvious to me for a longer time, but until earlier today I did not really realize the severity of the issues caused by str.format on untrusted user input. It came up as a way to bypass the Jinja2 Sandbox in a way that would permit retrieving information that you should not have access to which is why I just pushed out a for it.
这对我来说应该已经很长时间了,但是直到今天早些时候,我才真正意识到由str.format引起的问题的严重性。 这是绕过Jinja2沙箱的一种方式,它允许检索您不应该访问的信息,这就是为什么我为此了一个 。
However I think the general issue is quite severe and needs to be a discussed because most people are most likely not aware of how easy it is to exploit.
但是,我认为一般问题非常严重,需要进行讨论,因为大多数人很可能不知道利用它的难易程度。
Starting with Python 2.6 a new format string syntax landed inspired by .NET which is also the same syntax that is supported by Rust and some other programming languages. It’s available behind the .format() method on byte and unicode strings (on Python 3 just on unicode strings) and it’s also mirrored in the more customizable string.Formatter API.
从Python 2.6开始,.NET启发了一种新的格式字符串语法,该语法也与Rust和其他一些编程语言所支持的语法相同。 它在.format()方法后面可用于字节和unicode字符串(在Python 3上仅在unicode字符串上),并且还反映在更可定制的string.Formatter API中。
One of the features of it is that you can address both positional and keyword arguments to the string formatting and you can explicitly reorder items at all times. However the bigger feature is that you can access attributes and items of objects. The latter is what is causing the problem here.
它的功能之一是您可以将位置和关键字参数都设置为字符串格式,并且可以随时明确地对项目进行重新排序。 但是,更大的功能是您可以访问属性和对象项。 后者是导致此问题的原因。
Essentially one can do things like the following:
本质上,人们可以做以下事情:
>>> >>> 'class of {0} is {0.__class__}''class of {0} is {0.__class__}' .. formatformat (( 4242 ))"class of 42 is""class of 42 is "
In essence: whoever controls the format string can access potentially internal attributes of objects.
本质上:控制格式字符串的任何人都可以访问对象的潜在内部属性。
First question is why would anyone control the format string. There are a few places where it shows up:
第一个问题是为什么有人会控制格式字符串。 它显示在一些地方:
For as long as only C interpreter objects are passed to the format string you are somewhat safe because the worst you can discover is some internal reprs like the fact that something is an integer class above.
只要仅将C解释器对象传递给格式字符串,您就有些安全了,因为您可能发现的最糟糕的情况是某些内部代表,例如上面的某些东西是整数类。
However tricky it becomes once Python objects are passed in. The reason for this is that the amount of stuff that is exposed from Python functions is pretty crazy. Here is an example from a hypothetical web application setup that would leak the secret key:
传递Python对象后,它变得多么棘手。其原因是,从Python函数公开的内容非常疯狂。 这是假设的Web应用程序设置中的一个示例,该示例可能会泄露密钥:
If the user can inject format_string here they could discover the secret string like this:
如果用户可以在此处注入format_string ,他们可以像下面这样发现秘密字符串:
{event.__init__.__globals__[CONFIG][SECRET_KEY]}{event.__init__.__globals__[CONFIG][SECRET_KEY]}
So what do you do if you do need to let someone else provide format strings? You can use the somewhat undocumented internals to change the behavior.
那么,如果您需要让别人提供格式字符串,该怎么办? 您可以使用未公开的内部文件来更改行为。
Now you can use the safe_format method as a replacement for str.format:
现在,您可以使用safe_format方法替代str.format :
>>> >>> '{0.__class__}''{0.__class__}' .. formatformat (( 4242 ))""" ">>> >>> safe_formatsafe_format (( '{0.__class__}''{0.__class__}' , , 4242 ))Traceback (most recent call last): File Traceback (most recent call last): File " ", line " " , line 1, in 1 , in AttributeError: AttributeError : __class____class__
翻译自:
转载地址:http://qqqwd.baihongyu.com/