前回までに、Webアプリケーションの脆弱性について、発生原理や脆弱性による影響と対策をまとめた。ここでは、代表的なセキュリティ機能であり、利用者の本人確認の手段である認証(Authentication)について7要素に分けて解説する。
1 ログイン機能
ログイン(本人確認)機能とは、ユーザIDとパスワードをデータベースに照合して、一致するものがあれば認証されたとみなすことである。通常、以下のようなSQL文を用いて、IDとパスワードの両方が一致するユーザを検索し、ユーザが存在すればログインできたとみなす。
SELECT * FROM usermaster WHERE id=? AND password=?
ログイン機能に対する攻撃
- SQLインジェクション攻撃によるログイン機能のバイパス
- SQLインジェクション攻撃によるパスワードの入手
- ログイン画面に対するパスワード試行:総当たり攻撃、辞書攻撃
- ソーシャルハッキングによるパスワード入手:利用者本人をだます手法
- フィッシングによるパスワード入手
ログイン機能が破られた場合の影響
攻撃者は利用者の持つ権限をすべて利用できる。例えば、情報の閲覧、更新、削除、物品の購入、送金、掲示板への投稿などである。
不正ログインを防ぐためには
- SQLインジェクションなどセキュリティバグ(狭義の脆弱性)をなくす:SQLインジェクション、セッションIDの固定化、クッキーのセキュア属性不備、オープンリダイレクタ脆弱性、HTTPヘッダ・インジェクション
- パスワードを予測困難なものにする
- パスワードの文字種と桁数の要件:パスワードの組み合わせ総数=文字種の数^桁数
- パスワード利用の現状:「123456」が最多
- パスワードに関するアプリケーション要件:英数字で8桁まで入力可能(最低)
- 積極的なパスワードポリシーのチェック:「単純すぎます」表示など
2 総当たり攻撃への対策
基本的なアカウントロック
- ユーザIDごとにパスワード間違いの回数を数える
- パスワード間違いの回数が上限値を超えると、アカウントをロックする。ロックされたアカウントはログインできなくなる
- アカウントロックが発生した場合はメールなどで対象利用者と管理者に通知する
- 正常にログインした場合は、パスワード間違いのカウンタをクリアする
一方、ロックされたアカウントの再有効化は以下の2つが挙げられる。
- アカウントロックから30分経過した場合、自動的に再有効化される
- 管理者が何らかの方法で本人確認した後に再有効化する
総当たり攻撃のバリエーションと対策
- 辞書攻撃:使用頻度の高いパスワード候補から順に試す方法
- ジョーアカウント探索:ユーザIDと同じ文字列をパスワードに設定しているアカウントを攻撃するもの
- 逆総当たり攻撃:パスワードを固定したIDに対する総当たり攻撃
- 変形総当たり攻撃への対策:積極的なパスワードチェック、ログインIDの秘匿(ログインIDにメールアドレスを使うなど)、ログイン失敗率の監視
3 パスワードの保存方法
パスワードの保護の必要性
以下の3つのような被害が生じる可能性があるため、保護が必要となる。
- 該当利用者の権限で使える機能の悪用(物品購入、送金など)
- 該当利用者の権限でのデータ投稿、変更、削除
- 利用者がパスワードを使い回している場合、他サイトへの影響の波及
暗号化によるパスワード保護と課題
- 安全な暗号アルゴリズムの選定
- 鍵の生成
- 鍵の保管
- 暗号アルゴリズムが危殆化(きたいか)した場合の再暗号化:暗号を破る手法が発見されたり、コンピュータの速度の向上などで総当たり攻撃が現実的になること
メッセージダイジェストによるパスワード保護と課題
メッセージダイジェストとは、固定長のデータ(ハッシュ値)のこと。任意の長さのデータ(ビット列)をメッセージダイジェストに圧縮する関数をハッシュ関数という。セキュリティ上の要件を満たすハッシュ関数を暗号学的ハッシュ関数という。以下では、暗号学的ハッシュ関数を単にハッシュ関数と表記する。
メッセージダイジェストによりパスワードが安全に保存できる理由は、ハッシュ関数の特性によるものである。すなわち、一方向性(ハッシュ値から元データを得ることが困難)と衝突体制(異なる入力から得られるハッシュ値が一致する確率が極めて低い)の2つ。しかし、パスワードの文字種や文字数が制限されているという特性によって、ハッシュ値から元のパスワードを解析するための手法が知られている。以下にその脅威を3つ取り上げる。
- オフライン総当たり攻撃:攻撃対象サーバーに接続せずに行える
- レインボー・クラック:逆引き表を使って高速にパスワードを求めるもの。零ボーテーブルの原理を用いる
- ユーザDB内にパスワード辞書を作られる:攻撃者がダミーのユーザを多数登録して、ハッシュ値から推定する
これらの脅威への対策としては、以下の2つが挙げられる。
- ソルト(salt):ハッシュの元データに追加する文字列のこと。要件は、ある程度の長さ(20文字以上)を確保し、ユーザごとに異なるものにすること。そのために、乱数をソルトとして使う方法やユーザIDを有力とする関数によりソルトを生成する方法がある
- ストレッチング(stretching):ハッシュの計算を繰り返し行うことによって、計算時間を延ばすこと
4 自動ログイン
危険な実装例
- ユーザ名と自動ログインのフラグを平文でクッキーに設定する
- クッキーに秘密情報を保存している
自動ログインの安全な実装方式
- セッションの寿命を延ばす:session_set_cookie_params関数により、セッションIDを保持するクッキーのExpires属性を設定する。php.iniにてsession.gc_maxlifetime設定を1週間などに延ばす(デフォルトは24分間)
- トークンを使う:ログイン時にトークンを発行、ログイン状態の確認と自動ログイン、ログアウト
- 認証チケットを使う
自動ログインのリスク低減方法
重要情報(個人情報など)の閲覧や、重要な処理(物品購入、送金、パスワード変更など)に先立ちパスワード入力を要求する(再認証)方法がある。Amazonなど。
5 ログインフォーム
一般的なガイドラインは以下の通り。
- パスワード入力欄はマスク表示する:type属性がpasswordのinput要素を使う
- HTTPSを利用する場合、ログインフォームからHTTPSにする:以下の2つの危険性がある。フォームが改ざんされていて、入力値の送信先が別のサイトになっている。DNSキャッシュポイズニングなどにより、偽物のサイトを表示している
6 エラーメッセージの要件
攻撃者のヒントとなる情報を含まないこと。具体的には「IDまたはパスワードが違うか、アカウントがロックされています」のように表示されること。例えば「指定されたユーザは存在しません」や「パスワードが間違っています」だと、どちらが間違っているかが特定されてしまうから。
7 ログアウト機能
ログアウト処理の要件は以下の3つ。
- ログアウト処理は副作用があるのでPOSTメソッドでリクエストする
- ログアウト処理ではセッションを破棄する
- 必要な場合CSRF対策の対象とする
最後に
認証機能のセキュリティ強度を高める方法についてまとめた。現在主流の認証方式であるパスワード認証のセキュリティ強度を高める施策には、以下のものがある。
パスワードの文字種と桁数の要件(ログイン攻撃対策)、総当たり攻撃への対策、パスワードの保存方法、入力画面(ログインフォーム)とエラーメッセージの要件、そして自動ログインと、ログアウト機能の安全な実装である。
セッションの寿命を延ばすことやトークンの利用、そしてソルトやストレッチングなど、開発者側も対策を練る必要性はある。しかし、利用者側もソーシャルハッキングなどをされないよう、最低限の知識は持つことが求められている。
次回は、アカウント管理、認可、ログ出力についてまとめる。
![]() |