2016-07-15 3 views
2

Я пытаюсь использовать (относительно) безопасный способ Python (2.7) eval. Таким образом, я определил:Является ли кто-нибудь действительно встроенным?

def safer_eval(string): 
    """Safer version of eval() as globals and builtins are inaccessible""" 
    return eval(string, {'__builtins__': {}}) 

Как и ожидалось, следующий не работает больше:

print safer_eval("True") 
NameError: name 'True' is not defined 

Однако, я все еще могу Eval в "None" строку:

print safer_eval("None") 
None 
  • Итак, None не встроенный? Они, по крайней мере, оба являются частью __builtin__ ...

  • Почему это еще возможно?

  • Как я могу избавиться от него, если бы мне пришлось?
+4

Почему бы просто не использовать 'ast.literal_eval'? – jonrsharpe

+0

Какая версия Python? – Ares

+0

Да, 'None' - это встроенный одноэлементный объект и ключевое слово *. –

ответ

9

None в Python константа, см Keywords documentation:

Изменено в версии 2.4: None стал постоянным и теперь распознается компилятором как имя для встроенного объекта None. Хотя это не ключевое слово, вы не можете назначить ему другой объект.

Компилятор просто вставляет ссылку на объект синглтон None всякий раз, когда вы называете его:

>>> from dis import dis 
>>> dis(compile('None', '', 'eval')) 
    1   0 LOAD_CONST    0 (None) 
       3 RETURN_VALUE 

True и False являются встроенные модули в Python 2, что также означает, что они могут быть замаскированы.

В Python 3 None, True и False все now keywords, и все три материализуются лишь называя их:

>>> eval('True', {'__builtins__': {}}) 
True 

См Guido van Rossum's blog post on why this was changed.

Обратите внимание, что есть ничего безопасно о Eval, даже с __builtins__ стерилизована, как его еще можно ссылаться с помощью других средств:

