14

サーバー上で (安全でない) クライアント コードをシミュレートしたいのですが、そのための適切な言語を探しています。シミュレーションに使用するのと同じ言語でクライアントに書いてもらいたいと思います。

  • 安全性が最大の関心事です
  • できればよく知られた言語 (クライアントが構文を習得しやすい)
  • サンドボックスで使用可能な言語機能を簡単に無効化/有効化できる必要があります
  • 実際にコードを段階的にシミュレートできればプラスになります

理想的には、単純にいくつかのインターフェイスを作成 (および公開) し、クライアント コードをロードして、インターフェイスと慎重に選択した標準 API のサブセットのみを使用できるようにすることで、そのコードをシミュレートします。

このシミュレーション中に、クライアント コードが使用するリソース (時間とメモリ) を制限できるはずです。ボーナスは、コードを段階的にシミュレートできれば、常に決定論的なソリューションを返すことができるということです。

パフォーマンスは実際には問題ではありません。アイデアは、クライアントが小さなゲーム/パズル用のカスタム AI を作成できるようにすることです。ゲームは (サーバー上で) シミュレートされ、結果がユーザーに返されます。

もともと私は、パーサーとエバリュエーターを含む外部 DSL を自分で構築することを考えていましたが、おそらくすぐに使用できるソリューションがそこにあるのでしょうか?

4

5 に答える 5

5

私の選択は、いくつかの広範なフレームワーク(.NetやJavaなど)へのアクセスを自動的に提供せずに使用できるスクリプト言語を使用することです。機能を制限するよりも追加する方が簡単です。LUAのようなゲームエンジンスクリプト言語はオプションであり、通常、それらを使用するための複数のプラットフォームの実装が付属しています。

一般的な考慮事項:

どの言語/フレームワークを選択する場合でも、次のリスクから回復/受け入れることができることを確認してください。

  • 致命的な例外(再帰関数によるスタックオーバーフローなど)
  • 無制限のメモリ割り当て/メモリ不足の例外
  • 長時間実行されるタスク

ユーザーが新しいスレッド/タスク/同期オブジェクト(ロック/セマフォ)を制御の外部で作成したり、そのようなAPIを提供するプラットフォーム上に構築したりできるようにするAPIを公開することに注意してください。このようなメソッドを許可すると、サーバーのリソースが無制限に消費されたり、DOS/デッドロックが発生したりする可能性があります。

長時間実行されるタスクは、プログラムを見て終了するかどうかを判断できないため、合理的な言語では問題になることに注意してください。問題を停止します。どのプラットフォームを選択しても、解決策を見つける必要があります。

.Net / C#:

サンドボックス環境のユーザーのマシンで信頼できないコードを実行している.Netでこれを正確に実行するTerrariumを確認できます。

.Netは、複数のAPIの使用を制限する方法を提供します-方法:サンドボックスで部分的に信頼されたコードを実行することは、良い出発点です。@Andrewが指摘しているように、ユーザーによって提供されたアセンブリ(直接またはユーザーのソースからコンパイルされたもの)が、好ましくないAPIを使用していないか(またはその逆であるか-APIのみを使用しているか)を確認することをお勧めします。基本的なサンドボックスに加えて)。別のAppDomainで実行されている部分的に信頼されたコードは、あまり敵意のないコードからの保護を提供します。

スタックオーバーフローは一般的に防ぐのが難しく、.Netで処理するカスタムホストが必要です。長時間実行されるタスクは、Thread.Abortを使用して終了するか、ユーザーのコードを使用してAppDomainをシ​​ャットダウンできます。

于 2013-01-31T06:24:57.647 に答える
1

.NET(C#、VB、F#)をお勧めします。JITを利用して、サーバーにプログラムでコードをコンパイルさせ、リフレクションを使用してコードを分析し、セキュリティとコードの分離のために各クライアントを個別のAppDomainで実行させることができます。

于 2013-01-27T00:30:58.810 に答える
1

エンド ユーザーから提供されたコードを実行し、エンド ユーザーが既に知っている可能性が高い言語を使用したい場合、JavaScript を使用しない理由はありません。

WebWorker で JavaScript をサンドボックス化することができます (メインの JavaScript アプリから分離され、Window オブジェクトや DOM などの共有メモリやグローバルにアクセスできず、メイン スレッドとの通信手段が 1 つしかない並行スレッド)。

私が考えることができる唯一のセキュリティ上の問題は、消費されるハードウェア リソースを 1 つに制限することですが、私はそれを調べていません。また、1 つの WebWorker が追加の WebWorker を生成するのを防ぐ方法を見つけたいと思うでしょう。誰かの WebWorker が一定時間後に自動的にシャットダウンされるようにするには、追加のコードを追加する必要があります。

サーバーサイドの WebWorker はまだ試していませんが、見た目から、NodeJS、Rhino、PhantomJS はすべてサポートしています。Node と Rhino は一般的な Web ブラウザーとは異なる環境を提供しますが、PhantomJS はヘッドレスで実行される完全なブラウザー エンジン (WebKit) です。WebWorker の観点からは、おそらくすべて同じように見えます。

于 2013-01-31T17:59:03.727 に答える
1

Java にはSecurityManagerの概念があり、仮想マシンで実行できるものと実行できないものを微調整できます。

また、実行時にコードをコンパイルし、結果のクラスをロードすることもできます。操作が許可されていないために SecurityManager が SecurityException をスローしない場合は、これらのクラスにあるコードを実行できます。

この投稿では、実行時に一部のコード (テキスト ソース コードとして提供) をコンパイル、ロード、実行する不自然な例を示します。

この別の投稿では、信頼されていない (悪意のある可能性のある) コードを実行する方法を説明しています。

于 2013-01-30T16:03:26.380 に答える
0

本当に「よく知られている」ことが必要な場合、ADsafeは効果的にサンドボックス化された JavaScript のサブセットですが、いくつかの癖があります (例: を回避するthis)。

Java には、クラスがアクセスできるクラスを制限できる「クラス ローダー」があります (「参考文献」を参照SecureClassLoader)。詳細はわかりませんが、基本的には、Java アプレットのセキュリティを提供するために使用されるものです。メモリ使用量を制限できるかどうかはわかりませんが、CPU 時間を制限することはそれほど難しくありません (スレッドを生成して、タイムアウト後に信頼できないコードを実行しているスレッドを強制終了させないでください)。

(信頼できない AI を実行し、ゲームの制約内で他の信頼できない AI を殺そうとするRobocodeを懐かしく思い出します。主な違いは、自動ランキングを行っているサイトはありましたが、エンドユーザーのコンピューターで実行することを意図していたことです。 Java の紹介でしたが、現在は .NET をサポートしていることに注意してください。これは、おそらく 2 つの言語の類似性によるものです。)

于 2013-01-27T01:57:49.120 に答える