这是一个Python的问题.

请考虑下面的Python代码:

def controlled_exec(code):
  x = 0
  def increment_x():
    nonlocal x
    x += 1

  globals = {"__builtins__": {}} # remove every global (including all python builtins)
  locals = {"increment_x": increment_x} # expose only the increment function

  exec(code, globals, locals)

  return x

我希望这个函数提供一个受控代码API,它只计算increment_x()次调用的数量.我试过了,我得到了正确的行为.

# returns 2
controlled_exec("""\
increment_x()
increment_x()
""")

我认为这种做法不安全,但出于好奇心,我想知道.我可以通过controlled_exec(...)执行代码,将x设置为任意值(比如负值)吗?我该怎么做呢?

推荐答案

可以,通过controlled_exec执行的代码可以将x设置为任意值.

请考虑以下演示:

def controlled_exec(code):
  x = 0
  def increment_x():
    nonlocal x
    x += 1
    print(f"{x=}")

  globals = {"__builtins__": {}} # remove every global (including all python builtins)
  locals = {"increment_x": increment_x} # expose only the increment function

  exec(code, globals, locals)

  return x


controlled_exec("""\
increment_x()
increment_x.__closure__[0].cell_contents = -100
increment_x()
""")

这将输出

x=1
x=-99

这真的不是"确保"exec的方法.无论您做什么,最终您都在执行任意的Python代码,它与您编写的代码一样可以自由地访问和修改Python解释器的状态.

要强调保护exec的安全是多么困难,请注意,尽管您试图对执行的代码隐藏内建,但攻击者仍然可以通过

increment_x.__globals__['__builtins__']

这只是试图利用此功能的人可能使用的数十个技巧之一.

我们可以修改变量x这一事实确实是一个平淡无奇的例子.从字面上讲,没有什么能阻止传递给controlled_exec的代码做更灾难性的事情,比如擦除硬盘或下载恶意软件.

Python相关问答推荐

预期LP_c_Short实例而不是_ctyles.PyCStructType

使用Python Cerberus初始化一个循环数据 struct (例如树)(v1.3.5)

Pandas :多索引组

从webhook中的短代码(而不是电话号码)接收Twilio消息

try 与gemini-pro进行多轮聊天时出错

由于NEP 50,向uint 8添加-256的代码是否会在numpy 2中失败?

如何在Python中将returns.context. DeliverresContext与Deliverc函数一起使用?

在Google Colab中设置Llama-2出现问题-加载判断点碎片时Cell-run失败

沿着数组中的轴计算真实条目

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

如何启动下载并在不击中磁盘的情况下呈现响应?

如何从需要点击/切换的网页中提取表格?

在嵌套span下的span中擦除信息

Pandas Data Wrangling/Dataframe Assignment

如何在两列上groupBy,并使用pyspark计算每个分组列的平均总价值

Odoo16:模板中使用的docs变量在哪里定义?

并行编程:同步进程

Pandas—堆栈多索引头,但不包括第一列

从源代码显示不同的输出(机器学习)(Python)

Tensorflow tokenizer问题.num_words到底做了什么?