有限的评估功能失败-如何导入所选模块

时间:2019-04-15 14:59:48

标签: python function lambda eval

我想将功能性存根附加到我编写的数据处理作业中,并且能够通过配置文件应用这些存根会很方便。

我可以通过eval函数来加载和运行这些函数,但是希望能够控制所评估函数可以在其中运行的可用名称空间“沙盒”,因此可以避免恶意代码注入。

在python文档中,建议先屏蔽__builtins__,然后将全局变量和局部变量中的任意一个(或者是两者都不清楚?)填充为包含执行名称空间中对象的字典。

执行此操作时,我一直成功运行的代码停止工作。

认为这是因为我的测试lambda之一是引用通常从datetime模块导入的函数-但我不清楚如何使它们成功附加到命名空间。

from datetime import datetime
now = datetime.now()
lambdas = { "Report Date" : "lambda x : now.strftime(\"%d/%m/%Y\")",
             "Scary Test"  : "lambda x : os.curdir " }

compiled_funcs = {k:eval(v) for k,v in lambdas.items()}

compiled_funcs ['Report Date'](1)
>>> '15/04/2019'

compiled_funcs ['Scary Test'](1)
>>> '.'

现在,我想编辑eval()函数以限制可用范围,以便datetime函数继续运行,但是os模块失败(如果我可以调用os命令,那么我可能会做一些可怕的事情,例如擦拭磁盘,或更糟)

我尝试过以下构造:

compiled_funcs = {k:eval(v,{'__builtins__':None, "now" : now, "datetime" : datetime, } , { }) for k,v in lambdas.items()}

但是当我这样做时,出现以下错误:

AttributeError: 'NoneType' object has no attribute '__import__'

这暗示我想在某处/以某种方式应用的功能试图在行中调用/导入某些内容-并且(大概)由于使__builtins__内容令人厌烦而被正确阻止。有没有办法将这些功能预先打包并注入到eval全局变量或局部变量字典中,以启用一组预定义的功能工具?

完成这项工作后,我应该可以对其进行扩展,以便整理自己的安全函数调用子集,以暴露给配置文件中的运行时集合。

我在上面知道,我可以不带参数定义lambdæ-但在我的实际代码中,馈入单个参数是正常的,因此已相应地构建了测试代码。

0 个答案:

没有答案