繁体   English   中英

Python:使用 sympy.sympify 对数学函数执行安全的 eval()

[英]Python: Using sympy.sympify to perform a safe eval() on mathematical functions

我正在编写一个程序,用户需要能够使用自己编写的数学函数,其中包含来自 numpy 和 scipy 的函数,例如。 scipy.special.wofz()

这些函数将存储在文件中,并由程序作为字符串导入。 我环顾四周,发现eval()exec()不是安全的方法。 例如。 在这里

安全问题是好用户从可以访问好用户系统的恶意用户加载文件。

我正在考虑做这样的事情:

#!/bin/python
from scipy.special import *
from numpy import *
import sympy

# Define variable a
vars = {"a":1}
# This is the string I get from a file
string = "wofz(a)"

parsed_string = sympy.sympify(string)
parsed_string.evalf(subs=vars)

但是,这不起作用。 它只返回:

wofz(a)

wofz(a) 未被评估。 这甚至应该那样工作吗?

我有另一个想法:所以我想,一旦这个数学 function 通过 sympify,它应该是安全的。 我可以简单地做这样的事情:

globals = {wofz:wofz}
eval(str(parsed_string), vars, globals)

工作正常并返回:

(0.36787944117144233+0.60715770584139372j)

那安全吗? 我知道这不好。

请帮忙。

使用 sympy,这是一种更安全的选择。

import sympy
from sympy.core.function import Function
from sympy.core import S
from sympy import sympify
from sympy.functions import im
from scipy.special import wofz

class Wofz(Function):
    is_real = True
    @classmethod
    def _should_evalf(csl,arg):
        return True
    def as_base_exp(cls):
        return cls,S.One

    def _eval_evalf(cls, prec):
        return sympy.numbers.Number(im(wofz(float(cls.args[0]))))

print sympify("Wofz(2)",{'Wofz':Wofz}).evalf()

Output(你必须以某种方式处理虚部):

0.340026217066065

如果字符串是唯一不受信任的信息,我认为以下应该是安全的:

要将eval()用于受限词汇,请将第二个参数传递给它,该参数是允许名称的字典,其中__builtins__被定义为无害的东西(参见http://docs.python.org/library/functions.html#eval ) .

>>> import numpy as np
>>> d = dict(linspace=np.linspace, range=range, __builtins__=None)
>>> eval("str(1), 2+2")
('1', 4)
>>> eval("str(1)", d)
Traceback (most recent call last)
NameError: name 'str' is not defined

>>> eval("{'a': linspace(0, 0.5, 6)}, range(2)", d)
({'a': array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5])}, [0, 1])
>>> eval("linspace.__dict__", d)
Traceback (most recent call last)
RuntimeError: function attributes not accessible in restricted mode

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM