安全的Python3沙箱——eval
Posted | stdout
很早之前从 reddit 看到过有人吹
eval(expr.replace('__', ''), {'__builtins__': None}, {})
这个写法其实很安全,当年没人能攻破沙箱。我这个水平肯定是不肯能了,现在有AI了,让 opus-4.6-thinking 试了下
The classic escape chain needs object.__subclasses__() → find a class with __init__.__globals__['os'] → os.system(). Every step past info disclosure is blocked:
| Vector | Why it fails |
|---|---|
str.format() calling methods |
Format only does attribute/index access, never calls () |
getattr(obj, runtime_str) |
getattr is a builtin → None |
gi_frame.f_back (generator frame escape) |
f_back is None when generator is suspended |
NFKC unicode (__class__) |
SyntaxError: U+FF3F is not valid in identifiers |
replace nesting (____) |
Single-pass left-to-right, can never produce __ |
Type name access (tuple, type) |
All type names are builtins → None |
[].sort(key=lambda) calling out |
Key gets called, but nothing useful to call with |
不过看它的尝试过程还是挺有意思的。我学习到
a = (x for x in [1,2])); a.gi_frame.f_builtins"
这个居然可以拿到所有内置方法,这语法设计也太奇怪了。不过这条路是走不通的,因为 __builtins__ 是 None。
AI 很厉害的一点,超级接近成功了,它找到了突破双下划线的方法,用 str.format()
('{0._' + '_class_' + '_}').format(())
但是这个只能拿来读到 attributes,并不能调用。
不知道我的设定是不是有问题,ChatGPT虽然也失败了,但是还是嘴犟,说我可以[0]*1e1000 搞爆你内存,所以你那玩意仍然不安全 🤣 sama家的真是打死不认输
Comments