linux foundationの「セキュア ソフトウェア開発」より「セキュリティ要件」「セキュア設計の原則」まとめ

linux foundationの「セキュア ソフトウェア開発」というオンライン講座が無料で受けられると知り、登録してみました。
資料を読む→理解度チェックという流れが基本なので、自分のペースで進められます。

[セキュア ソフトウェア開発(LFD121-JP)](https://training.linuxfoundation.org/ja/training/developing-secure-software-lfd121-jp/)

その中でも、個人的にいつでも見返せるようにしておきたいと感じた「セキュリティ要件」と「セキュア設計の原則」についてまとめてみました。
これら以外にも、セキュリティに関する具体的な事例などがたくさん詰まった講座なので、気になる方はぜひ見てみてください！


## セキュリティ要件

<details><summary>機密性（Confidentiality）</summary>

- 不正な読み取りをさせない
- 考えるべきこと
    - 公にすべきでない情報は何か
    - 誰がそれを見ることを許可されるべきか
    - パスワード情報の保存方法
</details>

<details><summary>完全性（Integrity）</summary>

- 不正な修正（書き込みや削除）をさせない
- 考えるべきこと
    - ある人だけが修正を許されるべき情報と、それが誰であるか
</details>

<details><summary>可用性（Availability）</summary>

- 攻撃を受けても動作し続ける
- 考えるべきこと
    - 単純な入力で簡単にダウンしないようにソフトウェアを開発すること
    - 新しいサーバーを迅速に追加してソフトウェアを一時的にスケールアップできるようにすること
    - 攻撃が終わったときに素早く回復するようにソフトウェアを実装すること
</details>

<details><summary>否認防止（non-repudiation）または 説明責任（accountability）</summary>

- 誰かがある行動を取れば、たとえ関係者が後でその行動を否定しても、システムが後でその事実を証明できる
- 考えるべきこと
    - 誰かがしたことを証明できるようにしたい行為があるか
</details>

<details><summary>アイデンティティ（Identity）と認証（Authentication）（I&A）</summary>

- 認可が必要な何かを行う前に、ユーザーが自分自身を特定（identify）し、身元を証明する（認証する）ことを要求
- 考えるべきこと
    - 通常、二要素認証（two-factor authentication：2FA）に直接対応するか、二要素認証に対応した他のサービスを介して本人確認ができるようにする必要がある
</details>

<details><summary>認可（Authorization）</summary>

- そのユーザーが何をすることが許されているか（認可されているか）を判断してから、それを実行することを決定する
= 各ユーザーに許可されていることのリスト
- 考えるべきこと
    - 誰が何をすることを許可されているのか
    - 守るべき情報
    - 人の役割
</details>

<details><summary>監査/ロギング（Auditing/Logging）</summary>

- 重要なイベントを記録して、攻撃の検出や復旧を助ける
- 否認防止や説明責任の要件を実装するために重要である
- 考えるべきこと
    - 一般的には、少なくともログイン、ログアウト、ユーザーアカウントの作成と削除などの重要なイベントを記録する必要がある
    - 何かが起こった日時、何が起こったか、どのシステムコンポーネントがそれをしたか、誰がそれを引き起こしたかを記録する必要がある
</details>

## セキュア設計の原則

<details><summary>最小限の権限（Least privilege）</summary>

- サーバーのincludeファイルやconfigurationファイルなどのファイルにユーザーがアクセス（読み取り）できないようにする
- ユーザーに直接提供する必要のないものはすべて「ドキュメントルート」（DOCROOT）の外に置く
- システム設定ファイル（LinuxやUnixの/etcにあるシステムファイルなど）は、デフォルトでユーザーに書き込みを許可しないようにし、現実的には、通常のユーザーによる読み取りも防止することを検討する
- システム設定情報の一部（例：/etcの中） に広い読み取り権限を与える理由がある場合、ディレクトリ名が慣習的に.dで終わるシステム設定ファイルの代わりに、システム設定ディレクトリの作成を検討する
- 外部APIを実装する場合（RESTやGraphQLなど）、使われることを想定していない限り、書き込み操作を提供しないようにする

</details>

<details><summary>完全な仲介（Complete mediation）（別名、非バイパス性）</summary>

- そのデータで行動する前に、要求が許可されているか、入力が有効であるかをチェックする
    - 攻撃者がコントロールできるシステムでセキュリティチェックを実行しても意味がないので注意
    - 信頼できる環境で信頼できるコードを実行することが大切
- チェックリスト
    - クライアントサイドのHTML入力検証
        - 攻撃者がコントロールする可能性のあるシステム上でセキュリティに関連する入力検証を行う、クライアントに送信されるHTMLまたはその他のデータ形式がある場合、これらのチェックがすべて信頼できる環境で再実行されているか
    - クライアントサイドのJavaScript/WASM入力検証
        - 攻撃者がコントロールする可能性のあるシステム上で入力検証やその他のセキュリティ関連の操作を行う、クライアントに送信されるJavaScriptやその他のコードがある場合、これらのチェックがすべて信頼できる環境で再実行されているか
    - クライアントサイドのチェックを用いたモバイルアプリケーション
        - クライアントサイドの問題と同じ
    - ネットワーク経由で直接アクセス可能なデータベース
        - クライアントアプリケーション（Webブラウザー、モバイルアプリなど）が使用するために、ネットワーク経由で直接アクセス可能なデータベースがある場合、そのユーザーが実行できるすべての操作が許可されていることを確認しているか
        - データベースへの直接アクセスを提供するのではなく、プログラムを使ってアクセスを仲介する方が良い（あるいは必要な）場合が多い
    - 攻撃者が乗っ取ることができるネットワーク通信路を使っていないか
        - TLS（https:など）やSSHを使用するネットワーク接続は、適切に実装されていれば乗っ取りに耐えることができる

</details>

<details><summary>効率的なメカニズム（Economy of mechanism）（別名、シンプルさ）</summary>

- システム、特にセキュリティに依存する部分は、できる限りシンプルで小さくあるべき
    - システムのその部分のレビューが容易になり、間違いが起こりにくくなる

</details>

<details><summary>オープンな設計（Open design）</summary>

- システムは公開されたメカニズムであるべき
    - 秘密性は、パスワードや秘密鍵といった比較的少数のアイテムにとどめる
- 攻撃者の無知に依存しない
- オープンな設計は、広範な公開調査を可能にする
- オープンな設計にすることで、利用者は、使用しようとしているシステムが適切なものであると確信することができるようになる

</details>

<details><summary>フェイルセーフなデフォルト（Fail-safe defaults）</summary>

- デフォルトのインストールは安全なインストールであるべき
- もし何かが許可されるべきであると確信できないならば、それを許可してはいけない
    - 例
        - 空の、あるいはデフォルトのパスワードでソフトウェアを配布してはいけない
        - その代わりに、ソフトウェアをインストールするときに新しいパスワードを設定することを要求する

</details>

<details><summary>権限の分離（Separation of privilege）（例えば、二要素認証の使用）</summary>

- オブジェクトへのアクセスは複数の条件に依存するようにする
    - ある条件を破ったからといってすべてが壊れることがないようにする
- ソフトウェアにログインの仕組みがあるならば、二要素認証（two-factor authentication：2FA）をサポートすることを検討する

</details>

<details><summary>共通メカニズムの最小化（Least common mechanism）（別名、最小限の共有）</summary>

- 共有者が異なる権限を持っている場合、共有メカニズムの量と使用を最小限にする
- ファイル、ディレクトリ、OSのカーネル実行、またはコンピューターを信頼できないものと共有することは避ける
- 他の要因とトレードオフになることが多いので、適切な見極めが必要
    - 例
        - クラウドサービスを利用すると、プログラムが敵対者と共有環境で実行されることになるかもしれない
        - 共有の少ない代替手段（シングルテナント クラウドやプライベートクラウドなど）を選択すると、コストが上がる可能性がある

</details>

<details><summary>心理学的受容性（Psychological acceptability）（別名、使いやすさ）</summary>

- ユーザーが日常的かつ自動的に保護機構を正しく使用できるように、ヒューマンインターフェイスは使いやすく設計されていなければならない
- セキュリティと使いやすさは常にトレードオフの関係にあるという考えは、多くの場合間違っている
    - 使いにくいものは、実際には人々がそれを回避するため、安全でないことが多い

</details>