Python安全沙箱RestrictedPython 设计理念

RestrictedPython 设计理念

Python 是一种图灵完备的编程语言。在 Web 上下文中为用户提供 Python 接口是一种潜在的安全风险。Web 框架和内容管理系统 (CMS) 希望通过 Web (TTW) 为其用户提供尽可能多的可扩展性,这也意味着用户有权通过 Python 脚本添加功能。

抛开 RestrictedPython 不谈,根据信息安全最佳实践,应该采取额外的预防措施来确保应用程序和服务器本身的完整性。

RestrictedPython 定义了 Python 编程语言的一个安全子集,这是增强语言安全性的一种常用做法,比如Ada的Ravenscar profile 就是这种做法的另一个例子。

定义语言的安全子集涉及限制EBNF元素,还有要显示允许或禁止某些语言特性。编程语言的大部分功能来自其标准库和其它库,因此任何对这些方法的调用都必须检查并可能需要进行限制。RestrictedPython 通常不允许调用任何未明确列入白名单的库。

由于 Python 是一种由解释器执行的脚本语言,因此在解释器执行生成的字节码之前,任何要执行的 Python 代码都必须进行显示地检查。

Python 提供了完成该流程的三种方法:

  • compile() 将源代码编译为字节码

  • exec/exec()在解释器中执行字节码

  • eval/eval()执行字节码表达式

因此 RestrictedPython 提供了 python 内置的compile()函数(Python 2 / Python 3)的替代函数,该Python内置函数定义如下:

compile(source, filename, mode [, flags [, dont_inherit]])

compile()函数的定义随着版本不同而不同,但其相关参数sourcemode一直存在。

有三个有效的字符串值mode

  • 'exec'

  • 'eval'

  • 'single'

对于 RestrictedPython,此compile()函数被替换为:

RestrictedPython.compile_restricted(source, filename, mode [, flags [, dont_inherit]])

主要参数source必须是字符串或是ast.AST的实例。这两个方法都会返回已编译好的解释器可以执行的字节码,如果源代码无效则会抛出异常。

由于compilecompile_restricted仅仅是将源码编译为字节码,因此代码仍然可以调用库文件,所以这作为沙箱来说仍然是不够的。

注意到,下面的两个方法/语句:

  • exec / exec()

  • eval / eval()

有两个参数:

  • globals

  • locals

它们是对 Python 内置函数的引用。

因此通过修改和限制globalslocals中可用的模块、方法和常量,我们就可以限制可能的调用。

此外,RestrictedPython 还提供了定义属性保护策略的能力,该策略允许开发人员保护对属性的访问。这通过定义以下函数的限制版本来实现:

  • print

  • getattr

  • setattr

  • import

RestrictedPython 还提供了 Python 的三个预定义的受限__builtins__

  • safe_builtins (在 Guards.py 中提供)

  • limited_builtins (在 Limits.py 中提供),它提供了受限的序列类型

  • utilities_builtins (在 Utilities.py 中提供),它提供对标准模块数学、随机、字符串和集合的访问。

一个快捷设置:

  • safe_globals(在 Guards.py 中提供)相当于{'__builtins__': safe_builtins}

此外,还有一些保护函数可以使 Python 对象的属性不可变: full_write_guard(写和删除受保护)。

posted @ 2021-07-19 20:13  鸪斑兔  阅读(1273)  评论(0编辑  收藏  举报