3

Pysandbox に関して 2 つの質問があります。

  1. の機能を実現するにはどうすればよいevalですか? sandbox.execute()が と同等であることは理解していますが、入力されたコードがである場合に が返されるexecようなものは見つかりませんでした。2 + 24

  2. デフォルトでsandbox.execute()は、渡された環境を読み取り専用にします。つまり、そうするとsandbox.execute('data.append(4)', locals={'data': [1, 2, 3]})、エラーが発生します。渡された環境を読み書き可能にするにはどうすればよいですか?

4

2 に答える 2

1

ああ、最後の PySandbox リリース (1.5) は、あなたが説明したように動作するようです。私はgit masterブランチを試していました。

質問 1 については、PySandbox 1.5 には簡単なオプションはないと思います。このコードは、サンドボックス内での状態の変更または送信を許可しないように特別に記述されています。sandbox.call(eval, CODE)ローカルとグローバルの名前空間を簡単に渡すことができないため、良いオプションではありません (試すことはできますが、サンドボックスがそれらをプロキシし、ローカルとグローバルは実際の辞書でなければならないため、eval() は失敗します)。そして、ここでローカルとグローバルを設定できるようにしたいと考えています。

同様の理由で、質問 2 も簡単ではありません。これらはどちらも現在の git master ブランチで可能ですが、それがバグによるものなのか設計によるものなのかは明らかではありません:)

したがって、サンドボックス機能を拡張し、おそらくプライベート インターフェイスを意図したものを使用する両方の質問に対する解決策を次に示しますが、サンドボックスがそうでない場合と同じくらい安全である必要があります。

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)

とはいえ、実際の製品コードやシステムの安全性をこの PySandbox モジュールに基づいて構築しないことを強くお勧めします。コードを見てみると、欠陥や穴だらけのようです。攻撃者がこの種のセキュリティを突破する方法を見つけるのに 1 時間ほどかかるとは思いません。また、これがセキュリティの専門家や、コミュニティ全体の大部分による真剣なレビューを受けていないとも思います。信頼できないコードを実行したいが、それがプロセスにまったく影響を与えないようにする場合は、おそらく AppArmor などに基づいた、より強力な何かが必要です。悪意のあるコードとは対照的に、コードの誤った動作のみを心配している場合は、これで問題ないかもしれませんが、実際にはそれについてもわかりません。

于 2012-05-09T22:23:43.330 に答える
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]
于 2012-05-09T05:42:24.323 に答える