セキュリティではよくあることですが、これが適用されるコンテキストを設定することが重要です。潜在的に悪意のあるコードが、攻撃されたトラステッド クラスにアクセスできるケースに関心があります。たとえば、ブラウザ内で 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 プログラミング言語のセキュア コーディング ガイドライン を参照してください。