JPCERT コーディネーションセンター

SER05-J. 内部クラスのインスタンスをシリアライズしない

「内部クラス(inner class)とは、明示的にも暗黙的にも static 宣言されていない入れ子クラスのことである」[JLS 2005]。内部クラス(ローカルあるいは匿名クラスを含む)をシリアライズすると間違いを犯しやすい。シリアライズに関する仕様には次のように記載されている[Sun 2006]。

したがって、内部クラスをシリアライズしてはならない。

static 宣言されたメンバクラスにはこのような問題はないため、シリアライズしてもよい。

違反コード

以下の違反コード例では、内部クラスをシリアライズするときに外部クラスに含まれているフィールドも一緒にシリアライズされてしまう。

public class OuterSer implements Serializable {
  private int rank;
  class InnerSer implements Serializable {
    protected String name;
    //...
  }
}
適合コード

以下の適合コードでは、InnerSer クラスは Serializable を意図的に実装していない。

public class OuterSer implements Serializable {
  private int rank;
  class InnerSer {
    protected String name;
    //...
  }
}
適合コード

メンバクラスを static 宣言することで、(それを囲むクラスをシリアライズするときに一緒に)シリアライズされることを防ぐことができる。また、static 宣言したメンバクラス自身が Serializable を実装することもできる。

public class OuterSer implements Serializable {
  private int rank;
  static class InnerSer implements Serializable {
    protected String name;
    //...
  }
}
リスク評価

内部クラスをシリアライズ可能にすると、プラットフォーム依存なコードになる可能性がある。また、内部クラスをシリアライズすると、外部クラスのインスタンスも一緒にシリアライズされることがある。

ルール 深刻度 可能性 修正コスト 優先度 レベル
SER05-J P12 L1
自動検出

Serializable を実装した内部クラスの検出は容易である。

関連ガイドライン
MITRE CWE CWE-499, "Serializable Class Containing Sensitive Data"
参考文献
[API 2006] Interface Externalizable
  Interface Serializable
[Bloch 2008] Item 74: "Implement serialization judiciously"
[JLS 2005] Section 8.1.3, Inner Classes and Enclosing Instances
[Sun 2006] "Serialization specification", Section 1.10 The Serializable Interface
翻訳元

これは以下のページを翻訳したものです。

SER05-J. Do not serialize instances of inner classes (revision 63)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter