信頼できないコードの実行のベストプラクティス


31

私は、ユーザーがサーバーに対して任意の信頼できないpythonコード(このようなビット)を実行できるようにする必要があるプロジェクトを持っています。私はpythonにかなり慣れていないため、システムにセキュリティホールやその他の脆弱性を招くようなミスを避けたいと思います。利用可能なベストプラクティス、推奨される読書、または私のサービスを使用可能にするが悪用できないようにする他のポインターはありますか?

これまで私が考えてきたことは次のとおりです。

  • コンテキストから削除__builtins__して、execなどの潜在的に危険なパッケージの使用を禁止しますos。ユーザーは、私が提供したパッケージのみを使用できます。
  • スレッドを使用して、適切なタイムアウトを強制します。
  • execコンテキスト内で割り当てることができるメモリの総量を制限したいのですが、それが可能かどうかはわかりません。

ストレートexecに代わるものがいくつかありますが、ここでどれが役立つかわかりません:

  • を使用して、ast.NodeVisitor安全でないオブジェクトにアクセスする試みをキャッチします。しかし、どのオブジェクトを禁止する必要がありますか?
  • 入力内の二重アンダースコアを検索します。(上記のオプションよりも優雅ではありません)。
  • PyPyコードのサンドボックスを使用するか、サンドボックスに似たもの。

注: JavaScriptベースのインタープリターが少なくとも1つあることは承知しています。私のシナリオではうまくいきません。



3
@MartijnPieters:すばらしい。それぞれを要約すると、おそらく答えに値します。
ロバートハーベイ

また、ディスクに残っているゴミ、ネットワーク(スパムなどを送信させない)、他のファイルへのアクセス許可(ファイルの読み取り)も考慮してください。whileループで取り出すことでもCDの仕組みを破壊する可能性があります。独自のプログラムを活用するために、適切で適切なメモリ量を設定してください。
kyticka


1
PyPyを試す:>サンドボックス:PyPyは、信頼できないコードを完全に安全な方法で実行する機能を提供します。
ヴォラック

回答:


28

Pythonのサンドボックス化は困難です。Pythonは複数のレベルで本質的に内観的です。

これは、特定の型のファクトリメソッドをそれらの型自体から見つけて、構築できることも意味します 、インタープリターによって制限なしで直接実行される新しい低レベルオブジェクト。

Pythonのサンドボックスから抜け出すための創造的な方法を見つける例を次に示します。

基本的な考え方は、基本的なPython型を作成する方法を常に見つけることです。Pythonインタプリタに任意の(チェックされていない!)バイトコードを実行させることにより、関数とクラスを作成し、シェルから抜け出します。

同じことがexecステートメント(exec()Python 3の関数)にも当てはまります。

だから、あなたがしたい:

  • Pythonコードのバイトコンパイルを厳密に制御するか、少なくともバイトコードを後処理して、アンダースコアで始まる名前へのアクセスを削除します。

    これには、Pythonインタープリターの動作とPythonバイトコードの構造に関する詳細な知識が必要です。コードオブジェクトはネストされています。モジュールのバイトコードはステートメントの最上位レベルのみを対象とし、各関数とクラスは、独自のバイトコードシーケンスとメタデータで構成され、たとえば、ネストされた関数とクラスの他のバイトコードオブジェクトを含みます。

  • ホワイトリストに登録する必要があります使用できるモジュールます。慎重に。

    pythonモジュールには、他のモジュールへ参照が含まれてます。をインポートする場合、モジュールを参照osするローカル名osがモジュールのネームスペースにありosます。これにより、断固とした攻撃者は、サンドボックスからの脱出に役立つモジュールに誘導される可能性があります。pickleモジュールは、例えば、あなたがそうならば、例えば、任意のコードオブジェクトをロードすることができます任意のに対してホワイトリストモジュールのリード線を通るパスpickleモジュール、あなたはまだ問題を抱えています。

  • 時間の割り当てを厳密に制限する必要があります。最も去勢されたコードでさえ、あなたのリソースを拘束して、永久に実行を試みることができます。

厳密なバイトコード制御を提供しようとするRestrictedPythonを見てください。RestrictedPythonPythonコードを、Python 2.3から2.7で許可される名前、モジュール、オブジェクトを制御できるものに変換します。

場合はRestrictedPython、あなたの目的のために十分安全であるあなたが実装するポリシーに依存しません。アンダースコアで始まる名前へのアクセスを許可せず、モジュールを厳密にホワイトリストに登録することから始めます。

私の意見では、本当に堅牢なオプションは、実行後に毎回破棄する外部世界へのネットワークアクセスがない別の仮想マシンを使用することだけです。新しいスクリプトには、代わりに新しいVMが割り当てられます。そのようにコードがPythonのサンドボックスから抜け出したとしても(これはありそうもないことですが)、攻撃者がアクセスできるのは短命で、価値がありません。


10

TL; DR chroot / jailを使用し、特権のないカスタムユーザーとして実行します。

信頼できないコードを実行するためのベストプラクティスは、システムサンドボックスを介して分離することです。最も安全なために:

  • Pythonのみでコンテナを作成し、依存関係とコンテナの依存関係を作成します
  • 絶対に必要ではないすべてのデバイス(つまり、ネットワークとストレージ)なしでコンテナーを作成する
  • メモリとプロセスの使用に制限のあるコンテナを作成します
  • 実行ごとにコンテナを再作成します(少なくとも、一意のユーザーと最大期間ごとに)
  • 必要な最小限の特権を持つユーザーとして実行する
  • ファイルを書き込む権限のないユーザーとして実行する

また、chrootで安全に実行するための標準的なプラクティスに従います。同様に、各呼び出しでchrootのファイルシステムを再構築できます。通常、chrootが実行されているファイルシステムをユーザーが変更できないようにします。


これは、あなたがリモートでさえあなたがそれを正しく持っていると確信することになる唯一のことです-それにそれ自身のプロセスを与えてください。
マイケルコーネ

3

これを安全に行う方法はありません。

このようなことを安全に行いたい場合は、完全に制御された環境で実行するpythonの独自の実装から始める必要があります。できれば、システムではなくユーザーのブラウザーで実行してください。Jython(java for python)から始めて、Javaアプレットとしてパッケージ化できます。ユーザーのマシン上のjavaサンドボックスで実行されるため、システムはかなり安全です。


4
安全性の問題は、クライアントのマシンではなく、サーバーの問題でした。他のWebテクノロジーと同様に、Javaの潜在的なセキュリティ上の危険は、サーバーがクライアントに危険なプログラムを展開するために使用される可能性があることです。
ddyer

1
@grasGendarmeは、飛行機のabout落についての新しい物語によく似ており、実際にそれらがどれほどまれであるかについて多くを語っています。Javaのセキュリティホールに関する話から、Javaは比較的安全であることがわかります。あなたが得る応答は「まあまあ。それを実行すると、それは何でもやります」
リチャード・ティングル

2

Martijnが上で言ったように、これはPythonでは本当に、本当に難しいです。率直に言って、Pythonは非常に内観的であるため、言語機能を制限することで可能になるとは思いません。また、あるバージョンのPythonでサンドボックスが動作するようになった場合、次のバージョンでサンドボックスが壊れる可能性があります。

標準のCPythonではなく、PyPyを見てみました。要するに、それはPythonの準拠代替実装です。いくつかの利点と明確な機能があり、そのうちの1つは、言語機能を制限する代わりにシステムコールを置き換えることによるサンドボックス化です。


0

パフォーマンスがそれほど重要でない限り、Brythonでいつでも実行でき、JavaScriptサンドボックスに効果的に配置できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.