Jの衝動書き日記

さらりーまんSEの日記でございます。

体系的に学ぶ安全なWebアプリケーションの作り方の読書メモ 第5回 認証と認可のまとめ

今回は、自作する機会はほとんどないだろうが、原理を知っておきたいこととして、認証と認可を取り上げてみる。ひとまず今回で最終回。

認証(Authentication)とは

利用者が確かに本人であることをなんらかの手段で確認すること

ログイン機能に関するメモ

  • 総当たり攻撃への対策
    • アカウントロックが有効
    • 単純なアカウントロックには効果がない事例
      • ジョーアカウント(Joa Account)探索
        • ユーザ名とパスワードが同一のものを探す
      • 逆総当たり攻撃
        • パスワードを固定にしてユーザIDを取り替えながらログイン試行する
    • 対策
      • 積極的なパスワードチェック
        • よくあるようなパスワード(PasswordやユーザIDと同一といったありふれたもの)を除外する
      • ログインIDの秘匿
        • アカウントIDをメールアドレス等にして、実際のログインIDは内部で持つなど
  • パスワード保存方法
    • メッセージダイジェストによるパスワード保護
      • メッセージダイジェストとは任意の長さのデータ(ビット列)を暗号学的ハッシュ関数を用いて固定長のデータに圧縮すること
      • ハッシュ関数:SHA-256(推奨)、 MD5
    • メッセージダイジェストでパスワード保護できる理由
      • ハッシュ値から元データを得ることが困難(一方向性)
      • 異なる入力から得られるハッシュ値が一致する確率が極めて低い(衝突耐性)
    • 課題
      • 現実的な時間でハッシュ値から元データが得られる可能性がある
        • パスワードが短い場合(8文字以下)、パスワードの文字種が少ない場合
      • レインボークラック
        • ハッシュ値を予め算出しておいて、そこから逆引きで探す
        • レインボーテーブルという手法でテーブルサイズが実用サイズになった
      • ユーザDB内にパスワード辞書を作られる
        1. 解析用にダミーのユーザを攻撃対象のサイトで登録する
        2. ハッシュ化されたパスワードを何らかの方法で取得する
        3. 他のユーザとマッチングしているものを探す
      • ハッシュ化されたパスワードが流出すれば不正ログイン可能と思った方が良い
    • 対策
      • ソルト(salt)
        • ハッシュの元データに文字列を追加し、パスワードの見かけ上の長さを長くする
        • ソルトは、ユーザIDを入力とする関数により生成する
        • ユーザごとに変えることによりパスワードが同じでもハッシュ化されたパスワードの内容が変わる
        • 何故にソルト? →〈商品などを〉実際以上に見せるという意味もあるらしい
      • ストレッチング(stretching)
        • ハッシュ化した文字列を入力として再ハッシュ化することを繰り返す → 繰り返し回数がわからないと元がわからない

自動ログインについて

  • 自動ログインの危険な実装
    • ユーザ名と自動ログインを示すフラグのみをクッキーとして発行
      • 何故危険?
        • クッキーは変更可能であるため、他人のIDでログイン可能
    • パスワードを加えてクッキー発行
      • 何故危険?
        • XSS脆弱性が原因でCookieが漏れた場合、パスワードも流出してしまう
  • 自動ログインの推奨実装
    • セッションの寿命をのばす
      • ログイン認証に成功した後、セッションIDを発行する。以降のアクセスはセッションIDだけをクッキーとして渡す。
      • セッションIDが存在し、期限が有効ならば認証済のものとして扱う。
      • 通常は短期間の寿命だが、それを伸ばせば良い。
      • 方法
        • セッションIDを保持するクッキーのExpires属性を設定 → 一週間などに設定
    • トークンによる自動ログイン(推奨)
      • メリット
        • 自動ログインを選択しない利用者に影響を与えない
        • 複数端末からログインしている場合に一斉にログアウトできる
        • 管理者が、特定利用者のログイン状態をキャンセルできる
        • クライアント側に秘密情報が渡らないので解析されるリスクがない
      • 方法
        1. トークンを発行し、それをクッキーで発行。トークンはサーバ側で管理。ユーザIDと有効期限などと一緒に管理する。
        2. セッション情報が存在するかまずは確認 → あればOK
        3. 無い場合、トークンが有効か確認 → 有効な場合、セッションを再作成し、トークン再発行 ※有効なトークンなのでログイン認証不要
        4. セッションがなく、トークンも無効である場合はログイン認証からやり直し

認可のポイント

認可とは、利用者に対して権限を与えること

  • 認可不備の例
    • 情報リソースのIDを変更すると権限外の情報が参照できる → URLのユーザIDを変えるとそのユーザ情報が見える等
    • メニューの表示・非表示のみで制御している → 直接URLを実行するなどすると利用可能になる等
    • hiddenパラメータやクッキーに権限情報を保持している → これらも書き換え可能
  • 正しい認可実装
    • 操作に先立って適切な確認を行う
      • このスクリプト(画面)を実行してよいユーザであるか
      • リソースに対する操作(参照、変更、削除など)の権限はあるか
    • セッション変数に格納したユーザIDを基準に権限をチェックする
    • 権限情報をクッキーやhiddenパラメータなどに保持しない
  • 認可制御の要件定義のポイント
    • 権限マトリックスを作成する
      • 行:権限付与する対象の機能
      • 列:権限付与する対象のユーザ種別(ロール)

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践

体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践