WEBアプリのログイン機構のセキュリティチェック観点

ログイン関連の機能開発するときに、私が確認している項目

**[重要!!]金融、行政システムなど、業界独自の法規・基準は意識していません**

## 結論

もろもろいろいろ面倒なので、ログインロジックの自作は極力避けましょう。
SNSとかのソーシャルログインがいいです。
作るの大変ですけど、運用が相対的に楽になります。

あと、不必要に個人情報持つのもやめましょう。
持っちゃうと後が大変です。。。

## リスク評価観点

* ログインユーザに紐づけて以下の情報を保持するか？
    * 個人情報
        * 個人を特定可能な情報
        * メールアドレスだけでも個人情報
            * cf. https://www.soumu.go.jp/main_sosiki/gyoukan/kanri/question03.html
            * 総務省では、「メールアドレスだけでも個人情報になる場合がある」としているので、
              そういったアドレスを排除できない以上、メアドだけでも個人情報を持っていることになる
    * センシティブ情報
        * 家族構成や、趣味嗜好、年収は個人を特定できなくてもハイリスク
    * 所属組織の機密情報
* ログインユーザは以下の行動を行うか
    * 金銭のやり取り、財産の処分
* 利用可能者はだれか？限定方法はなにか？
    * 一定組織（例えば会社）内に限定されるか？
        * ただし、昨今のゼロトラストの流れを考慮すると、  
          社内システムだからといって、ログイン機構のリスクを低く見積もれる時代は、  
          2，3年以内に終了する恐れに留意

## 確認観点

ログイン機構をどのように用意するかによって確認点は大きく異なる
これから新たに作るということは、大体以下のようなものを作る場合があるが、これには縛られない