>>> s = ''' 
... [ 
...  c for c in().__class__.__base__.__subclasses__() 
...  if c.__name__ == 'catch_warnings' 
... ][0]()._module.__builtins__ 
... ''' 
>>> eval(s, {'__builtins__': {}}) 
{'bytearray': <type 'bytearray'>, 'IndexError': <type 'exceptions.IndexError'>, 'all': <built-in function all>, 'help': Type help() for interactive help, or help(object) for help about object., 'vars': <built-in function vars>, 'SyntaxError': <type 'exceptions.SyntaxError'>, 'unicode': <type 'unicode'>, 'UnicodeDecodeError': <type 'exceptions.UnicodeDecodeError'>, 'memoryview': <type 'memoryview'>, 'isinstance': <built-in function isinstance>, 'copyright': Copyright (c) 2001-2015 Python Software Foundation. 
All Rights Reserved. 

Copyright (c) 2000 BeOpen.com. 
All Rights Reserved. 

Copyright (c) 1995-2001 Corporation for National Research Initiatives. 
All Rights Reserved. 

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. 
All Rights Reserved., 'NameError': <type 'exceptions.NameError'>, 'BytesWarning': <type 'exceptions.BytesWarning'>, 'dict': <type 'dict'>, 'input': <built-in function input>, 'oct': <built-in function oct>, 'bin': <built-in function bin>, 'SystemExit': <type 'exceptions.SystemExit'>, 'StandardError': <type 'exceptions.StandardError'>, 'format': <built-in function format>, 'repr': <built-in function repr>, 'sorted': <built-in function sorted>, 'False': False, 'RuntimeWarning': <type 'exceptions.RuntimeWarning'>, 'list': <type 'list'>, 'iter': <built-in function iter>, 'reload': <built-in function reload>, 'Warning': <type 'exceptions.Warning'>, '__package__': None, 'round': <built-in function round>, 'dir': <built-in function dir>, 'cmp': <built-in function cmp>, 'set': <type 'set'>, 'bytes': <type 'str'>, 'reduce': <built-in function reduce>, 'intern': <built-in function intern>, 'issubclass': <built-in function issubclass>, 'Ellipsis': Ellipsis, 'EOFError': <type 'exceptions.EOFError'>, 'locals': <built-in function locals>, 'BufferError': <type 'exceptions.BufferError'>, 'slice': <type 'slice'>, 'FloatingPointError': <type 'exceptions.FloatingPointError'>, 'sum': <built-in function sum>, 'getattr': <built-in function getattr>, 'abs': <built-in function abs>, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'print': <built-in function print>, 'True': True, 'FutureWarning': <type 'exceptions.FutureWarning'>, 'ImportWarning': <type 'exceptions.ImportWarning'>, 'None': None, 'hash': <built-in function hash>, 'ReferenceError': <type 'exceptions.ReferenceError'>, 'len': <built-in function len>, 'credits':  Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands 
    for supporting Python development. See www.python.org for more information., 'frozenset': <type 'frozenset'>, '__name__': '__builtin__', 'ord': <built-in function ord>, 'super': <type 'super'>, '_': None, 'TypeError': <type 'exceptions.TypeError'>, 'license': See http://www.python.org/2.7/license.html, 'KeyboardInterrupt': <type 'exceptions.KeyboardInterrupt'>, 'UserWarning': <type 'exceptions.UserWarning'>, 'filter': <built-in function filter>, 'range': <built-in function range>, 'staticmethod': <type 'staticmethod'>, 'SystemError': <type 'exceptions.SystemError'>, 'BaseException': <type 'exceptions.BaseException'>, 'pow': <built-in function pow>, 'RuntimeError': <type 'exceptions.RuntimeError'>, 'float': <type 'float'>, 'MemoryError': <type 'exceptions.MemoryError'>, 'StopIteration': <type 'exceptions.StopIteration'>, 'globals': <built-in function globals>, 'divmod': <built-in function divmod>, 'enumerate': <type 'enumerate'>, 'apply': <built-in function apply>, 'LookupError': <type 'exceptions.LookupError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'basestring': <type 'basestring'>, 'UnicodeError': <type 'exceptions.UnicodeError'>, 'zip': <built-in function zip>, 'hex': <built-in function hex>, 'long': <type 'long'>, 'next': <built-in function next>, 'ImportError': <type 'exceptions.ImportError'>, 'chr': <built-in function chr>, 'xrange': <type 'xrange'>, 'type': <type 'type'>, '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", 'Exception': <type 'exceptions.Exception'>, 'tuple': <type 'tuple'>, 'UnicodeTranslateError': <type 'exceptions.UnicodeTranslateError'>, 'reversed': <type 'reversed'>, 'UnicodeEncodeError': <type 'exceptions.UnicodeEncodeError'>, 'IOError': <type 'exceptions.IOError'>, 'hasattr': <built-in function hasattr>, 'delattr': <built-in function delattr>, 'setattr': <built-in function setattr>, 'raw_input': <built-in function raw_input>, 'SyntaxWarning': <type 'exceptions.SyntaxWarning'>, 'compile': <built-in function compile>, 'ArithmeticError': <type 'exceptions.ArithmeticError'>, 'str': <type 'str'>, 'property': <type 'property'>, 'GeneratorExit': <type 'exceptions.GeneratorExit'>, 'int': <type 'int'>, '__import__': <built-in function __import__>, 'KeyError': <type 'exceptions.KeyError'>, 'coerce': <built-in function coerce>, 'PendingDeprecationWarning': <type 'exceptions.PendingDeprecationWarning'>, 'file': <type 'file'>, 'EnvironmentError': <type 'exceptions.EnvironmentError'>, 'unichr': <built-in function unichr>, 'id': <built-in function id>, 'OSError': <type 'exceptions.OSError'>, 'DeprecationWarning': <type 'exceptions.DeprecationWarning'>, 'min': <built-in function min>, 'UnicodeWarning': <type 'exceptions.UnicodeWarning'>, 'execfile': <built-in function execfile>, 'any': <built-in function any>, 'complex': <type 'complex'>, 'bool': <type 'bool'>, 'ValueError': <type 'exceptions.ValueError'>, 'NotImplemented': NotImplemented, 'map': <built-in function map>, 'buffer': <type 'buffer'>, 'max': <built-in function max>, 'object': <type 'object'>, 'TabError': <type 'exceptions.TabError'>, 'callable': <built-in function callable>, 'ZeroDivisionError': <type 'exceptions.ZeroDivisionError'>, 'eval': <built-in function eval>, '__debug__': True, 'IndentationError': <type 'exceptions.IndentationError'>, 'AssertionError': <type 'exceptions.AssertionError'>, 'classmethod': <type 'classmethod'>, 'UnboundLocalError': <type 'exceptions.UnboundLocalError'>, 'NotImplementedError': <type 'exceptions.NotImplementedError'>, 'AttributeError': <type 'exceptions.AttributeError'>, 'OverflowError': <type 'exceptions.OverflowError'>} 

или вы можете просто взорвать интерпретатор, создав сломанный код объект. См. Eval really is dangerous.

Если вы хотите сделать это, загрузите литеральный синтаксис Python (списки, кортежи, словари, строки, номера и т. Д.), Тогда вы хотите использовать ast.literal_eval() function, специально предназначенный для обеспечения безопасности.

+0

Возможно, вы хотите упомянуть 'ast.literal_eval' и ссылку на этот вопрос: http://stackoverflow.com/questions/4710247/python-3-are-there-any-known-security-holes-in-ast-literal -evalnode-or-string? Это похоже на вероятный последующий вопрос ... – NichtJens

+0

@NichtJens: добавлено упоминание; Я не думаю, что этот вопрос нуждается в связывании, документации достаточно: * Хорошо оценить ... * –

+0

Да, отлично! Вы на самом деле просто отвечаете на этот последующий вопрос уже здесь ;-) – NichtJens

1

В Python 2.7 это вполне допустимое утверждение.

True = False 
>>> print True 
False 

Попробуйте сделать это с None хотя и ..

SyntaxError: cannot assign to None

Может рода сделать вашу голову спина. Я не уверен, но я подозреваю, что True является встроенным и None на самом деле является постоянным. Вы можете изменитьTrue на другое значение, но вы не можете изменить None.

+0

Нет, True и False являются встроенными и могут быть замаскированы. –

+0

Значит, они все построены? В чем же тогда разница? EDIT: Ах, я вижу, «Нет» также является ключевым словом. – Ares

+0

Я не уверен, что это технически ключевое слово либо (по крайней мере, не в python2.x): 'import keyword; print keyword.iskeyword ('None') ' – mgilson

Смежные вопросы