SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Javaセキュアコーディング入門

ハッシュテーブルに対する攻撃手法のはなし

Javaセキュアコーディング入門(4)


Java実行環境やJava/Androidアプリへの影響

 Java言語仕様では、クラス階層の最上位に位置するObjectクラスがhashCode()メソッドを持つように規定されています。JDKにおける実装では、文字列を表すStringクラスのhashCode()メソッドは、以下のようにオーバライドされています。

JDK7付属のsrc.zipから引用
public int hashCode() {
    int h = hash;
    if (h == 0 && count > 0) {
        int off = offset;
        char val[] = value;
        int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

 すなわち、文字列を構成する各文字の文字コードを使って以下のようにハッシュ値を計算しています。

n 文字からなる文字列 s[0] s[1] ... s[n-1] に対し
ハッシュ値 = s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

 同じ文字列をキーとするデータを大量に登録させる、あるいは、ハッシュ値が衝突するような文字列を複数あらかじめ探しておき、それらを大量に登録させることができれば、ハッシュテーブルへの登録処理の効率を悪くすることが可能です。与えられた文字列から計算されるハッシュ値はいつでも一通りに決まっているために、ハッシュ値が衝突するような文字列をあらかじめ調べておくことができるのです。

 そのため、StringクラスのオブジェクトをキーとしたHashtableなどのクラスを使っているアプリケーションでは、登録するデータをプログラムの外部から受け付けている場合、DoS攻撃を受ける危険があると考えなければなりません。

 この問題に対する対策としては「randomizedハッシュ関数」を使うとよい、とされています。これはハッシュ関数の計算内容をプロセスごとに変化させるもので、ハッシュ値が衝突する文字列の組み合わせをあらかじめ用意することを困難にして、攻撃される危険を低減しようというものです。具体的なコードは(JavaではなくCですが)、次のセクションで Perlの対策例として紹介します。

 CCCの発表資料によると、OracleはJDK/JREにおけるハッシュ関数の実装をPerlのようなrandomizedハッシュ関数に変更するつもりはないようです。そのため、JDK/JREを更新することで対策を行うことは期待できません。Javaアプリケーション側で何らかの対策を行う必要があります。

 Javaアプリケーション側で行う対策としては、PerlやRuby 1.8で行われたようなrandomizedハッシュ関数を自分で実装して使うか、あるいは、最悪時の計算量がハッシュテーブルほど悪化しないjava.util.TreeMap<K,V>のようなデータ構造を使うように変更することが考えられます。

 そのような大きな変更が難しい場合には、回避策として、問題となる入力を受け付けないようにする必要があります。

 Apache Tomcatでは、HTTPリクエストの内容をハッシュテーブルに格納してWebアプリケーションに渡しています。そのため、攻撃者は細工したHTTPリクエストを送りつけることでDoS攻撃が可能です。Tomcatでは、以前から実装されているmaxPostSizeによってPOSTリクエスト全体の大きさを制限するか、新たに追加されたmaxParameterCountという設定項目によって、DoS攻撃に使われるような大量のパラメタを含むリクエストを拒否できるようにしています。

 このような回避方法では、アプリケーションの実装や実行環境、さらに稼働状況によって、制限すべき値(あるいは許容できる値の範囲)は変わってきます。サイト固有の状況を考慮して最適な値を検討する必要があるでしょう。

短期集中セミナーのお知らせ

 JPCERTコーディネーションセンターの講師陣によるAndroidセキュアコーディングセミナーを2012年3月14日に開催します(主催:翔泳社/CodeZine)。詳しくは特設ページまで!

次のページ
Perlの"randomized"ハッシュ関数

この記事は参考になりましたか?

Javaセキュアコーディング入門連載記事一覧

もっと読む

この記事の著者

戸田 洋三(JPCERT コーディネーションセンター)(トダ ヨウゾウ(JPCERT コーディネーションセンター))

リードアナリストJPCERTコーディネーションセンター東京工業大学情報理工学研究科修士課程修了。学生時代は、型理論および証明からのプログラム抽出を研究。その後、千葉大学総合情報処理センターのスタッフとして、学内ネットワークの運営、地域ネットワーク、IPマルチキャストの実験ネットワークであるJP-MB...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6396 2012/02/21 10:46

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー