这是python eval()的安全使用吗?

时间:2011-03-18 11:07:19

标签: python security

如果攻击者可以控制attacker_controlled_nasty_variable的值,那么此段代码是否容易受到攻击?

dic={"one":1,
      "nasty":attacker_controlled_nasty_variable,
     }
store=str(dict)
...
dic=eval(store)

4 个答案:

答案 0 :(得分:11)

使用ast.literal_eval()代替eval()

答案 1 :(得分:6)

是。它可以替换为具有__repr__()方法的对象,该方法具有有效负载本身,或者返回传递给eval()时可能不安全的字符串。

概念证明:

class MyClass(object):
  def __repr__(self):
    return 'os.system("format c:")'

bad = [MyClass()]
print str(bad)

答案 2 :(得分:3)

只要您确定attacker_controlled_nasty_variable永远不是攻击者可以控制__repr__(或__str__)的对象,它就是安全的,否则它会注入python代码。< / p>

但是,最好使用repr(dic)而不是str(dic),因为只有repr才能返回有效的python代码。

此外 - 正如@payne所述 - 使用更安全的ast.literal_eval()代替eval()

答案 3 :(得分:1)

我们试一试:

>>> 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}

您可能想尝试更多案例,但从经验上看,__repr__似乎正在引用内容。