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

EXP01-J. null ポインタ参照しない

null ポインタ参照は、値が null である変数が、有効なオブジェクトを参照しているものとしてその状態が検査されずに参照されるときに発生する。この場合、NullPointerException が発生し、サービス運用妨害(denial-of-service)につながる可能性がある。したがって、プログラムは決して null ポインタを参照してはならない。

違反コード

以下の違反コード例は Reasoning によって最初に発見された Tomcat version 4.1.24 のバグを示している[Reasoning 2003]。cardinality メソッドは、col コレクションのなかに現れる obj オブジェクトの出現回数を返すように設計されたメソッドである。cardinality メソッドの正しい使い道の一つは、コレクションのなかにあるオブジェクトのいくつが null であるのかを調べることである。しかし、コレクションに含まれるメンバをチェックするには、式 obj.equals(elt) を使うことになるので、objnull であり eltnull でない場合に null ポインタ参照が必ず発生する。

public static int cardinality(Object obj, final Collection col) {
  int count = 0;
  Iterator it = col.iterator();
  while (it.hasNext()) {
    Object elt = it.next();
    if ((null == obj && null == elt) || obj.equals(elt)) {  // null ポインタ参照
      count++;
    }
  }
  return count;
}
適合コード

以下の適合コードでは null ポインタ参照を排除している。

public static int cardinality(Object obj, final Collection col) {
  int count = 0;
  Iterator it = col.iterator();
  while (it.hasNext()) {
    Object elt = it.next();
    if ((null == obj && null == elt) || 
        (null != obj && obj.equals(elt))) {
      count++;
    }
  }
  return count;
}

ここに示す明示的な null チェックは、null ポインタ参照を排除する有効なアプローチの一つである。

リスク評価

null ポインタ参照はサービス運用妨害(denial-of-service)につながる可能性がある。 マルチスレッドプログラムにおいては、null ポインタ参照はキャッシュコヒーレンシポリシー(cache coherency policies)に違反し、リソースリークを引き起こす可能性がある。

ルール 深刻度 可能性 修正コスト 優先度 レベル
EXP01-J P3 L3
自動検出

null ポインタ参照はプログラムの実行フローに依存して発生する場合がある。ツールによる自動検出には限界があるため、人の手によるコード分析が必要となる場合もあるだろう[Hovemeyer 2007]。メソッド引数に(この引数の値は null ではない、というような意味の)アノテーションをつけることで、検出ツールの処理を助け、人の手によるコード分析の必要性を減らすことができる。このようなアノテーションを行うことは強く推奨される。

関連する脆弱性

JDK 1.6 の update 4 より前のバージョンにおける Java Web Start アプリケーションとアプレットには、セキュリティ上重大な問題を引き起こすバグが存在した。場合によっては、アプリケーションやアプレットがサーバとの間で HTTPS 接続を確立しようとすることで NullPointerException が発生した[SDN 2008]。HTTPS によるセキュアな接続を確立できなかった結果、サービス運用妨害(denial-of-service)が発生した。クライアントはセキュアでない HTTP 接続による通信を一時的に行わざるを得なくなったのである。

関連ガイドライン
CERT C Secure Coding Standard EXP34-C. Do not dereference null pointers
CERT C++ Secure Coding Standard EXP34-CPP. Ensure a null pointer is not dereferenced
ISO/IEC TR 24772:2010 "Null Pointer Dereference [XYH]"
MITRE CWE CWE-476. NULL Pointer Dereference
参考文献
[API 2006] method doPrivileged()
[Hovemeyer 2007]  
[Reasoning 2003] Defect ID 00-0001
  Null Pointer Dereference
[SDN 2008] Bug ID 6514454
翻訳元

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

EXP01-J. Never dereference null pointers (revision 79)

Top へ

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