17

Stringaが不変であることを知りました。その背後にある理由を読んでいたときに、いくつかの理由が浮かびました。たとえば、パフォーマンスが向上したり、値を変更できないため、複数のスレッドで共有したりできます。私が理解しているこれらの理由。

しかし、それがセキュリティとどのように関連しているかはわかりません。String不変であることは、Javaセキュリティにどのように役立ちますか?

4

3 に答える 3

18

クラスライブラリを作成する際の非常に一般的な方法は、APIに渡されたパラメータを、たとえばコンストラクタに次のように格納することです。

public class MyApi {
    final String myUrl;
    public MyApi(String urlString) {
        // Verify that urlString points to an approved server
        if (!checkApprovedUrl(urlString)) throw new IllegalArgumentException();
        myUrl = urlString;
    }
}

String変更可能である場合、これは微妙な悪用につながります。攻撃者は適切なURLを渡し、数マイクロ秒待ってから、攻撃サイトを指すようにURLを設定します。

コピーせずに保存することはかなり一般的な方法であり、文字列は最も一般的に使用されるデータ型の1つであるため、文字列を変更可能のままにしておくと、まだ書き込まれていない多くのAPIが開かれ、深刻なセキュリティ問題が発生します。文字列を不変にすることで、まだ作成されていないAPIを含む、すべてのAPIのこの特定のセキュリティホールが閉じられます。

于 2013-03-07T15:28:51.353 に答える
4

SecurityManagerの概念が機能するには、不変の文字列が必要です。dasbklinkenlightはすでに彼の答えで正しい方向に進んでいますが、可変の文字列はサンドボックスの概念を完全に壊してしまいます。

たとえばnew FileInputStream("foo");、ファイルを読み取るためにを実行すると、API実装は内部的に次のことを実行します。

  • 引数として「foo」を指定してセキュリティマネージャのcheckReadメソッドを呼び出し、チェックが失敗した場合は例外をスローします
  • セキュリティチェックに合格した場合は、オペレーティングシステムコールを使用して実際にファイルを開きます

呼び出し元がこれらの2つのステップの間で文字列を変更できる場合、実際には別のファイルが開かれている間に、1つのファイルのセキュリティチェックが成功する可能性があります。

于 2013-03-07T15:39:33.513 に答える
0

文字列は不変です。つまり、オブジェクト自体は変更できませんが、もちろん参照は変更できます。(たとえば)a = "ty"を呼び出すと、実際には、文字列リテラル"ty"によって作成された新しいオブジェクトへのaの参照が変更されます。オブジェクトを変更するということは、そのメソッドを使用してそのフィールドの1つを変更することを意味します。次に例を示します。

Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"

Stringなどの不変クラス(finalとして宣言されている)では、現在のStringを変更することはできませんが、新しいStringを返すことはできます。

String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"
于 2013-03-07T15:23:48.980 に答える