温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

使用eval函数会有什么影响

发布时间:2020-07-02 13:52:15 来源:亿速云 阅读:194 作者:清晨 栏目:编程语言

小编给大家分享一下使用eval函数会有什么影响,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨方法吧!

如果你了解JavaScript或者PHP等,那么你一定对eval()所有了解。如果你并没有接触过也没关系,eva()l函数的使用非常简单。

>>> eval("1+1==2")     #进行判断
True
>>> eval("'a'+'b'")    #字符连接
'ab'
>>> eval("4+5")        #数字相加
9
>>>1234567

Python中eval()函数将字符串str当成有效的表达式来求值并返回计算结果。其函数声明如下:

eval(expression[, globals[, locals]])1
  • expression – 表达式。
  • globals – 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
  • locals – 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

其中,globals 参数为字典形式,locals 为任何映射对象,它们分别表示全局和局部命名空间。如果传人globals参数的字典中缺少__builtins__的时候,当前的全局命名空间将作为globals参数输人并且在表达式计算之前被解析。locals 参数默认与globals相同,如果两者都省略的话,表达式将在eval()调用的环境中执行。

“eval is evil”(eval是邪恶的),这是一句广为人知的对eval的评价,它主要针对的是eval()的安全性。那么eval存在什么样的安全漏洞呢?来看一个简单的例子:

import sys
from math import *


def ExpCalcBot(string):
    try:
        print('Your answer is', eval(string))
    except NameError:
        print('The expression you enter is not valid')


print('Hi,I am ExpCalcBot.please input your experssion or enter e to end')
inputstr = ''
while 1:
    print('Please enter a number or operation.Enter c to complete')
    inputstr = raw_input()
    if inputstr == str('e'):
        sys.exit()
    elif repr(inputstr) != repr(''):
        ExpCalcBot(inputstr)
        inputstr = ''12345678910111213141516171819202122

上面这段代码的主要功能是:根据用户的输人,计算Python表达式的值。它有什么问题呢?如果用户都是素质良好,没有不良目的的话,那么这段程序也许可以满足基本需求。

比如,输人1+sin(20)会输出结果1.91294525073。但如果它是一个Web页面的后台调用(当然,你需要做一定的修改),由于网络环境下运行它的用户并非都是可信任的,问题就出现了。因为eval()可以将任何字符串当做表达式求值,这也就意味着有空子可钻。上面的例子中假设用户输人_import_(“os”).system(“drr”),会有什么样的输出呢?你会惊讶地发现它会显示当前目录下的所有文件列表,输出如下:
使用eval函数会有什么影响

于是顿时,有人的“坏心眼”来了,他输人了如下字符串,可悲的事情发生了,当前目录下的所有文件都被删除了,包括test.py,而这一切没有任何提示,悄无声息。

__import__("os").system("del * /q") #!!!不要轻易在你的计算机上尝试1

试想,在网络环境下这是不是很危险?也许你会辩护,那是因为你没有在globals参数中禁止全局命名空间的访问。那么我们来尝试一下

def ExpCalcBot(string):
    try:
        math_fun_list = ['acos', 'asin', 'atan', 'cos', 'e', 'log', 'log10', 'pi', 'pow', 'sin', 'sqrt', 'tan']
        math_fun_dict = dict([(k, globals().get(k)) for k in math_fun_list])  # 形成可以访问的函数字典
        print('Your answer is', eval(string, {"__builtins__": None}, math_fun_dict))
    except NameError:
        print('The expression you enter is not valid')1234567

再次输入__import__(“os”).system(“del * /q”) ,提示如下:
使用eval函数会有什么影响

安全问题不再是个问题!但同时又出现了新的问题,例如输入以下字符:
[ c for c in ().class.bases[0].subclasses() if c.name==‘Quitter’ ]0(),其中
().class.bases[0].subclasses()用来显示object类的所有子类。类Quitter与"quit"功能绑定,因此上面的输入会直接导致程序退出

你可以在python的安装目录下的Lib\site.py中找到其类的定义。也可以自行在python解释器中输入print().class.bases[0].subclasses()查看输出结果是什么。

因此对于有经验的侵入者来说,他可能会有一系列强大的手段,使得eval可以解释和调用这些方法,从而带来更大的破坏。此外,eval()函数也给程序的调试带来一定困难,要查看里面表达式具体的执行过程很难。因此在实际应用过程中如果使用对象不是信任源,应该尽量避免使用eval,在需要使用eval的地方可用安全性更好的ast.literal_eval替代。literaleval函数具体详情可以参考文档http://docs.pythonorg/2/library/ast.html#ast.literaleval。


看完了这篇文章,相信你对使用eval函数会有什么影响有了一定的了解,想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI