我有两个关于Pysandbox的问题:
如何实现eval
的功能?我理解sandbox.execute()
相当于exec
,但我找不到任何内容,如果输入的代码是2 + 2
,那么它会返回4
,或者其他什么为此。
默认情况下,sandbox.execute()
将传入的环境设为只读 - 即如果我sandbox.execute('data.append(4)', locals={'data': [1, 2, 3]})
,则会发生错误。如何将传入的环境设为可读写?
答案 0 :(得分:1)
啊哈,我看到最后一个PySandbox版本(1.5)的行为与你描述的一样。我正在尝试使用git master分支。
对于问题1,我认为PySandbox 1.5没有任何简单的选择。该代码专门用于尝试禁止在沙箱内修改或传输任何状态。 sandbox.call(eval, CODE)
不是一个好的选择,因为你不能很容易地传入locals和globals命名空间(你可以试试,但是沙箱会代理它们,然后eval()会失败因为locals和globals必须是真正的决定)。而且我相信你希望能够在这里设置本地和全局。
问题2也不是直截了当的,出于类似的原因。这两个都可以在当前的git master分支上实现,但是这是不是因为bug或设计而导致的:)
所以这里是两个问题的解决方案,这些问题扩展了沙盒功能并使用了可能意味着私有接口的东西,但是仍然应该像沙盒一样安全:
from sandbox.proxy import proxy
from sandbox.sandbox_class import _call_exec
def proxyNamespace(d):
return dict((str(k), proxy(v)) for k, v in d.iteritems())
def wrapeval(codestr, globs, locs):
subglobs = proxyNamespace(globs)
sublocs = proxyNamespace(locs)
return eval(codestr, subglobs, sublocs)
def eval_in_sandbox(sandbox, codestr, globs=None, locs=None):
if globs is None:
globs = {}
if locs is None:
locs = globs
return sandbox._call(wrapeval, (codestr, locs, globs), {})
def exec_in_sandbox_with_mutable_namespace(sandbox, codestr, globs=None, locs=None):
if globs is None:
globs = {}
if locs is None:
locs = globs
subglobs = proxyNamespace(globs)
sublocs = proxyNamespace(locs)
sandbox._call(_call_exec, (codestr, subglobs, sublocs), {})
globs.update(subglobs)
locs.update(sublocs)
现在,所有这一切,我强烈建议 not 基于此PySandbox模块上任何实际生产代码或系统的安全性。在查看代码时,似乎它完全充满了漏洞和漏洞。我认为攻击者不会花费超过一个小时的时间才能找到超越这种安全性的方法。我也不认为这已经过安全专业人员,甚至整个社区的很大一部分的任何认真审查。如果你想运行不受信任的代码并且它根本无法影响你的进程,你需要更强大的东西,可能是基于AppArmor或类似的东西。如果你只是担心意外行为不端的代码,而不是恶意代码,这可能没问题,但我实际上并不确定。
答案 1 :(得分:0)
问题1:
sandbox.call(eval, "2+2")
问题2:
from sandbox import Sandbox, SandboxConfig
cfg=SandboxConfig('stdout')
import sys
out1 = sys.stdout
err1 = sys.stderr
with open("logfile.txt", "w") as f:
sys.stdout = sys.stderr = f
sandbox = Sandbox(cfg)
indata={'data': [1, 2, 3]}
sandbox.execute('a=list(data);a.append(4); print(str(a))', locals=indata)
sys.stdout = out1
sys.stderr = err1
with open("logfile.txt", "r") as f:
indata=eval(f.read())
print indata
关于问题2的一些评论,很难得到一个Readable-Writebale对象并让它同时从外面看到。我想看看一些更聪明的方法。
<强>输出:强>
$ python test.py
[1, 2, 3, 4]