2010-12-01 3 views
9

現在、信頼できないJavaコードを実行するためにサンドボックスを作成しようとしています。このアイデアは、Javaアプリケーションがファイルシステムまたはネットワークソケットにアクセスするのを隔離することです。私が現在持っているソリューションは、IOやネットワークへのアクセスを禁止するSecurityManagerに書き直されています。Javaサンドボックス。 SecurityManagerを使用してI/Oアクセスをリダイレクトする

今私は呼び出しをファイルシステムにリダイレクトしたい、つまりアプリケーションが"/home/user/application.txt"に書き込もうとしている場合ファイルへのパスを次のように置き換える必要があります。 "/temp/trusted_folder/application.txt"。だから基本的には、アプリケーションが特定のフォルダ内のファイルシステムにしかアクセスできないようにし、他のすべての呼び出しをこのフォルダにリダイレクトすることを許可します。

したがって、クラスFileOutputStreamのメソッドがあります。ここでは、指定されたパスに書き込む権限があるかどうかをSMに問い合わせます。明らかに

public FileOutputStream(File file, boolean append) 
    throws FileNotFoundException 
{ 
    String name = (file != null ? file.getPath() : null); 
    SecurityManager security = System.getSecurityManager(); 
    if (security != null) { 
     security.checkWrite(name); 
    } 
    if (name == null) { 
     throw new NullPointerException(); 
    } 
    fd = new FileDescriptor(); 
    fd.incrementAndGetUseCount(); 
    this.append = append; 
    if (append) { 
     openAppend(name); 
    } else { 
     open(name); 
    } 
} 

、SMはのFileOutputStreamへのアクセス権を持っていないと、SecurityExceptionを投げる以外、(ファイルのような)方法で、内部変数を変更したり、何らかの形で実行順序に影響を与えることはできません。私は、内部フィールドにアクセスすることは、オブジェクト指向の原則に違反していることを理解しています。ローカル変数は、宣言されたメソッドの内部にのみ存在し、存在します。

私の質問は次のとおりです。Security Managerでファイルシステムへの呼び出しを置き換える方法はありますか?そうでない場合、これを行うために私が使用できる他の方法はありますか?

私は十分にはっきりしていたと思います。

答えて

6

SecurityManagerはそれを行うことはできません。はいいいえのみといいます。

私は2つのオプションを考えることができます:

  1. は、ファイルシステムとOSレベルで何かをします。 chroot jailsのようなものがあります。これはアプリケーションにとって透過的ですが、Java以外の作業が必要です。

  2. FileOutputStreamを開くAPIをアプリケーションに提供します。 APIレイヤーは、ファイルがどこにあるかを決定し、どこからでもファイルを開くことができる(Security Managerの用語では)特権です。もちろん、サンドボックスアプリケーションではjava.io.Fileの代わりにAPIを直接使用する必要があります。しかし、さらに柔軟性があり、Java WebStart for exampleのように、アプリケーションがサンドボックスを認識してサンドボックスAPIを使用する必要がある場合があります。

+0

答えに感謝します。最初のオプション私は自分のOSを1つのOSに制限したくないので、私は受け入れることができませんでしたが、2番目のオプションはかなりいいです。私はいくつかのAPIの置換を検索し、JMockitツールがクラスをモックしスタブを実行できることを発見しました。だから、基本的に私はそれを調べて、これが私が今必要としているものだと思う。 – Sevich

0

私はそれができるとは思わない。 セキュリティマネージャは、特定の操作へのアクセスを拒否するように設計されています.IOのリダイレクトやその他の操作はできません。

深刻な反射ハッキングによっても可能であっても、同じjvmを実行している別のオペレーティングシステムや異なるjvmベンダー間ではおそらく移植できません。 (OS固有のクラスを操作する必要があるためです)。

低レベルで試してみたいことは、linuxやその他の重い仮想化技術についてはchrootを参照してください。

0

あなたがしようとしていることは、すでにWealthfrontのエンジニアによって実装されていると思います。ここで
はそれについて自分のブログのエントリです:今、Javaはオープンソースであることをhttp://eng.wealthfront.com/2010/11/less-io-for-your-java-unit-tests.html

+0

この記事はそのようなことを言っていません。彼らは、予期しないI/O操作を監査し、潜在的に許可しないSecurityManagerを記述しています。禁止、変更はしません。 – Thilo

5

、あなたは、FileOutputStreamにソースコードをダウンロードし、あなたが望むものは何でも制約強制するために、そのソースコードを修正し、それを再コンパイルし、jarファイルに追加することができ、そしてJVMのブートローダーのクラスパスにそのJARを付加:

java -Xbootclasspath/p:myModifiedJavaClasses.jar sandbox.Main -run untrusted.Main 

JVMは今、あなたのjava.io.FileOutputStreamの実装の代わりに、通常のものを使用します。特別なサンドボックスリダイレクトロジックを必要とするすべてのJSEクラスについて、リンスして繰り返します。

パラメータを起動するために「VM外に」変更する必要があるため、移植性が高く、簡単に展開できるソリューションではありませんが、この解決策は容認でき、効果的です。

関連する問題