Это безопасное использование python eval ()? - PullRequest
4 голосов
/ 18 марта 2011

Если злоумышленник может контролировать значение attacker_controlled_nasty_variable, уязвим ли этот сегмент кода?

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

Ответы [ 4 ]

11 голосов
/ 18 марта 2011

Используйте ast.literal_eval() вместо eval().

6 голосов
/ 18 марта 2011

Да.Его можно заменить на объект, имеющий метод __repr__(), который либо сам имеет полезную нагрузку, либо возвращает строку, которая может быть небезопасной при передаче в eval().

Подтверждение концепции:

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

bad = [MyClass()]
print str(bad)
3 голосов
/ 18 марта 2011

Это безопасно, если вы можете быть уверены, что attacker_controlled_nasty_variable никогда не будет объектом, где злоумышленник может контролировать __repr__ (или __str__), поскольку он мог бы в противном случае ввести код Python.

Однако лучше использовать repr(dic) вместо str(dic), поскольку ожидается, что только repr вернет действительный код Python.

Дополнительно - как упоминалось @payne - используйте более безопасный ast.literal_eval() вместо eval().

1 голос
/ 18 марта 2011

Давайте попробуем:

>>> 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__ правильно цитирует содержимое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...