使用ast和白名单制作python';安全吗?

使用ast和白名单制作python';安全吗?,python,security,parsing,eval,Python,Security,Parsing,Eval,嗯。我和您永远不应该在不受信任的数据上使用python的eval()。我并不比世界上其他人聪明,甚至不应该尝试这个。但是无论如何,我要去 我的基本问题是,我希望编写一个小型计算器计算器程序,使用python语法的一个子集来接受不可信的输入。我知道:使用或编写解析器,我们就可以开始了。将全局和局部传递给eval()不会起作用 我所看到的(并且一直对其持怀疑态度的)所有方法都试图列举罪恶。在这里,我试图枚举好的——获取一个AST,只允许几个节点类型,然后验证所有调用都是对一组白名单函数之一的调用。下

嗯。我和您永远不应该在不受信任的数据上使用python的
eval()
。我并不比世界上其他人聪明,甚至不应该尝试这个。但是无论如何,我要去

我的基本问题是,我希望编写一个小型计算器计算器程序,使用python语法的一个子集来接受不可信的输入。我知道:使用或编写解析器,我们就可以开始了。将全局和局部传递给
eval()
不会起作用

我所看到的(并且一直对其持怀疑态度的)所有方法都试图列举罪恶。在这里,我试图枚举好的——获取一个AST,只允许几个节点类型,然后验证所有调用都是对一组白名单函数之一的调用。下面是一个小型实现(和):

导入ast
输入数学
安全系数={
“exp”:math.exp,
}
安全节点=集合(
(ast.Expression,
ast.Num,
打电话,
姓,
最后加载,
ast.BinOp,
最后加上,
东区分区办事处,
马斯特,
行政司)
)
类CleansingNodeVisitor(ast.NodeVisitor):
def通用_访问(自身、节点):
如果类型(节点)不在安全节点中:
引发异常(“%s”不在安全节点“%type(node))
超级(清除节点设备,自我)。一般访问(节点)
def访问呼叫(自我,呼叫):
如果call.func.id不在SAFE\u FX中:
引发异常(“未知函数:%s”%call.func.id)
定义我的安全评估:
tree=ast.parse(s,mode='eval')
cnv=清洁节点设备()
cnv.参观(树)
编译=编译(树,s,“eval”)
返回(评估(已编译、安全)
因此,
my_safe_eval('2*(4+exp(1.3))
有效,而
my_safe_eval('[].\uu class\uuuuuuu')
技巧和
my_safe_eval('open(“/something/evil”)
同样被禁止——但不禁止
\uu内置的东西或
\uuuuuu本地的东西

我。。。我认为这是可行的。我疯了吗?

Zope有一个东西叫做,你可能想检查它,至少是为了验证你的方法或者可能重用他们的代码。它是可配置和可重用的

这里有一个类似的问题。

试试看,这似乎是你需要的东西。
除此之外,还有一条

RestrictedPython看起来很整洁,但伙计,它太大了。我真的希望只安全地支持python语法的一小部分,并且只支持计算表达式和有限的函数调用集。我不认为沙盒python是我真正想要的。不能完全说出原因。太好了,但是如何处理
而为True:例如pass
?我也在看,非常有兴趣听到人们的输入。您是否对代码进行了基准测试?你试过所有的漏洞了吗?看到有人这么做真是太激动了!无法利用asteval,因为它非常有限,并且在AST级别删除。我不得不放弃我的项目,因为它是有限的。我使用spydermonkey和pyv8。。但在两种不同语言之间的上下文切换中,这是一个过载。因此,我要么使用pypy,要么只是删除eval功能,用简单的解析器替换它们——这是最好的决定。大多数情况下,你不需要图灵完整性……这与这个非常相似,也可以看到这个:这只是另一个例子,因为我实际上就是同一个Nate Vack:)