リフレクションはプライベート変数を制限できないので不利ですか?


14

private修飾子は、クラス外部からのアクセスを制限するために使用されていますが、反射他のクラスを使用すると、プライベートメソッドとフィールドにアクセスすることができます。ですから、もしそれが要件の一部であるなら、どうやってアクセシビリティを制限できるのだろうと思っています。


2
低信頼コードは、プライベートリフレクションを使用できません(少なくとも他のアセンブリでは、詳細を忘れていました)。完全信頼コードは、ポインターを使用して、プロセス内の制限をバイパスできます。
CodesInChaos

55
プライベートアクセス修飾子は、主にプログラマーに「クラスの外部からこれを使用しないでください。実際に使用しても、次のバージョンがコードを壊しても文句を言わないでください」と厳密に適用されるセキュリティ機能はありません。
CodesInChaos


4
また、ユーザーはコードにパッチを適用して、必要な処理を実行できます。DRM(永続的な保護を提供するほど強力ではない)の部分的な例外を除き、アプリケーション(バイナリまたはソースコード)にアクセスできる人はだれでもそれを使用できます。
ブライアン

6
これは言語固有の質問ではありませんか?Reflectionは、言語によって動作が異なります。この質問にJavaまたは他のタグが必要かどうか疑問に思っています。
ウェインコンラッド

回答:


54

アクセス修飾子の目的は、クラスのパブリックインターフェイスとは何かについてコードを記述する開発者に通知することです。これらは決してセキュリティ対策ではなく、文字通り情報を隠したり保護したりしません。


33
これは普遍的に真実ではありません。Eric Lippertの言葉を引用して、「CLRのアクセス修飾子はセキュリティ機能です。アクセスのルールは、セキュリティおよびタイプセーフティシステムと完全に混同されます。」これは、コードを実行しているシステムの悪意のあるユーザーには適用されません(また、適用できません)。ただし、悪意のあるプラグインには適用されます。
ブライアン

5
@Brianブライアンが言及している問題が関連するのは、システムがサードパーティのコードを完全に信頼せずに実行できる場合です。例には、ブラウザのサンドボックス(例:嫌いなアプレット)、googleアプリエンジンAzureが含まれます。信頼できないコードがプラットフォームのコアライブラリの詳細を調査できるようにすることは、Azureにとって本当にばかげているでしょう。
ジミージェームズ

3
@Brianそれは完全に正しいわけではありません-部分的に信頼できるコードで実行できるリフレクション操作がいくつかあります。プライベートフィールドにアクセスするようなことはできません。
ルアーン

1
@Brian誰かが制限を回避できる脆弱性またはソーシャルエンジニアリングを見つけるまで。それらをそのように使用しようとしても意味がありません。それは彼らの主な目的ではありません。
jpmc26

31

引用する クラスアクセス権についてハーブサッター

「ここでの問題は、Murphyに対する保護とMachiavelliに対する保護です。つまり、偶発的な誤用(この言語は非常にうまくいきます)に対する保護です。プログラマーはシステムを破壊するほどひどく欲しがり、方法を見つけるでしょう」


2
そこているサンドボックス信頼できないコードに必要な時間は、それは大変な作業です。エラー(マーフィー)からの保護は、はるかに一般的なケースです。
ポールドレーパー

#define private public(実際には未定義の動作であることを無視します)そして、私はあなたのクラスの制限された部分に外部から完全にアクセスできます。
-bolov

故意の虐待から保護することは理論的には不可能かもしれませんが、虐待を非常にまれにしか起こさないほど十分に困難にすることにより、事実上可能です。それについて明確にすることが重要です。そうしないと、生命にかかわる医療機器などの状況ではソフトウェアをまったく使用できません。
MarkJ

@MarkJ。ハーブ・サッターの発言は、最初にクラスを書いた開発者とおそらく彼のチームメイトによる意図的な虐待についてです。言語機能によるそのような悪用を防ぐ方法はないと思います。
ネマンジャトリフノヴィッチ

@bolovは、スタントが言語に依存していると思います。C / C ++プリプロセッサはおそらくそれを回避できますが、それらがない場合は、おそらく「#defineで予約語を使用できません」というエラーが発生します。
ダンはFirelightによって

10

いいえ、これは実際に重要な利点です。一部の開発者は、だれかが内部状態の一部にアクセスする必要があるとは考えなかったからといって、正当なユースケースが出現しないという意味ではありません。これらの場合、Reflectionを使用してオブジェクトの手術を行うことは最後の手段です。この手法を複数回使用する必要がありました。


1
言い換えれば、不完全な要件または不完全な実装が原因である可能性のある壊れたAPIを回避する方法です。
モニカの復元

4

実行環境というもう1つのレベルを上げることで、アクセシビリティをさらに制限できます。

すべての言語にこの概念があるわけではありませんが、少なくともJavaでは、プライベートフィールドへのアクセスを禁止するセキュリティマネージャーを使用できます。実行時にセキュリティマネージャを手動でインストールするか、jarファイルにセキュリティポリシーを追加して、変更を防ぐためにシールします。

Javaでこれを行うための詳細:Reflection Security


3

あなたはどんな反射について話しているのですか?

多くのリフレクションシステムでは、カプセル化の回避は、コードが取得する必要がある明示的な機能であり、デフォルトではありません。

カプセル化について懸念がある場合、単純な解決策は、それを保持しないリフレクションシステムを使用しないことです。


3

Pythonには、アクセス修飾子はありません。慣習では、クラスの外部からアクセスされることが予想されないメソッドと変数の前にアンダースコアを付けます。サードパーティクラスからそのようなフィールドにアクセスすることを技術的に妨げていますか?どういたしまして; しかし、もしそうなら、あなたは自分自身であり、他のクラスを責めることなく、何かを壊す危険を冒します。

C#には、アクセス修飾子が存在しますが、それらはまだ慣習にすぎません。コンパイラによって強制されるものですが、慣習です。つまり、技術的には、Reflectionを使用するか、メモリを直接改ざんすることで(ゲームトレーナーのように)、プライベート変数にアクセスして変更することができます。ように)。結果はまったく同じです。クラスの変数が別のクラスからのリフレクションまたは別のアプリケーションによるメモリ改ざんによって変更され、それがクラス内の何かを壊す場合、それはあなたのせいではありません。

これにより、サードパーティがデータにアクセスできるセキュリティ問題が明らかに発生することに注意してください文字列や類似のデータ構造の暗号化されたバリアントにつながる何か。しかし、そのような使用からコードを保護することは、より関連するOSとコードレベルのアクセス制限であり、Reflection自体とは関係ありません。


2
C#では、完全に信頼されたコードのみがプライベートメンバーを反映​​できることに注意してください。プロセスメモリへの直接書き込みは引き続き機能しますが、ネイティブコードより困難です。
ルアーン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.