Python内置函数eval()用来对表达式进行求值:

>>> eval('3+5')
8
>>> a = 3
>>> b = 5
>>> eval('a+b')
8

这个函数在Python 3.x中使用较多,因为在Python 3.x中使用input()函数接收用户输入时一律返回字符串,经常需要进行类型转换,这时候常使用eval()函数,例如:

>>> x = input('Please input:')
Please input:35
>>> x
'35'
>>> type(x)
<class 'str'>
>>> eval(x)
35
>>> type(_)
<class 'int'>
>>> x = input('Please input:')
Please input:[1, 2, 3]
>>> x
'[1, 2, 3]'
>>> type(x)
<class 'str'>
>>> eval(x)
[1, 2, 3]
>>> type(_)
<class 'list'>

但是,需要注意的是,我们无法保证用户总是输入合法的数据,而恶意黑客也是利用一些程序的bug来精心构造非法输入来触发漏洞,从而造成破坏和攻击。

>>> eval("__import__('os').startfile('notepad.exe')") #启动记事本程序
>>> eval('__import__("os").system("dir")') #列出当前目录的文件列表
>>> eval("__import__('os').system('md testtest')") #在当前目录中创建子目录testtest

当然,这里只是一些善意的演示,通过精心构造输入,充分利用Python标准库和扩展库的功能,会实现很多善意或恶意的目的。

如果程序中确实需要用户输入,并且确实需要对用户的输入进行eval(),那么为了保证安全,可以对用户输入进行敏感字符检查和过滤,例如:

>>> x = input('Please input:')
Please input:__import__("os").system("dir")
>>> if '__import__(' in x:  #使用关键字in进行检查
 print('error') 
error
>>> x = x.replace('__import__(', '***') #使用字符串方法replace()进行过滤和替换
>>> x
'***"os").system("dir")'
>>> eval(x) #如果用户输入中有敏感字符,过滤后会引发异常
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    eval(x)
  File "<string>", line 1
    ***"os").system("dir")
     ^
SyntaxError: invalid syntax

或者,也可以采用这样的办法,在程序第一行增加一行eval = print,这样运行程序时会显示用户输入而不是进行求值计算,当反复测试发现用户输入不会带来危害后再删除这一行。

还有一个办法是使用Python标准库ast提供的literal_eval()方法,功能与eval()一致,但更安全,例如:

>>> import ast
>>> ast.literal_eval('3+5') #正常执行
8
>>> ast.literal_eval("__import__('os').startfile('notepad.exe')") #引发异常
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    ast.literal_eval("__import__('os').startfile('notepad.exe')")
  File "C:\Python35\lib\ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "C:\Python35\lib\ast.py", line 83, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x0000000003539588>

温馨提示:单击文章顶部作者名字旁边浅蓝色的“Python小屋”进入公众号,关注后可以查看更多内容!

欢迎转发给您的朋友,或许这正是Ta需要的知识!