1. [単一システム内で認証を行う方式](#1-単一システム内で認証を行う方式)  
   ※ID,パスワード等の認証情報を単一システム内でストアし、  
      同システム内でのみ認証を行わせる伝統的な実装形式
2. [LDAP(ActiveDirectory)等、サーバ間通信を通じて認証を行う方式](#2-ldapactivedirectory等サーバ間通信を通じて認証を行う方式)
3. [OAuth2.0 等の認証を別システムで実行し、認可のみ行う方式](#3-oauth20-等の認証を別システムで実行し認可のみ行う方式)
4. [他のWEBアプリからシングルサインオンする場合のクライアント側](#4-他のwebアプリからシングルサインオンする場合のクライアント側)
5. [他のWEBアプリへシングルサインオンする場合のサーバ側](#5-他のwebアプリへシングルサインオンする場合のサーバ側)

OAuth2.0のサーバ側のセキュリティチェック観点はここでは論じない。
（やったことがないので。）

### 1. 単一システム内で認証を行う方式

**以下の観点は必ず対応すべきものもあれば、リスク見合いで実施すべきものあります**

* アプリケーションレイヤ
    * 認証は1要素か2要素か
        * 2要素の場合、**記憶（知識）情報**・**所持情報**・**生体情報**の3つから異なる２つが選ばれているか
    * 以下の対策はどういった方式か？穴はないか？
        * ブルートフォース（総当たり攻撃）対策
        * bot対策
            * reCpatureなどはブルートフォース対策にもなる
        * パスワードリストアタック対策
            * 余所で漏洩したパスワードのリストを浴びせかける攻撃
            * ブルートフォースとは異なる対策が求められる
        * セッションハイジャック対策
            * ログインできたセッションを乗っ取ることで、情報を抜いたりする攻撃
        * セッションフィクセーション対策
            * 攻撃者の用意したセッションを使わせて、ログインさせ、情報を抜いたりする攻撃
        * クロスサイトリクエストフォージェリ対策
            * パスワード変更機能などに無理やり遷移させて、  
              攻撃者の指定のパスワードに変更させるなどの攻撃
    * パスワードなどの認証に用いる情報は、どのようにシステム内に保持されているか
        * 暗号化
            * 暗号化のアルゴリズム、キーはどのように決定、保持されるか
            * 一般的にパスワードの暗号化保持は非推奨
            * やるにしても暗号化アルゴリズムに脆弱性のあるものを採用していないか
        * ハッシュ化
            * ソルトおよびストレッチはどのように実施されるか
    * パスワード再設定機能などが、情報を暴露しないか
        * 「そのIDは登録されていません」は、ブルートフォースの試行回数を激減させてしまう
        * パスワードをメールで平文で送れば、漏洩の可能性が高まる
            * 上記をパスワードリマインダと呼ぶが、新たにこういった機能を実装するのは避けるべきである
    * ログイン前後でCookieにどのような情報を格納するか
        * Cookie格納情報は Secure + HTTP Onlyでも漏洩前提で設計されるべき
    * 所持情報および、生体情報の奪取・詐称対策
        * 情報漏洩後の無効化機構は存在するか  
            * 指紋などの生体情報も結局はデジタル化されてやり取りされるので、  
          漏洩後の対応の検討が必要
            * 最近、指紋認証デバイスがちらほら出始めたが、指紋情報自体が極めて厳重に管理する必要がある  
              漏洩したからといって、指紋を取り替えられないので。
    * ログの取得方式
        * 意図的に入力値をログ出力したりしていないか
        * 偶然に入力値がログに出力されるようになっていないか
            * 例外時のスタックトレースを、ログ書き出ししている場合に起きうる  
              即時ないしは事後のマスキング等の対応が必要
* インフラレイヤ
    * 当該WEBシステムはSSLを利用しているか
    * 当該WEBページはCDNなどのキャッシュ機構を利用していないか
    * HTTPやFTPなどの外部アクセス可能な領域にDBを配置していないか
    * DBは透過的暗号化されるか
* 運用レイヤ
    * 内部犯行対策はどのように行われるか
    * DB等のバックアップデータはどのように管理・破棄されるか
    * 改ざん対策はどのように行われるか
        * キーロガー型のJavaScriptを埋め込むことでパスワードを奪取したりする攻撃への対策

## 2. LDAP(ActiveDirectory)等、サーバ間通信を通じて認証を行う方式

**以下の観点は必ず対応すべきものもあれば、リスク見合いで実施すべきものあります**

* アプリケーションレイヤ
    * LDAP等認証サーバとの通信は暗号化されるか
        * HTTPSやLDAPSなど、セキュアな通信方式か
    * 認証は1要素か2要素か
        * 2要素の場合、**記憶（知識）情報**・**所持情報**・**生体情報**の3つから異なる２つが選ばれているか
    * 以下の対策はLDAP等認証サーバ側の責任か？それともクライアント側の責任か？  
      クライアント側にも責任がある場合どういった方式か？穴はないか？
        * ブルートフォース（総当たり攻撃）対策
        * bot対策
        * パスワードリストアタック対策
    * 以下の対策は、どういった方式か？穴はないか？
        * セッションハイジャック対策
        * セッションフィクセーション対策
        * クロスサイトリクエストフォージェリ対策
    * パスワードなどの認証に用いる情報は、当該WEBアプリ側でシステム内に保持していないか
        * 保持しているなら、どのように暗号化orハッシュ化しているか
    * パスワード再設定機能などが、情報を暴露しないか
    * ログイン前後でCookieにどのような情報を格納するか
    * 所持情報および、生体情報の奪取・詐称対策
    * ログの取得方式
        * 意図的に入力値をログ出力したりしていないか
        * 偶然に入力値がログに出力されるようになっていないか
            * 例外時のスタックトレースを、ログ書き出ししている場合に起きうる  
              即時ないしは事後のマスキング等の対応が必要
* インフラレイヤ
    * 当該WEBシステムはSSLを利用しているか
    * 当該WEBページはCDNなどのキャッシュ機構を利用していないか
    * HTTPやFTPなどの外部アクセス可能な領域にDBを配置していないか
    * （認証情報等を保持している場合）DBは透過的暗号化されるか
* 運用レイヤ
    * 内部犯行対策はどのように行われるか
    * DB等のバックアップデータはどのように管理・破棄されるか
    * 改ざん対策はどのように行われるか
        * キーロガー型のJavaScriptを埋め込むことでパスワードを奪取したりする攻撃への対策

## 3. OAuth2.0 等の認証を別システムで実行し、認可のみ行う方式

**以下の観点は必ず対応すべきものもあれば、リスク見合いで実施すべきものあります**

* アプリケーションレイヤ
    * 以下の対策はどういった方式か？穴はないか？
        * リダイレクトURL改ざん対策
            * 認証サーバからの戻りURLを外部から改ざん可能な形で生成していないか
        * 認可コード等キー漏洩対策
            * 受け取った認可コード等キーが漏洩しても、攻撃者が利用不可にしているか
        * セッションハイジャック対策
            * ログインできたセッションを乗っ取ることで、情報を抜いたりする攻撃
        * セッションフィクセーション対策
            * 攻撃者の用意したセッションを使わせて、ログインさせ、情報を抜いたりする攻撃
        * クロスサイトリクエストフォージェリ対策
            * パスワード変更機能などに無理やり遷移させて、  
              攻撃者の指定のパスワードに変更させるなどの攻撃
    * 認可コード等キーは、どのようにシステム内に保持されているか
        * 暗号化 or 平文
            * 暗号化のアルゴリズム、キーはどのように決定、保持されるか
            * やるにしても暗号化アルゴリズムに脆弱性のあるものを採用していないか
    * 認可サーバでのアカウント凍結・破棄・変更に対応するか、どう対応するか
        * リソースサーバへの要求は認可サーバ側で対応してもらえるが、  
        ログイン維持だけを目的にしている場合、認可サーバ・リソースサーバへ通信せず、  
        ログインが維持され続ける実装も可能。それを良しとするか、しないならどうするか。
    * 認証前後でCookieにどのような情報を格納するか
        * Cookie格納情報は Secure + HTTP Onlyでも漏洩前提で設計されるべき
    * ログの取得方式
        * 意図的に認可コードをログ出力したりしていないか
        * 偶然に認可コードがログに出力されるようになっていないか
            * 例外時のスタックトレースを、ログ書き出ししている場合に起きうる  
              即時ないしは事後のマスキング等の対応が必要
* インフラレイヤ
    * 当該WEBシステムはSSLを利用しているか
    * 当該WEBページはCDNなどのキャッシュ機構を利用していないか
    * HTTPやFTPなどの外部アクセス可能な領域にDBを配置していないか
    * DBは透過的暗号化されるか
* 運用レイヤ
    * DB等のバックアップデータはどのように管理・破棄されるか

## 4. 他のWEBアプリからシングルサインオンする場合のクライアント側

(あとで追記する)

## 5. 他のWEBアプリへシングルサインオンする場合のサーバ側

(あとで追記する)