开发者

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?

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


Use ast.literal_eval() instead of 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().

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.

However, better use repr(dic) instead of str(dic) since only repr is expected to return valid python code.

Additionally - as mentioned by @payne - use the safer ast.literal_eval() instead of 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