繁体   English   中英

禁用嵌入式Python中的内置模块导入

[英]Disable built-in module import in embedded Python

我在我的应用程序中嵌入了Python 3.6,我想在脚本中禁用import命令以防止用户导入任何python内置库。 我只想使用语言本身和我自己的C ++定义模块。

Py_SetProgramName (L"Example");
Py_Initialize ();
PyObject* mainModule = PyImport_AddModule ("__main__");
PyObject* globals = PyModule_GetDict (mainModule);

// This should work
std::string script1 = "print ('example')";
PyRun_String (script1.c_str (), Py_file_input, globals, nullptr);

// This should not work
std::string script2 = "import random\n"
                      "print (random.randint (1, 10))\n";
PyRun_String (script2.c_str (), Py_file_input, globals, nullptr);

Py_Finalize ();

你知道怎么做到这一点吗?

Python有很长的历史,无法创建一个安全的沙箱(请参阅我如何在纯Python中沙盒Python?作为起点,然后深入探讨旧的python-dev讨论,如果您愿意的话)。 以下是我认为最好的两种选择。

预扫描代码

在执行任何操作之前,请扫描代码。 您可以使用AST模块在Python中执行此操作,然后遍历树,或者可以通过更简单的文本搜索获得足够的效果。 这可能适用于您的场景,因为您具有受限的用例 - 它不会推广到真正任意的代码。

在您的情况下,您正在寻找的是任何import语句(简单),以及任何顶级变量(例如,在abc您关心某个给定a a和可能的ab )并非“已批准”。 这将使您在运行之前对任何不干净的代码失败。

这里的挑战是即使是模糊的代码也会绕过你的检查。 例如,以下是一些导入模块的方法,这些模块给定了import的基本扫描找不到的其他模块或全局变量。 您可能希望使用__double_underscores__和某些类型的成员限制对__builtins__ __double_underscores__globals ,某些/大多数/所有名称的直接访问。 在AST中,这些将不可避免地显示为顶级变量读取或属性访问。

getattr(__builtins__, '__imp'+'ort__')('other_module')

globals()['__imp'+'ort__']('other_module')

module.__loader__.__class__(
    "other_module",
    module.__loader__.path + '/../other_module.py'
).load_module()

(我希望有点不用说,这是一个不可能的挑战,为什么这种沙盒方法从未完全成功。但它可能已经足够好了,具体取决于您的特定威胁模型。)

运行时审核

如果您可以编译自己的Python运行时,可以考虑使用(当前草案) PEP 551钩子。 (免责声明:我是本PEP的作者。)针对最新的3.73.6版本提供了草案实施。

实质上,这将允许您为Python中的一系列事件添加钩子并确定如何响应。 例如,您可以监听所有import事件,并根据要导入的模块确定是在运行时允许还是失败,或者监听compile事件以管理所有运行时编译。 您可以使用Python代码(使用sys.addaudithook )或C代码(使用PySys_AddAuditHook )执行此操作。

repo中的Programs / spython.c文件是一个相当彻底的C审计示例,而从Python执行它看起来更像是这样(取自对此PEP的讨论):

import sys

def prevent_bitly(event, args):
    if event == 'urllib.Request' and '://bit.ly/' in args[0]:
        print(f'WARNING: urlopen({args[0]}) blocked')
        raise RuntimeError('access to bit.ly is not allowed')

sys.addaudithook(prevent_bitly)

这种方法的缺点是您需要构建和分发自己的Python版本,而不是依赖于系统安装。 但是,一般来说,如果您的应用程序依赖于嵌入,这是一个好主意,因为这意味着您不必强制用户进入特定的系统配置。

暂无
暂无

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

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