能否通过exec()修改Python受控函数中的变量x?
能否绕过
controlled_exec的限制将x设为任意值? 先看原函数实现,它试图通过限制exec的全局和局部作用域,只暴露increment_x函数来统计调用次数:
def controlled_exec(code): x = 0 def increment_x(): nonlocal x x += 1 globals = {"__builtins__": {}} # 移除所有全局对象(包括Python内置函数) locals = {"increment_x": increment_x} # 仅暴露increment函数 exec(code, globals, locals) return x
测试用例中调用两次increment_x()会返回2,符合预期,但这个实现存在明显的安全漏洞——完全可以直接修改x为任意值,不需要调用increment_x。
具体实现方法
核心是利用Python闭包函数的__closure__属性,直接访问并修改闭包内的x变量:
# 执行后返回-100 controlled_exec(""" # 获取increment_x闭包中存储x的cell对象 x_cell = increment_x.__closure__[0] # 直接修改cell的内容为任意值 x_cell.cell_contents = -100 """)
原理说明
increment_x是一个闭包函数,它的__closure__属性会返回一个元组,里面包含了所有闭包引用的变量(这里只有x对应的cell对象)。- cell对象的
cell_contents属性是可读写的,直接修改这个属性就能改变原函数中x的值,完全绕过了increment_x的限制。 - 原代码只清空了全局作用域,但没有限制传入的
increment_x本身的属性访问,而Python默认允许访问函数的这些内部属性,导致了这个漏洞。
内容的提问来源于stack exchange,提问作者Bix
相关产品推荐
相关产品推荐

