本記事は学習用です。作成には ChatGPT と GitHub Copilot を使用しています。
1. 設計原則と実装原則の役割分担
セキュア開発では、「設計で守るべき性質」と「実装で守るべき作法」を分離すると、レビュー観点が明確になります。
- 設計原則:アーキテクチャや機能分割、権限モデル、境界(インターフェース)を決める際の判断基準
- 実装原則:コード・ビルド・テスト・運用設定で脆弱性を作り込みにくくする具体的な作法
ここでは代表例として、Saltzer & Schroeder(1975)の「保護機構の設計原則(8原則)」と、SEI CERT の「Top 10 Secure Coding Practices(実装原則)」を取り上げます。Saltzer & Schroeder の一次情報は論文(PDF)で確認できます。(CSE CGI Server)
SEI CERT の Top 10 は CERT Secure Coding のページとして公開されています。(SEI Wiki)
2. Saltzer & Schroeder の設計原則(8原則)
Saltzer & Schroeder は「保護(protection)機構」を設計・実装する際の指針として、8つの原則を示しています。(CSE CGI Server)
※日本語記事は解説として便利ですが、定義の確定は一次情報(論文)側で確認しておくと確実です。(Zenn)
以降では、用語を次のとおり整理します。
- 認証(Authentication):利用者が誰かを確認します
- 認可(Authorization):その利用者が何をしてよいかを決めます
- アクセス制御(Access Control):認証・認可に基づき資源への操作を許可・拒否する仕組みです
2.1 8原則の要点
| 原則 | 実務上の意味(短い定義) |
|---|---|
| Economy of Mechanism(機構の経済性) | 仕組みを小さく単純にし、誤りの余地を減らします |
| Fail-safe Defaults(フェイルセーフなデフォルト) | 既定は拒否(deny)にし、許可は例外として明示します |
| Complete Mediation(完全な媒介) | すべてのアクセスを毎回検査します(抜け道を作りません) |
| Open Design(公開された設計) | 秘密に頼らず、設計は公開されても安全にします(鍵だけを秘密にします) |
| Separation of Privilege(特権の分離) | 重要操作は複数条件・複数主体で成立させます |
| Least Privilege(最小権限) | 必要最小限の権限だけを付与します |
| Least Common Mechanism(共通機構の最小化) | 共有部分(共通機構)を減らし、影響範囲を狭めます |
| Psychological Acceptability(心理的受容性) | 利用者が誤りにくく、理解しやすいUI/運用にします |
これらは設計上の選択に強く影響します。たとえば「最小権限」は RBAC(Role-Based Access Control)の役割設計や、プロセス分割(特権境界)に直結します。
3. SEI CERT の実装原則(Top 10 Secure Coding Practices)
SEI CERT は Secure Coding の知識体系を継続的に更新しており、その入口として「Top 10 Secure Coding Practices」を提示しています。(SEI Wiki)
また、一次資料に近い日本語資料として、IPA の「セキュア・プログラミング講座」が実装原則として SEI CERT Top 10 を取り上げる旨を明記しています。(IPA)
3.1 Top 10(実装原則)の一覧
SEI CERT 側の Top 10 を軸に、実務的な補足を付けています。項目名や説明は改訂される可能性があるため、最新は参照先で確認します。(SEI Wiki)
- Validate input.(入力を検証する)
- Heed compiler warnings.(コンパイラ警告を重視する)
- Architect and design for security policies.(セキュリティポリシーを実装できる設計にする)
- Keep it simple.(設計・実装を単純に保つ)
- Default deny.(既定は拒否)
- Adhere to the principle of least privilege.(最小権限に従う)
- Sanitize data sent to other systems.(他システムに渡すデータを無害化する)
- Practice defense in depth.(多層防御)
- Use effective quality assurance techniques.(有効なQA手法を使う:静的解析・動的解析・レビュー等)
- Adopt a secure coding standard.(セキュアコーディング標準を採用する)
※IPA 講座の掲載箇所では、章立ての都合で並び順が異なる、または抜粋される場合があります。実装現場では「Top 10」を前提にし、教材側の省略有無を区別して扱うと混乱が減ります。(IPA)
3.2 Bonus Secure Coding Practices(補足)
SEI Wiki では Top 10 に加えて、補足の Secure Coding Practices として次の 2 項目も挙げられています。実装原則というより、要件定義・設計工程まで含めた実務の入口として扱うと整理しやすくなります。(SEI Wiki)
- Define security requirements.(セキュリティ要件を定義する)
- 要件が未定義だと、設計・実装・テスト成果物の適合性を評価しにくくなります
- 本稿の流れでは、セキュリティポリシーの文章化(手順 1)と対応しやすくなります
- Model threats.(脅威をモデリングする)
- 脅威モデリングにより、守るべき資産・境界・想定攻撃を早期に洗い出しやすくなります
- 「境界を決める」「多層防御」を設計へ落とす際の補助線として機能します
4. 設計原則(S&S)と実装原則(CERT)を対応付ける
設計原則を「レビュー観点」、実装原則を「実行手段」として対応付けると、チーム運用が回りやすくなります。
4.1 対応表(代表的なつながり)
| Saltzer & Schroeder(設計) | SEI CERT(実装) | 接続のしかた(例) |
|---|---|---|
| Economy of Mechanism | Keep it simple. / Adopt a secure coding standard. | 小さい設計+標準で複雑化を抑えます (CSE CGI Server) |
| Fail-safe Defaults | Default deny. | 設計の「拒否デフォルト」をコード・設定の既定値に落とし込みます (CSE CGI Server) |
| Complete Mediation | Architect and design for security policies. | 「毎回チェック」を可能にする境界と責務分離を設計します (CSE CGI Server) |
| Open Design | Adopt a secure coding standard. / Use effective quality assurance techniques. | 秘密依存を避け、レビュー可能な規約+検査で担保します (CSE CGI Server) |
| Separation of Privilege | Adhere to the principle of least privilege. / Practice defense in depth. | 重要操作を多条件化し、層で守ります (CSE CGI Server) |
| Least Privilege | Adhere to the principle of least privilege. | OS権限・DB権限・クラウドIAMまで一貫させます (CSE CGI Server) |
| Least Common Mechanism | Architect and design for security policies. | 共有コンポーネントを減らす分割設計+境界ごとの認可に接続します (CSE CGI Server) |
| Psychological Acceptability | Validate input. / Sanitize data sent to other systems. | 利用者が誤りにくい入力制約・エラーメッセージ設計に落とし込みます (CSE CGI Server) |
5. 実装へ落とすための具体的手順
- セキュリティポリシーを文章化します(例:誰が何をできるか、拒否デフォルト、監査ログ要否)
- ここが曖昧な場合、「Complete Mediation」「Default deny.」を実装しにくくなります。(SEI Wiki)
- 境界を決めます(モジュール境界、プロセス境界、ネットワーク境界)
- Least Common Mechanism の観点で「共有を減らす」方向に設計すると整理しやすくなります。(CSE CGI Server)
- 権限設計を行います(ロール、サービスアカウント、DBユーザ、クラウドIAM)
- Least Privilege を「実体(人/プロセス/鍵)」単位で適用します。(CSE CGI Server)
- コード規約とツールを固定します(警告をエラー化、静的解析、レビュー項目)
- CERT C などの標準採用は「Adopt a secure coding standard.」に該当します。(SEI Wiki)
- 入力検証・無害化・ログ・例外処理をテンプレ化します
- 「Validate input.」「Sanitize data sent to other systems.」を個人技にしない運用が重要です。(SEI Wiki)
6. コードと設定で見る実装例
6.1 Validate input.:入力検証(Python例)
目的は「想定外の型・長さ・文字種を境界で落とす」ことです。
import re
def parse_user_id(raw: str) -> int:
# 例:ユーザーIDは1〜10桁の数字のみを許可
if not re.fullmatch(r"[0-9]{1,10}", raw):
raise ValueError("invalid user_id")
return int(raw)
ポイント:
- 受け入れ条件(ホワイトリスト)を先に決めると Default deny. と整合します。(SEI Wiki)
- エラー文言は過度に内部情報を出しません。Open Design は「秘密に頼らない」原則ですが、ログと返却メッセージは分けて設計します。(CSE CGI Server)
6.2 Sanitize data sent to other systems.:他システムへ渡すデータの無害化(Web例)
「入力検証」と「出力(他システム送信)無害化」は別物です。たとえば HTML はエスケープが必要になります。
import html
def render_comment(comment: str) -> str:
safe = html.escape(comment, quote=True)
return f"<p>{safe}</p>"
この点は XSS などに直結するため、Web開発ではフレームワークの標準機構を優先します(自作の必要性が高い場合を除きます)。(SEI Wiki)
6.3 Heed compiler warnings.:警告を「潰し切る」(C例)
「警告を放置しない」を仕組みに落とし込みます。
cc -Wall -Wextra -Werror -O2 -o app main.c
-Werrorで警告をビルド失敗にします- 静的解析(例:clang-tidy 等)を CI に組み込みます(「Use effective quality assurance techniques.」にも接続します)
6.4 Default deny. + Complete Mediation:認可チェックを毎回行う(疑似コード)
ありがちな失敗として、「最初にチェックしたから以後は省略する」というキャッシュ設計が挙げられます。
# 悪い例:ログイン時だけ role を確認し、その後の操作では再確認しない
# 良い例:保護対象操作ごとに「主体×資源×操作」を評価する
authorize(subject, resource, action) -> allow/deny
- Complete Mediation は「すべてのアクセス要求を検査する」という設計原則で、実装原則の「Architect and design for security policies.」に強く依存します。(CSE CGI Server)
- Default deny. は「deny を既定にし、allow 条件を列挙する」考え方です。(CSE CGI Server)
6.5 Adhere to the principle of least privilege.:プロセス権限を落とす(Linux運用の基本)
- アプリは root 以外で動かす運用が基本です
- DB はアプリ専用ユーザを作り、必要最小限のテーブル権限だけを付与します
- クラウドは IAM ポリシーを最小化します
Least Privilege は S&S の設計原則として登場し、SEI CERT 側では Adhere to the principle of least privilege. として整理されています。名称は異なりますが意図は近く、設計→実装の接続点として特に重要です。(CSE CGI Server)(SEI Wiki)
6.6 Defense in depth:層で守る(例:API)
- ゲートウェイ層:WAF、レート制限、認証
- アプリ層:入力検証、認可(Complete Mediation)、例外処理
- DB層:最小権限、監査ログ
- 運用層:監視、アラート、インシデント対応手順
「Defense in depth」は単なる多重化ではなく、「単一障害点を作らない」設計・運用の統合として扱うと整理しやすくなります。(SEI Wiki)
7. よくある誤りとチェックリスト
7.1 よくある誤り(原因→対策)
- 誤り:入力検証と無害化を混同し、片方だけで済ませてしまう
- 対策:「境界で検証」「他系送信で無害化」を別チケットで管理すると切り分けやすくなります。(SEI Wiki)
- 誤り:認可を UI やルーティングだけで済ませ、内部 API で抜けてしまう
- 対策:操作関数(use case)単位で
authorizeを必須にすると、Complete Mediation を保ちやすくなります。(CSE CGI Server)
- 対策:操作関数(use case)単位で
- 誤り:最小権限が「運用が面倒」という理由で崩れる
- 対策:ロール設計と棚卸し(権限レビュー)をスプリントの定例に入れると継続しやすくなります。(CSE CGI Server)
- 誤り:警告を放置し、未定義動作や型変換バグが温床になる(C/C++で顕著)
- 対策:コンパイルフラグ固定+CERT C 等の標準採用を前提にします。(JPCERT)
7.2 最小チェックリスト(レビュー用)
- [ ] 既定は deny とし、allow 条件が明示されています(Default deny.)。(SEI Wiki)
- [ ] 保護対象操作ごとに認可が評価されています(Complete Mediation)。(CSE CGI Server)
- [ ] 入力検証(Validate input.)と無害化(Sanitize data sent to other systems.)の両方が用意されています。(SEI Wiki)
- [ ] 警告ゼロ(Heed compiler warnings.)が CI で強制されています。(SEI Wiki)
- [ ] 権限・鍵・アカウントが最小化されています(Adhere to the principle of least privilege.)。(SEI Wiki)
- [ ] 規約(Secure coding standard)が明文化され、逸脱時の扱いが定義されています。(JPCERT)
8. まとめ
- Saltzer & Schroeder の 8 原則は設計判断を支え、抜け道を作りにくいセキュリティ機構の骨格を与えます。(CSE CGI Server)
- SEI CERT の Top 10 は「実装・ビルド・QA」の具体策として機能し、設計原則を日々の開発手順に落とし込みます。(SEI Wiki)
- 実務では「対応表」と「チェックリスト」で設計レビューとコードレビューの観点を接続すると、運用効果が出やすくなります。
※本稿は一般的な技術原則を整理したもので、業界規制(医療・金融等)や法令対応の要否は個別事情で変わります。必要に応じて専門家への確認も検討します。
A. 参考サイト
- Saltzer, J. H., & Schroeder, M. D. “The Protection of Information in Computer Systems” (1975)(PDF)(CSE CGI Server)
- SEI CERT “Top 10 Secure Coding Practices” (SEI Wiki)
- IPA「セキュア・プログラミング講座」(実装原則として SEI CERT Top 10 を採用する旨の記載)(PDF)(IPA)
- JPCERT/CC「CERT C コーディングスタンダード」(JPCERT)
- JPCERT/CC「Java セキュアコーディングスタンダード CERT/Oracle 版」紹介(JPCERT)

コメント