2010-12-14 22 views
1

クラスがその偽装を偽装することは可能ですか?たとえば、クラスAはクラスBメソッドにアクセスしようとします。 Class Bメソッドは、getClass().getName()を使用して、クラスAをチェックして、それが誰であるかを確認しようとします。偽装は可能ですか?例えばクラスCAを偽装し、getclass().getName()クラスBをチェックに使用するようにしますか?クラスベースの偽装

クラスBが以下のサンプルメソッドで有効なチェックのためにgetClass().getName()を実装したい場合、以下のサンプルコードで正しく実装するにはどうすればよいですか?

public byte[] getStoragePrivateKey(String application) { 
    if (application.getClass().getName().equals("correctClass") { 
     // Allow access to Private Key. 
    } else { 
     // Access denied 
    } 
} 

上記の例では、システム内の内部鍵サーバのデータベースにアクセスしようとしているシステムでは、プラグインアプレットのシミュレーションです。

+1

B b=new B(); byte[] key=b.getStoragePrivateKey(this); 

しかし、検証を避けるには、同じくらい簡単ですか! Java内でセキュリティを有効にする方法はたくさんありますが、最も簡単な方法はセキュリティポリシーです。私は堅牢な方法でアクセス制御を提供できるので、まずそこを見てみましょう。http://download.oracle.com/javase/1.4.2/docs/guide/security/permissions.html –

答えて

2

複数のクラスローダーでこれを行うことができます。各クラスlaoderは、異なる名前のクラスを持つことができます。

しかし、私はあなたがちょうどあなたがこの「セキュリティ」

により、合格することができるかどうかの検証を書くための簡単な方法は、検証を実施するための改善された方法がある

if (application.getClass() == CorrectClass.class) { 

で反射を使用することをお勧め使用する

StackTraceElement[] stes = Thread.currentThread().getStackTrace(); 
if (stes[0].getClassName().equals("correctClass") { 

これにより、呼び出し元が正しいクラス名からのものであることが保証されます。それでもクラスローダーで偽装することができます。

sun.misc.Unsafeクラスは、getUnsafe()メソッドを保護するために後者のようなものを使用します。その周りの標準的な作業は、行うことです。

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); 
theUnsafe.setAccessible(true); 
Unsafe unafe = theUnsafe.get(null); 

危険が保護されていると、なぜあなたがアクセスを取得したい場合がありますなぜあなたは不思議に思っている場合は、メソッドのリストを見てみましょう。 ;)

EDIT:Unsafe.getUnsafe()は以前は保護されていましたが、最新のソースにはもう存在しません。チェックが簡単にバイパスされる可能性があるためです。 ??

+1

fake java。*クラスをロードするか、通常は親クラスローダによってロードされる任意のクラス。 –

+1

@Tom Hawtin、ライセンス契約を破ることなく。しかし、それは技術的に可能です。私はgc()への呼び出しがどこに行われたかを報告するランタイムである自己圧縮Stringの使用に関する記事を書いています。Terracottaは実行時にjava。*クラスを変更し、Profilerは任意のクラスにコードを注入して追加情報を取得します。しかし、私は彼らが複数のコピーを読み込むとは思わない。 –

+0

@Peter Lawrey Javaライブラリの一部を '-Xbootclasspath'などと置き換えることはできますが、クラスローダーを使用してそのライブラリをプルすることはできません。 –

2

これは動作しません: application.getClass().getName()は、「アプリケーション」パラメータのタイプを取得すると、常に"java.lang.String"を返します。

さらに、Javaでは、呼び出されたメソッドが呼び出されている場所から型を見つけることができないため、他の種類のアクセス制御を実装してデザインをチェックする必要があります。

EDIT:私は、あなたが呼び出し元の型をチェックしようとすることができ、それが他のソースからの呼び出しを回避していないだろうかどのようにあなたのコードに基づいて、例を追加してみましょう。

//Change the String for an Object, to allow the invoker pass a 
//reference to itself 
public byte[] getStoragePrivateKey(Object application) { 
    if (application.getClass().getName().equals("correctClass") { 
     // Allow access to Private Key. 
    } else { 
     // Access denied 
    } 
} 

参照タイプAからは、呼び出しは次のようになります。C「偽装」クラスからそれを呼び出す

B b=new B(); 
    byte[] key=b.getStoragePrivateKey(this); 

は、失敗するでしょう、これはCであるとしてクラスインスタンス:それはあなたが達成しようとしているされて何

B b=new B(); 
    A a=new A(); 
    byte[] key=b.getStoragePrivateKey(a);