gpt4 book ai didi

python - 在嵌入式 Python 中禁用内置模块导入

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:24 24 4
gpt4 key购买 nike

我在我的应用程序中嵌入了 Python 3.6,我想在脚本中禁用导入命令以防止用户导入任何 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 长期以来一直无法创建安全的沙箱(请参阅 How can I sandbox Python in pure Python? 作为起点,如果您愿意,可以深入研究旧的 python-dev discussion)。以下是我认为最适合您的两个选项。

预扫码

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

在您的案例中,您正在寻找的是任何 import 语句(简单),以及您关心的任何顶级变量(例如,在 a.b.ca 并且对于给定的 a 可能是 a.b)未被“批准”。这将使您能够在运行任何不干净的代码时失败。

这里的挑战是,即使是经过简单混淆的代码也会绕过您的检查。例如,这里有一些导入模块的方法,这些模块给定了 import 的基本扫描找不到的其他模块或全局变量。您可能希望限制直接访问 __builtins__globals、一些/大多数/所有带有 __double_underscores__ 的名称和某些类型的成员。在 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钩子(Hook)。 (免责声明:我是本 PEP 的作者。)有针对最新 3.7 的实现草案。和 3.6发布。

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

Programs/spython.c repo 中的文件是一个相当详尽的 C 审计示例,而从 Python 执行它看起来更像这样(取自 my talk 关于此 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 版本,而不是依赖于系统安装。但是,如果您的应用程序依赖于嵌入,通常这是一个好主意,因为这意味着您不必强制用户进入特定的系统配置。

关于python - 在嵌入式 Python 中禁用内置模块导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48992030/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com