8

最近、Joshua Bloch による『Effective Java』の第 2 版を読んでいます。項目 39 で、彼は、たとえば特定のクラス Foo のコンストラクターで、これらのオブジェクトが後でクラス Foo の状態を表すために使用される場合、引数として渡される可変オブジェクトの防御コピーを作成することをお勧めします。同じコンテキストで、悪意のある操作を実行するように設計された信頼できないサブクラスのインスタンスを返す可能性があるため、非 final クラスの clone() メソッドの使用を避けるように言及しています。

これが私が明確に得ていないものです。悪意のあるサブクラスの例として、彼は「作成時に各インスタンスへの参照をプライベートな静的リストに記録し、攻撃者がこのリストにアクセスできるようにする」クラスについて言及しています。

私の疑問:

  1. 彼は、この悪意のあるクラスが、カプセル化クラスのすべてのプライベート/保護/パッケージ/パブリック インスタンスの参照を実際に記録できるということですか?

  2. もしそうなら、どのようにそれが可能でしょうか?. 例を教えてください。

どうも!

4

2 に答える 2

9

セキュリティではよくあることですが、これが適用されるコンテキストを設定することが重要です。潜在的に悪意のあるコードが、攻撃されたトラステッド クラスにアクセスできるケースに関心があります。たとえば、ブラウザ内で Java PlugIn の信頼されたライブラリが、信頼されていないコードからアクセスされる可能性があります。以前は RMI がリモート コードをロードしていましたが、現在ではデフォルトでセキュアのポリシーに準拠しています。

変更可能な引数の問題は、有効性がチェックされてから使用されるまでの間に変更できることです。これは、Time Of Check/Time Of Use の脆弱性、TOCTOU (または TOC2TOU) として知られています。実際には、これは 1 回の使用が特にチェックではなく、2 回の使用になる可能性があります。不変に見えるがサブクラス化可能 (たとえばjava.io.File) である他の不適切に設計されたクラスは、呼び出されたときに任意のコードを実行する機能の一部として、サブクラス化して可変にすることができます。

ここで説明している特定の攻撃シナリオはclone、コピーの試みを阻止するために がオーバーライドされる場所です。a への参照staticは、このコンテキストでは無関係です (finalizer攻撃では重要ですが、ほとんどの場合、攻撃コードがクリーンになるように設計されていることはほとんどないことを反映しています)。

class MaliciousDate {
    private final List<MaliciousDate> dates;
    public MaliciousDate(List<MaliciousDate> dates) {
        this.dates = dates;
    }
    @Override public MaliciousDate clone() {
        MalicousDate other = (MalicousDate)super.clone(); // Or new MalicousDate
        synchronized (dates) {
            dates.add(other);
        }
        return other; // Or return this;
    }
}

本の例を変更するには。

public Period(Date start, Date end) {
    // Failing defensive copy.
    start = (Date)start.clone();
    end   = (Date)end  .clone();

    if (start.compareTo(end) > 0)
        throw new IllegalArgumentExcpetion();
    this.start = start;
    this.end = end;
} 

次に、次のように攻撃します。

List<MaliciousDate> dates = new ArrayList<>()
Date start = new MaliciousDate(dates);
Date end = new MaliciousDate(dates);
Period p = new Period(start, end);
dates.get(1).setYear(78); // Modifies internals of p!

結論: 値の型を堅牢に不変にします。詳細については、完全にすばらしいJava プログラミング言語のセキュア コーディング ガイドライン を参照してください。

于 2014-02-20T08:14:39.173 に答える
1

悪意のあるサブクラスのメソッドは、 getDeclaredFieldscloneメソッドを介してスーパークラスのプライベート メンバーにアクセスできます。これにより、プライベートと宣言されたものも含め、スーパークラスのすべてのフィールドが返されます。

この本が言及しているのは、cloneメソッドがメソッドを介してインスタンス化されたすべてのインスタンスのリストも格納できるということだと思いますclone

class MaliciousClass extends LegitimateClass {
  public static ArrayList privateData = new ArrayList()
  public static ArrayList clonedInstances = new ArrayList();
  protected Object clone() {
    Fields[] fields = this.getSuperclass().getDeclaredFields();
    for(Field field: Fields) {
      privateData.add(field.get(this));
    }
    Object clonedObject = // perform clone, returning an instance of MaliciousClass
    clonedInstances.add(clonedObject);
    return clonedObject;
  }
}
于 2014-02-20T03:55:23.810 に答える