我在检查一个计算器的例子,在这个例子中使用eval()
,这通常是危险的,但这是这个例子的一部分
if button == "=":
#Check carefully how we using the 'dangerous' eval()
total = eval(str1,{"__builtins__":None},{})
str1 = str(total)
print (str1)
我检查了一下,但我不明白,eval(str1,{"__builtins__":None},{})
怎么不危险?显然是关于{"__builtins__":None},{}
这一部分,但我不明白。在
注意:str1
是一个字符串,我们正在添加数字和smybols,如4+5
。然后eval()
处理它。在
密码一点也不安全。只需访问文本的属性就可以相对容易地访问
builtins
模块。在例如
细分:
''.__class__.__base__
是object
的简写object.__subclasses__()
列出解释器中{[klass for klass in ... if klass.__name__ == "BuiltinImporter"][0]
选择BuiltinImporter
类。在load_module("builtins")
使用BuiltinImporter
访问builtins
模块,这正是您试图限制访问的地方。在之所以这是一种更安全的eval()执行方法,是因为它显式地限制了允许哪些内置方法(在本例中不允许)。可以使用该参数指定允许的任何内置项。Here是关于这个主题的更多信息
根据the documentation of ^{}
因此,您所展示的代码试图
eval
在没有潜在危险函数可用的上下文中使用表达式。例如,eval('print("bad stuff")')
将打印不好的内容,但如果传递一个空的全局命名空间,即使没有内置的print
,也不会。在别把这种安全感看得太过分。不受信任的代码也可以共享您的程序,即使在这些限制内。例如,以下字符串if
eval()
d将通过超出其递归堆栈使Python解释器崩溃:正如Håken Lid在his comment中提到的,一个更安全的方法是使用^{} ,这正是为此而设计的。一般来说,最好是使用功能最弱的命令来完成任务,而不是使用功能强大的命令并尝试手动限制它。有太多的事情你可以忘记。在
相关问题 更多 >
编程相关推荐