安全なセッション管理を実現するためにStrutsで作るセキュアWebアプリケーション(4)(1/3 ページ)

» 2006年08月01日 00時00分 公開
[安西真人三井物産セキュアディレクション株式会社]

 HTTPを使用したWebアプリケーションにおいて、安全なセッション管理を行うことは難しい問題である。タブブラウザによる画面の複数起動や、Webブラウザの戻るボタン/更新ボタンの押下といった、予期しない画面遷移に起因するバグの発生に頭を悩ませることは多いだろう。

 大きな問題が発生しないならば、画面遷移の仕様上の制限をクライアントに許容してもらう選択肢もあるだろうが、不正な画面遷移を利用したセキュリティホールが存在するならば、放置しておいてよい問題ではなくなる。今回はセッション管理を安全に行うための基本的な注意点について解説していこう。

セッション固定攻撃とは何か

 セッション固定攻撃(Session Fixation)という脆弱性を耳にしたことはあるだろうか。脆弱性そのものの詳しい解説は本稿の趣旨ではないため割愛するが、簡潔に説明すると、以下のような手順を踏むことによりセッション情報がハイジャックされてしまう問題である。

  1. 攻撃者が取得したセッションIDを含むリクエストを正規ユーザーに発行させる
  2. 正規ユーザーがWebサイトにログインする
  3. 攻撃者のセッションIDが正規ユーザーの認証情報と結び付く
  4. 攻撃者が正規ユーザーの認証情報を利用してWebサイトを利用することが可能となる

 この攻撃は以下の条件がそろうときに成立する。

  • ログイン前にセッションIDが発行される
  • 任意のセッションIDを付加したリクエスト発行のわなをしかけることができる
  • ログイン前とログイン後でセッションIDが変化しない

 Strutsを使用したアプリケーションでは攻撃の成功条件がそろいやすいため、この問題を必ず認識しておく必要がある。攻撃の成功条件がそろいやすいという根拠および対策について順を追って説明していこう。

セッションID発行のタイミング

 J2EEを使用したWebアプリケーションにおいてセッションIDはセッションオブジェクトを生成した段階で発行される。セッションを開始する際には、以下のような実装がログインロジック内で組み込まれることが多いだろう。

/** ログイン処理を実行して成功したらセッションを発行 */
if (login(userId, password)) {
    HttpSession session = request.getSession(true);
    // sessionにログイン情報をセット
}

 一見ログインに成功しないとセッションIDが発行されないように見える実装だが、Strutsを使用したアプリケーションでは落とし穴が存在する。個々のActionクラスはRequestProcessorのprocess()メソッドにより呼び出される流れを取るが、process()メソッド内においてSession呼び出しのロジックが実装されているからだ。

 以下はSession呼び出しのロジックの一例である。多言語対応のため使用される言語情報を取得するために、緑色で示す個所においてSessionが呼び出されている。

public void process(HttpServletRequest request,
             HttpServletResponse response)
  throws IOException, ServletException {
// 中略
  // Select a Locale for the current user if requested
  processLocale(request, response);
// 後略

protected void processLocale(HttpServletRequest request,
                   HttpServletResponse response) {
// 中略
  // Has a Locale already been selected?
  HttpSession session = request.getSession();
  if (session.getAttribute(Globals.LOCALE_KEY) != null) {
    return;
  }
// 後略

RequestProcessor.java

 従って一般的な実装においては、セッションIDの発行タイミングは開発者が制御できるものではなく、Strutsにより自動的に処理されるということが分かるだろう。

 ログイン画面がActionクラスを介さない静的コンテンツとして実装されていたとしても、空の認証情報を設定してログイン処理を実行するなどの手段で、Actionクラスが呼び出されるリクエストを送信することにより、セッションIDはログイン前であっても強制的に発行される結果となる。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。