我正在尝试使用Python设置客户端和服务器,以便客户端发送一些代码,服务器执行和处理它,然后发送输出。我可以使用exec命令在服务器上执行接收到的代码,但每当我尝试var = exec "print 'word'"时,它都无法正常工作并且失败,显示语法错误;而当我运行相同的命令而不设置变量时,它能够无缝运行。我正在使用Python2.7。
我正在尝试使用Python设置客户端和服务器,以便客户端发送一些代码,服务器执行和处理它,然后发送输出。我可以使用exec命令在服务器上执行接收到的代码,但每当我尝试var = exec "print 'word'"时,它都无法正常工作并且失败,显示语法错误;而当我运行相同的命令而不设置变量时,它能够无缝运行。我正在使用Python2.7。
不要使用eval和exec,它们对于不可信的输入非常危险,而且没有合理的方法可以使它们安全:
从不可信的输入中使用eval
或exec
意味着您可能会得到这样的查询:
eval("os.system('clear')", {})
ast.literal_eval
安全地将字符串转换为Python对象。>>> import ast
>>> string = '{}'
>>> b = ast.literal_eval(string)
>>> b
{}
>>> type(b)
<class 'dict'>
如果你可以信任输入,使用eval
。
>>> string = '{}'
>>> b = eval(string)
>>> b
{}
>>> type(b)
<class 'dict'>
Eval和Exec的危险性
为了解释为什么eval
是危险的,以及为什么ast.literal_eval是安全的,你需要了解eval的工作原理:它只是将一个字符串解释为Python代码,允许发生基本上任何事情。
有许多方法可以尝试使eval
和exec
安全,但是所有这些方法都有各种绕过它们的方式。你可以防止几乎一切,包括导入、内置函数等等,但是某些人仍然可以找到绕过它们的方法(参见上面的链接)。
ast.literal_eval
通过仅允许评估有效的Python数据类型(例如dict、list、tuple、None、int、string和float)来避免这种情况。这可以防止任何代码的恶意执行,但应用程序的功能要受到更大的限制。然而,对于来自未知来源的代码来说,这种额外的安全性是非常值得失去功能的。
ast.literal_eval
如何保护你的安全的一个很好的例子是以下片段:
>>> import ast
>>> eval('__import__("os")')
<module 'os' from '/usr/lib/python3.4/os.py'>
>>> ast.literal_eval('__import__("os")')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/ast.py", line 84, in literal_eval
return _convert(node_or_string)
File "/usr/lib/python3.4/ast.py", line 83, in _convert
raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7f68e03db2e8>
您可以在exec
语句中设置变量:
>>> exec("var = 'hello'")
>>> var
'hello'
os.system('clear')
很糟糕。它到底是做什么的? - Toothpick Anemoneos.system
访问权限的人可以轻松地擦除您的硬盘或者更糟的情况。这个命令本意是无害的,因为我不想让别人复制粘贴代码时不小心把自己的数据给擦除了。 - Alex Huszagh