Java リフレクションとセキュリティの問題

1. Java リフレクション メカニズム

Java リフレクション メカニズムは、実行状態では、どのクラスについても、このクラスのすべてのプロパティとメソッドを知ることができ、どのオブジェクトについても、そのメソッドやプロパティのいずれかを呼び出すことができ、この動的に取得された情報と動的関数の機能を意味します。オブジェクトのメソッドを呼び出すことをJava言語のリフレクション機構といいます。

リフレクション メカニズムの非常に重要な点は「ランタイム」です。これにより、プログラムの実行中に、コンパイル中にまったく不明な .class ファイルをロード、探索、および使用できるようになります。一言でまとめると、リフレクションによって、任意のクラスのプロパティとメソッドを実行時に知ることができることがわかります。

2.反映機構のメリットとデメリット

リフレクションを初めて使用する人は、なぜリフレクションを使用してオブジェクトを直接作成するのかと疑問に思うかもしれませんが、現時点では、Java の動的コンパイルと静的コンパイルの概念が関係しています。

静的コンパイル: コンパイル時に型を決定し、オブジェクトをバインドします。

動的コンパイル: 型を決定し、実行時にオブジェクトをバインドします。Java の柔軟性を最大限に高め、ポ​​リモーフィズムを実現し、クラス間の結合を軽減します。

アドバンテージ:

リフレクション メカニズムは、オブジェクトの動的な作成とコンパイルを実現でき、特に J2EE 開発者にとって、その柔軟性は非常に明白であり、優れた柔軟性を示します。例えば、大規模なソフトウェアの開発において、プログラムをコンパイルしてリリースする際、将来的に機能のアップデートが必要になった場合、ユーザーに以前のソフトウェアをアンインストールして新しいバージョンを再インストールしてもらうことはできません。静的を使用した場合、機能の更新を実現するためにプログラム全体を一度再コンパイルする必要がありますが、リフレクション機構を使用した場合、アンインストールする必要はなく、実行時に動的に作成してコンパイルするだけで機能を実現できます。 。

欠点:

パフォーマンスに影響を与えます。リフレクション メカニズムは実際には解釈操作であり、私たちがやりたいことを JVM に伝え、JVM が要件を設定します。このような操作は、同じ操作を直接実行するよりも常に遅くなります。

3. リフレクションメカニズムとデシリアライゼーションの脆弱性

逆シリアル化の脆弱性の主な機能は次のとおりです。

writeObject() シリアル化、オブジェクトをバイト ストリームに出力

readObject() はバイトストリームをデシリアライズしてオブジェクトとして出力します

リフレクション メカニズムを使用して readObject メソッドを書き換え、コマンドを実行できる関数 Runtime.getRuntime() を追加し、calc.exe コマンドを実行して電卓を呼び出します。

個人的なおすすめブログ:ゆでたまごのブログ

上記の逆シリアル化の脆弱性からわかるように、Java リフレクションは確かにプライベート メソッドとプロパティにアクセスできます。これは、第 2 レベルのセキュリティ メカニズムをバイパスする方法の 1 つです。これは実際には、Java 自体が特定の目的のために、またはデバッグを容易にするために残された「バックドア」に似たものです。いずれの場合も、その原則はアクセス セキュリティ チェックをオフにすることです。

一般に、脆弱性を見つけてプログラムにコマンド実行を実装したい場合、努力する方向は 2 つあります。

1. コードと機能の制御: 名前付きインジェクションやその他のインジェクションの脆弱性と同様に、データはコードとして実行されます。または、上記のデモ コードのように readObject が書き換えられ、カスタム コードが追加されます。

2. 入力、データ、変数の制御:コード内の既存の関数とロジックを使用し、入力内容の形式を変更することでプロセス制御を実現します(異なる入力は異なるロジックプロセスに従い、異なるコードブロックでコードを実行します)

Java 逆シリアル化の脆弱性の場合、これは制御されたデータ入力のカテゴリに分類されます。リフレクション メカニズムを呼び出して脆弱性をトリガーする場合、彼は満たさなければならない基本的な点が 2 つあります。

1. シリアル化可能なクラスがあり、そのクラスが readObject() メソッドを書き換えます (コード インジェクションがないため、既存のコード ロジックにそのようなクラスがあるかどうかを確認することしかできません)。

2. 書き換えられた readObject() メソッドのロジックに Method.invoke 関数が表示され、パラメータが制御可能になります。

4. 反射型セキュリティ

上記の内容を読んだ後、Java のリフレクション メカニズムは本当に強力すぎると心からため息をつくはずです。しかし、セキュリティに対するある程度の意識を持っていると、Java の強力な仕組みは少しやりすぎであることがわかります。

リフレクションを扱う場合、セキュリティはより複雑な問題になります。リフレクションはフレームワーク タイプのコードでよく使用されます。そのため、通常のアクセス制限に関係なく、フレームワークがコードに完全にアクセスできるようにする必要がある場合があります。ただし、場合によっては、制御されていないアクセスが重大なセキュリティ リスクを引き起こす可能性があります。

これらの矛盾する要件のため、Java プログラミング言語では、リフレクション セキュリティに対処するためのマルチレベルのアプローチが定義されています。基本的なパターンは、ソース コード アクセスに適用されるものと同じ制限をリフレクションに適用することです。

1. どこからでもクラスのパブリックコンポーネントにアクセス

2. クラス自体の外部のプライベート コンポーネントにはアクセスできません。

3. 保護およびパッケージ化されたコンポーネントへのアクセスが制限されている (デフォルトのアクセス)

Java は C++ よりも安全な言語です。これは、C++ の動作メカニズムと密接に関係しており、C++ はローカルで実行されるため、理論的にはほとんどすべてのプログラムが同じ権限を持っていることになります。Java は仮想マシン内で実行され、外部と直接接続しないため、Java の動作環境は実際には「サンドボックス」環境にな​​ります。そしてJavaのセキュリティモデルとしてはバイトコードベリファイア、クラスローダ、セキュリティマネージャ、アクセスコントローラなど一連のセキュリティコンポーネントが含まれているため、Javaのセキュリティ機構はより複雑であると思われます。

以上がこの記事の内容です、皆様のお役に立てれば幸いです、コードファーマーズハウスへのたくさんのご支援をよろしくお願いいたします。皆様のご支援が創作の原動力となります!皆さんの幸せな人生を祈っています!   

おすすめ

転載: blog.csdn.net/wuxiaopengnihao1/article/details/127920887