python3 eval安全替代函数ast.literal
一、eval函数
eval()
官方文档里面给出来的功能解释是:将字符串string
对象转化为有效的表达式参与求值运算返回计算结果。
示例:
>>> s='8*8'
>>> eval(s)
64
>>> eval('2+5*4')
22
>>> x=1
>>> y=4
>>> eval('x+y')
5
>>> eval('98.9')
98.9
>>> eval('9.9\n')
9.9
>>> eval('9.9\n\t\r \t\r\n')
9.9
最有用的一个是
eval
可以将字符串转换成字典,列表,元组
>>> l = "[2,3,4,5]"
>>> ll=eval(l)
>>> ll
[2, 3, 4, 5]
>>> type(ll)
<type 'list'>
>>> d="{'name':'python','age':20}"
>>> dd=eval(d)
>>> type(dd)
<type 'dict'>
>>> dd
{'age': 20, 'name': 'python'}
>>> t='(1,2,3)'
>>> tt=eval(t)
>>> type(tt)
<type 'tuple'>
>>> tt
(1, 2, 3)
eval()
函数功能强大,但也很危险,若程序中有以下语句:
s=input('please input:')
print (eval(s))
下面举几个被恶意用户使用的例子:
1、运行程序,如果用户恶意输入:
please input:__import__('os').system('ls')
则eval()
之后,当前目录文件都会展现在用户前面。
演示结果:
2、运行程序,如果用户恶意输入:
please input: open('xxx.py').read()
如果,当前目录中恰好有一个文件,名为data.py
,则恶意用户变读取到了文件中的内容。
3、运行程序,如果用户恶意输入:
please input:__import__('os').system('del test.txt /q')
如果,当前目录中恰好有一个文件,名为test.txt,则恶意用户删除了该文件。/q :指定静音状态。不提示您确认删除。
二、ast.literal_eval方法
ast.literal_eval是python针对eval方法存在的安全漏洞而提出的一种安全处理方式。
简单点说ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的Python类型,如果是则进行运算,否则就不进行运算。
比如下面查看系统文件的操作就会被拒绝,而只会执行合法的python类型,从而大大降低了系统的危险性
import ast
res = ast.literal_eval('1 + 1')
print(res)
# 2
res = ast.literal_eval('[1, 2, 3, 4]')
print(type(res))
# <class 'list'>
print(res)
# [1, 2, 3, 4]
res = ast.literal_eval("__import__('os').system('ls')")
# 报错如下:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/didi/.pyenv/versions/3.6.4/lib/python3.6/ast.py", line 85, in literal_eval
return _convert(node_or_string)
File "/Users/didi/.pyenv/versions/3.6.4/lib/python3.6/ast.py", line 84, in _convert
raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x10e63ca58>
所以出于安全考虑,对字符串进行类型转换的时候,最好使用
ast.literal_eval()
赞 (0)