別の投稿から回答を見ました:
文字列は、ネットワーク接続を開く、データベース接続を開く、ファイルを開くなど、多くの Java クラスのパラメーターとして広く使用されています。String が不変でない場合、深刻なセキュリティ上の脅威につながる可能性があります。
使用前に文字列を確認すると問題が解決すると思います。文字列が不変になるように設計されているのはなぜですか?
誰か具体的なコード例を教えてもらえますか?
別の投稿から回答を見ました:
文字列は、ネットワーク接続を開く、データベース接続を開く、ファイルを開くなど、多くの Java クラスのパラメーターとして広く使用されています。String が不変でない場合、深刻なセキュリティ上の脅威につながる可能性があります。
使用前に文字列を確認すると問題が解決すると思います。文字列が不変になるように設計されているのはなぜですか?
誰か具体的なコード例を教えてもらえますか?
一般に、結果に影響を与える可能性のある操作のインターリーブが少ないため、値が変更されない場合は、機密性の高いコードの記述とレビューが容易になります。
次のようなコードを想像してください
void doSomethingImportant(String name) {
if (!isAlphaNumeric(name)) { throw new IllegalArgumentException(); }
Object o = lookupThingy(name);
// No chance of SQL-Injection because name is alpha-numeric.
connection.executeStatement("INSERT INTO MyTable (column) VALUES ('" + name + "')");
}
コードは、権限の昇格を防ぐためにいくつかのチェックを行いますが、これisAlphaNumeric(name)
は引数 toexecuteStatement
が呼び出されたときに true である場合にのみ有効です。
最初の 2 つのステートメントの順序が変更された場合、これは問題にならないため、不適切なインターリーブが部分的に原因で、セキュリティの低下が生じます。ただし、他のコードがこの関数を呼び出しname
、それによって変更されていないと想定する場合があるため、有効性チェックを実行して再実行する必要がある場合があります。
String
が不変でない場合、 によって変更された可能性がありますlookupThingy
。セキュリティ チェックが機能することを確認するには、このコードが SQL インジェクションに対して安全であるために正しく実行する必要がある、はるかに大量のコードがあります。
正しく実行する必要があるコードの量が多くなるだけでなく、ある関数にローカルな変更を加えるメンテナーは、遠く離れた他の関数のセキュリティに影響を与える可能性があります。非局所的な影響により、コードのメンテナンスが困難になります。セキュリティの脆弱性が明らかになることはめったにないため、セキュリティ プロパティを維持することは常に危険です。
文字列が不変になるように設計されているのはなぜですか?
これは、セキュリティ的に悪い理由とは別です。
すぐに利用できる不変の文字列型を持つ言語で書かれたプログラムは、そうでないものよりも不要なバッファー コピーを少なくすると広く信じられています。不要なバッファ コピーはメモリを消費し、GC チャーンを引き起こし、小さな入力よりも大きな入力に対する単純な操作のパフォーマンスが大幅に低下する可能性があります。
また、不変の文字列を使用すると、正しいプログラムを作成しやすくなると広く信じられています。これは、バッファーの防御的なコピーに失敗する可能性が低いためです。
これは本の中で最も古いセキュリティのなりすましです: オペレーティング システムにいくつかのパラメーターを提示し、パラメーターを検証してから、OS がパラメーターを参照している間にパラメーターを更新するため、検証したものとは異なることが行われます。
これは、60 年代に IBM OS/360 を壊すために使用されました。ディスク I/O を要求するには、ディスク アドレスとメモリ アドレスなどを含む「チャネル プログラム」を OS に渡します。OS は、ディスクとメモリのアドレスが認証された場所であることを確認し、ローカル コピーを最初に作成せずに、その「チャネル プログラム」を I/O チャネル ハードウェアに渡して実行します。チェック後、I/O チャネル ハードウェアがプログラムを実行する前にチャネル プログラムを変更して、許可されていないディスクやメモリへのアクセスを許可するように、時間を調整することは難しくありませんでした。
(この時間枠ではメモリが非常に貴重だったので、チャネル プログラムをコピーしないことでかなりの量のメモリが節約されたことを覚えておいてください。しかし、この抜け穴を悪用する方法がかなり広く知られるようになると、この抜け穴はすぐに閉じられました。)
(もちろん、Objective-C プログラムが同じプロセスで実行されている他のコードから「安全」と見なされるかどうかは疑問に思う必要があります。Objective-C の「ダックタイピング」の性質により、真のセキュリティはせいぜいありそうにありません。不変の文字列を使用することはより悪意のある変更に対する保護よりも偶発的な変更に対する保護のほうが重要です。)