我知道对用户输入运行 eval 非常危险,像我在下面的代码中所做的那样限制输入是否可以消除所有危险?
q=''
safe=['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '*', '/', '(', ')', '.']
while True:
i= input('input = ')
if i == 'exit':
exit('Shutting Down.')
elif i in safe:
q += i
elif i == '=':
print(eval(q))
else:
print('no')
如果这仍然包含漏洞,是否有某种方法可以将符号添加到一串数字中并计算答案?我知道我可以简单地使用 float() 将字符串数字转换为实际数字,但我不知道如何将“+”添加为 +,以便可以在计算中使用它。
编辑:由于我不小心上传了错误的代码,所以切换了代码
如果要检查整个输入字符串,可以将安全字符放入一个集合中,然后将输入与安全集合进行比较。
试试这个代码:
safe=['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '*', '/', '(', ')', '.']
safeall = set(safe) # all safe characters
while True:
i= input('input = ').strip()
if i == 'exit':
exit('Shutting Down.')
if safeall & set(i) == set(i): # if input in safe characters
print('Safe')
print(eval(i))
else:
print('Not Safe')
输出
input = test123
Not safe
input = ##$$%%
Not safe
input = 12 + 67
Safe
79
input = exit
Shutting Down.
当涉及到安全性时,提出自己的解决方案几乎从来都不是一个好主意。几乎总会有一些你忘记的洞。
最佳做法是使用
ast.literal_eval
。这是专门为了允许安全地计算表达式而设计的,而不会让代码进行函数调用。