[英]Is this a safe use of python eval()?
If an attacker can control the value of attacker_controlled_nasty_variable
, is this segment of code vulnerable? 如果攻击者可以控制的值
attacker_controlled_nasty_variable
,是这个代码段脆弱?
dic={"one":1,
"nasty":attacker_controlled_nasty_variable,
}
store=str(dict)
...
dic=eval(store)
使用ast.literal_eval()
而不是eval()
。
Yes. 是。 It could be replaced with an object that has a
__repr__()
method that either has a payload itself, or returns a string that could be unsafe when passed to eval()
. 它可以替换为具有
__repr__()
方法的对象,该方法具有有效负载本身,或者返回传递给eval()
时可能不安全的字符串。
Proof of Concept: 概念证明:
class MyClass(object):
def __repr__(self):
return 'os.system("format c:")'
bad = [MyClass()]
print str(bad)
It is safe as long as you can be sure that attacker_controlled_nasty_variable
is never an object where the attacker can control __repr__
(or __str__
) as he could otherwise inject python code. 它是安全的,只要你可以确定
attacker_controlled_nasty_variable
永远不是攻击者可以控制__repr__
(或__str__
)的对象,否则它会注入python代码。
However, better use repr(dic)
instead of str(dic)
since only repr
is expected to return valid python code. 但是,最好使用
repr(dic)
而不是str(dic)
因为只有repr
才能返回有效的python代码。
Additionally - as mentioned by @payne - use the safer ast.literal_eval()
instead of eval()
. 另外 - 正如@payne所提到的 - 使用更安全的
ast.literal_eval()
而不是eval()
。
Let's try it: 我们来试试吧:
>>> attacker_controlled_nasty_variable="`cat /etc/passwd`"
>>> dic={"one":1,
... "nasty":attacker_controlled_nasty_variable,
... }
>>> store = repr(dic)
>>> store
"{'nasty': '`cat /etc/passwd`', 'one': 1}"
>>> dic=eval(store)
>>> dic
{'nasty': '`cat /etc/passwd`', 'one': 1}
>>> attacker_controlled_nasty_variable="'hello',}"
>>> dic={"one":1,
... "nasty":attacker_controlled_nasty_variable,
... }
>>> repr(dic)
'{\'nasty\': "\'hello\',}", \'one\': 1}'
>>> eval(repr(dic))
{'nasty': "'hello',}", 'one': 1}
You may want to try more cases, but empirically it looks like __repr__
is quoting the contents correctly. 您可能想尝试更多案例,但从经验
__repr__
正在引用内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.