- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我在我的应用程序中嵌入了 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.c
中 a
并且对于给定的 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/
当我这样做时... import numpy as np ...我可以使用它但是... import pprint as pp ...不能,因为我需要这样做... from pprint import
我第一次尝试将 OpenCV 用于 Python 3。要安装,我只需在终端中输入“pip3 install opencv-python”。当我这样做时,我在 Finder(我在 Mac 上)中看到,在
如果有一个库我将使用至少两种方法,那么以下之间在性能或内存使用方面是否有任何差异? from X import method1, method2 和 import X 最佳答案 有区别,因为在 imp
我正在从 lodash 导入一些函数,我的同事告诉我,单独导入每个函数比将它们作为一个组导入更好。 当前方法: import {fn1, fn2, fn3} from 'lodash'; 首选方法:
之间有什么关系: import WSDL 中的元素 -和- import元素和在 XML Schema ...尤其是 location 之间的关系前者和 schemaLocation 的属性后者的属性
我在从 'theano.configdefaults' 导入 'local_bitwidth' 时遇到问题。并显示以下消息: ImportError
我注意到 React 可以这样导入: import * as React from 'react'; ...或者像这样: import React from 'react'; 第一个导入 react
对于当前的项目,我必须使用矩阵中提供的信息并对其进行数学计算,以及使用 ITK/VTK 函数来显示医疗信息/渲染。基本上我必须以(我猜)50/50 的方式同时使用 matlab 例程和 VTK/ITK
当我看到 pysqlite 的示例时,SQLite 库有两个用例。 from sqlite3 import dbapi2 as sqlite3 和 import sqlite3 为什么有两种方式支持s
我使用 Anaconda Python 发行版:Python 2.7 x64 和 Windows 7 SP1 x64 Ultimate。 当我import matplotlib.pyplot时,我得到
目录 【容器】镜像导出/导入 导出 导入 带标签 不带标签,后期修改 【仓库】镜像导出/导入
我正在寻找一种导入模块的方法,以便我可以从子文件夹 project/v0 和根文件夹 project 运行脚本。/p> 我在 python 3.6 中的文件结构(这就是没有初始化文件的原因) proj
我通常被告知以下是不好的做法。 from module import * 主要原因(或者有人告诉我)是,您可能会导入一些您不想要的东西,并且它可能会隐藏另一个模块中具有类似名称的函数或类。 但是,Py
我为 urllib (python3) 编写了一个小包装器。在if中导入模块是否正确且安全? if self.response_encoding == 'gzip': import gzip
我正在 pimcore 中创建一个新站点。有没有办法导出/导入 pimcore 站点的完整数据,以便我可以导出 xml/csv 格式的 pimcore 数据进行必要的更改,然后将其导入回来? 最佳答案
在 Node JS 中测试以下模块布局,看起来本地导出的定义总是在名称冲突的情况下替换外部导出的定义(参见 B.js 中的 f1)。 A.js export const f1 = 'A' B.js e
我在使用 VBA 代码时遇到了一些问题,该代码应该将 excel 数据导入我的 Access 数据库。当我运行代码时,我收到一个运行时错误“运行时错误 438 对象不支持此属性或方法”。来自我在其他论
我有一个名为 elements 的包,其中包含按钮、trifader、海报等内容。在 Button 类中,我正在执行 from elements import * 这执行正常,当我尝试 print(p
在我长期使用 python 的经验中,我遇到了一个非常奇怪的问题。 提前我想说我想知道为什么会发生这种情况 ,而不是如何更改我的代码或如何修复它,因为我也可以做到。 我正在使用 python2.7.3
我正在更新我的包。但是,我正在为依赖项/导入而苦苦挣扎。我使用了两个冲突的包 - ggplot2和 psych及其功能 alpha当然还有 alpha ggplot2 的对象不同于 alpha psy
我是一名优秀的程序员,十分优秀!