可以将Python配置文件沙箱化吗?

1 投票
2 回答
1159 浏览
提问于 2025-04-15 16:08

我在考虑实现一个用Python语法写的配置文件,类似于Django的做法。

我看到过一些关于在配置文件中使用可执行代码的优缺点的讨论,但我想知道有没有办法在一个“沙箱”环境中执行这些配置文件的代码,这样可以避免代码中的错误导致主应用程序崩溃。

因为这个主应用程序是一个程序员的工具,所以我不担心教人Python语法或者引入安全漏洞的问题。不过,我确实担心配置代码可能会出现问题,导致主应用程序卡住。我更希望主应用程序能捕捉到这些问题,并显示出错误信息。

有没有人尝试过为Python配置文件做这种沙箱处理?如果有的话,哪些方法有效,哪些陷阱是我需要注意的?

2 个回答

2

很遗憾,使用标准的Python,你对这个问题能做的事情不多。当Python解释器在运行“配置代码”时,这段代码可以做任何事情,包括访问主程序或者不返回控制权。把配置代码放在一个单独的进程中运行可能会有所帮助,但这也会限制主程序和配置代码之间的互动。

你可以看看PyPy项目的沙箱功能。这可能正是你需要的,但也可能需要你花不少功夫来整合。

有没有替代rexec的Python沙箱方案?也讨论了这个话题。

你可能还需要问问自己,这个问题对你来说到底有多重要。我想这取决于你的使用场景,以及谁来编写配置代码。

3

我们这样做是为了我们的一些内部工具。

这样做可以保护我们免受异常问题的影响,并且不鼓励用户在配置脚本中进行过于创意的尝试。不过,这并不能防止无限循环或恶意第三方的攻击。

这个方法的核心是把脚本放在一个受限制的环境中执行。

  1. 首先,我们会查看 __ builtin __ 模块,删除所有我们不希望他们接触的东西,尤其是 __ import __。我们实际上是在一个上下文管理器中进行这个操作,它会在进入时备份原始值并删除它们,然后在退出时恢复原始值。

  2. 接下来,我们创建一个空字典,作为配置脚本的命名空间。

  3. 然后,我们在这个命名空间中执行配置脚本。

  4. 执行的过程当然是放在一个 try except 语句中,以捕捉任何可能出现的问题。

  5. 最后,我们检查命名空间,提取我们感兴趣的变量。

需要注意的几点:

  1. 虽然可能会想要在命名空间中预先填充一些对配置脚本有用的内容,但这样做要非常小心,因为这可能会让用户重新连接到主程序。

  2. 配置脚本仍然可以创建函数和类,所以你可能会得到一些看起来像字符串的东西,但实际上它可能是任意的可执行代码。

因此,我们规定配置脚本应该只产生纯粹的基本数据结构(通常是整数、字符串、列表、元组和 None),然后我们会单独验证这些数据。

撰写回答