一个可以安全执行的Python线代码的简单解析器

safe-parser的Python项目详细描述


安全解析器

python的标准库提供了一个函数ast.literal_eval,它可以安全地计算python文本(如列表或字符串)的字符串表示。这允许一个解析,例如,'["string", {}, 12.34]'和其他这样的安全文本。

这个包提供了一个改进的想法。

安全解析器是一个对象,它可以获取包含赋值的有效python代码的字符串,并生成结果where环境字典的字典。因此,它允许解析和执行以下操作:

a=['a','list']b={'content':a}

它被解析为以下内容:

{'a':['a','list'],'b':{'content':['a','list']}}

解析器还允许执行函数,只要它知道它们可以安全地执行。例如,如果存在函数

defrepeat(x,n):return[x]*n

然后解析器可以将字符串a = repeat('x', 3)解析为:

{'a':['x','x','x']}

安全性是有保证的,因为解析器知道哪些函数可以通过使用插件系统安全地执行。所有解析器都包含一个(最初为空)插件存储,可用于注册新插件:

fromsafeparserimportParserparser=Parser()@parser.plugin_store.registerdefrepeat(x,n):return[x]*nparser.parse('a = repeat("x", 3)')print(parser.env)# output: {'a': ['x', 'x', 'x']}

动机

这个包提供的解析器最重要的是能够以安全和可控的方式运行用户输入。python作为一种通用编程语言,可以“执行任何事情”,因此不适合用户输入。然而,在某些情况下,系统非常复杂,用户可能需要与第三方进行更明确的对话。

这个包的主要目标是充当系统的用户输入处理器,该系统允许用户请求服务器调用具有一系列输入值的函数。例如,用户可能对所提供的一组实体中的任何一对之间的相似性感兴趣。因此,用户需要提供实体和对。对于n复杂实体,这意味着提供on2)对,这可能是不切实际的。如果系统知道如何创建对本身,那么用户只需要提供实体。

什么是安全的?

就这个包而言,safe语句是一个一旦执行,除了在字典中创建或编辑变量(或多个变量)之外,不会产生任何可见的副作用的语句。

功能

  • 解析器可以解析字符串和文件对象。以下两项有效
parser.parse('a = 1')withopen('filename.txt')asf:parser.parse(f)
  • 一个解析器可以解析多个输入,每个输入都建立在前面的dictionray的基础上
parser.parse('a = 1')parser.parse('b = 2')print(parser.env)# output: {'a': 1, 'b': 2}
    可以用现有环境启动解析器
parser=Parser(env={'a':1})parser.parse('b = a')print(parser.env)# output: {'a': 1, 'b': 1}
  • 插件可以使用decorator或方法注册。以下是等效的
@parser.plugin_store.registerdefadd(a,b):returna+bdefadd(a,b):returna+bparser.plugin_store.add(add)
  • 插件可以直接访问正在构建的环境,并可以更改它
@parser.plugin_store.registerdefnew_variable(*,env):env['var']=0

为此,插件函数必须有一个名为env的非可选仅关键字参数。请注意,环境不是python字典,但它的行为与python字典类似,只是它不允许使用双下划线变量(请参见下面的限制),并且方法keys()values()没有实现。

限制

  • 由于代码是如何工作的,而且也不妨碍将来的开发,所以不允许使用双下划线变量名。一方面,这样我们可以安全地将空的__builtins__注入到代码的计算中,同时允许将当前环境的状态注入到请求它的插件中(见上文)。

  • 目前,我不允许除了调用和文字以外的表达式。这意味着输入不允许binray操作,例如,与ast.literal_eval函数不同。

  • 无法执行方法。不可能执行

l=[]l.append(0)

即使从上面的定义来看这是安全的

  • 注意,插件只有在cod他们被处决是安全的。但是,由于解析器本身控制它支持的插件,因此执行不安全的用户提供的代码的想法仍然是不可能的。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java Getting“类型不匹配:在实例化映射列表时,无法将ArrayList<HashMap<String,String>>转换为List<Map<String,String>>”   java如何将ArrayList传输到安卓中的其他活动?   使用bouncy castle作为加密提供程序和GCM、cipherOutputStream时使用java。close()似乎没有抛出invalidCipherTextException   将自定义库导出到可导入jar文件java   java如何在队列中使用异常   JAVA木卫一。FileNotFoundException。正在尝试传入参数[0]   java使用自定义构造函数将JsonNode转换为POJO   由于无限循环,java Netbeans自动生成的GUI未显示。。。但我需要那个环   运行时从另一个Java cosole应用程序运行Java控制台应用程序   java在安卓中播放彩信wmv视频   web服务在Java中创建和发送SOAP消息   ReactJS&Java:对飞行前请求的响应未通过访问控制检查   java如何在安卓中使用PRDownloader恢复下载文件?   java为什么openFd(文件名)不能使用字符串?