2

想请教几个有关 py3 的 exec、字节码和代码对象的问题

 3 years ago
source link: https://www.v2ex.com/t/792987
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Python

想请教几个有关 py3 的 exec、字节码和代码对象的问题

  O5oz6z3 · 12 小时 12 分钟前 · 455 次点击
一个低水平小白的几个无关痛痒的困惑,如果有人能帮忙指明搜索方向也非常感谢。任何其他意见也欢迎。

1. `exec` 命令从 python2 中的语句变成 python3 的内置函数,是出于什么原因?在哪里能找到相关的说明?安全是不是因素之一?

2. 在 python3 中怎么把 字节码(bytecode) 转换为可执行的 代码对象(coed object)?
不知道是表达和理解是否有误,具体来说,代码对象指的是 `function.__code__`,字节码指的是 `function.__code__.co_code`。可以把 `co_code` 转换回 `__code__` 吗?

3. 在 python3 中调用 `` 内置函数时,在清空了参数 `globals={…}` 中 `__builtins__` 变量的情况下,还可能有什么其他的安全隐患?不包括死循环和递归溢出等人为疏忽。

4. X-Y 问题:最初的想法是,在 python3 中能否实现一个简单的隔离沙箱运行环境给第三方脚本运行?比如 问题 3. 中提到的方法是否在一定程度上足够安全?

第 1 条附言  ·  9 小时 2 分钟前

订正一下问题描述,之前不知道触发了什么发不出来。
[不知道(是)表达和理解是否有误] => [不知道表达和理解是否有误]
[3. 在 python3 中调用 (``) 内置函数时] => [3. 在 python3 中调用 exec 内置函数时]
8 条回复    2021-08-01 22:27:12 +08:00

hsfzxjy

hsfzxjy   9 小时 58 分钟前 via Android   ❤️ 1

1. 是易用性问题。函数可以作为表达式一部分,语句不行。

2. 使用 types.CodeType

3. 不安全,可以用内置对象构建任意函数 https://www.floyd.ch/?p=584

4. 建议用 docker 容器

ysc3839

ysc3839   9 小时 23 分钟前 via Android

关于 Python 的沙盒,我个人猜测 CPython 解释器本身应该是安全的,问题出在众多库函数。比如 open 什么的内置函数都没做限制,要一个个加上限制的话太麻烦,且很容易遗漏。

O5oz6z3

O5oz6z3   7 小时 16 分钟前

@hsfzxjy 谢谢!
>1. 原来如此,我之前以为在 python3 中 exec 作为内置函数,可以通过覆盖 __builtins__ 来屏蔽掉,但是在 python2 中作为语句的 exec 就没办法屏蔽了,所以改成内置函数会安全些。

>2. 我去看看

>4. 明白了。不过这就已经超出 python 解释器的层面了,最初是想在脚本层面简单实现一个粗糙的隔离环境给 exec 运行。

不看不知道,一看吓一跳,这 __builtins__ 在很多标准库模块里都能获取到,泄露成筛子似的,看来确实很难在脚本层面实现简陋的沙箱。
罪魁祸首看来是 __subclasses__,也许可以归结于 python 本来就不注重属性的访问限制? python 在自省和透明的路上真是越走越远。

O5oz6z3

O5oz6z3   7 小时 13 分钟前

@hsfzxjy
>3. “构建任意函数”听上去似乎没有安全问题,因为在 exec 里面执行的代码字符串本来就可以随意定义函数,这个“任意函数”好像没有什么特别。
如果我没理解错的话,只是构造不正确的字节码让解释器崩溃,那么效果上似乎和递归溢出没有区别。

hsfzxjy

hsfzxjy   7 小时 11 分钟前 via Android

@O5oz6z3 我的意思是可以访问到原先的 builtins,这就很危险了

O5oz6z3

O5oz6z3   6 小时 59 分钟前

@ysc3839 确实,虽然可以通过替换覆盖 __builtins__ 模块内的内置函数来添加限制,但除了 __import__ 和 open 我也想不到哪里会不安全,的确又麻烦又容易遗漏。
用这个思路做沙盒确实很麻烦,可能方向不对,又或者是 python 在设计上本来就不打算支持沙盒功能。

O5oz6z3

O5oz6z3   6 小时 46 分钟前

@hsfzxjy #5
“可以通过内置对象访问到原先的 builtins”,回过头来发现,exec 本质上就是在当前解释器环境解释执行代码,复用了当前环境的内置对象,那么能够通过自省访问到原先的 builtins 也就不奇怪了。看来想简单地用 exec 来实现沙盒不太可行。

no1xsyzy

no1xsyzy   4 小时 42 分钟前

沙箱最大的问题就是,插件作者调用第三方库不一定预设了你是沙箱内的,可能去访问一些不允许访问的资源。
所以沙箱要么是 deno 这种处于解释器-操作系统边界的,要么是纯函数的。
话说如果自己愿意写的话用 ast 模块重新写一个解释器也行。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK