前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python内置函数eval()用法及其安全问题

Python内置函数eval()用法及其安全问题

作者头像
Python小屋屋主
发布2018-04-16 14:32:12
3.8K0
发布2018-04-16 14:32:12
举报
文章被收录于专栏:Python小屋Python小屋

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>

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档