ストーリー
高橋アーキテクトが要件定義書のテンプレートを開きました。
セキュリティ要件の分類
セキュリティ要件は以下の4つに分類されます。
| 分類 | 説明 | 例 |
|---|---|---|
| 認証要件 | ユーザーの本人確認に関する要件 | パスワードポリシー、MFA |
| 認可要件 | アクセス制御に関する要件 | RBAC、リソースの所有者チェック |
| データ保護要件 | データの機密性・完全性に関する要件 | 暗号化、マスキング |
| 運用要件 | セキュリティ運用に関する要件 | ログ、監視、インシデント対応 |
セキュリティ要件の書き方
SMART原則で書く
セキュリティ要件も、SMART(Specific, Measurable, Achievable, Relevant, Time-bound)に書きます。
// 悪い例:曖昧な要件
// 「パスワードは安全なものを使用すること」
// 良い例:具体的で計測可能な要件
interface PasswordPolicy {
minLength: 12; // 最低12文字
requireUppercase: true; // 大文字必須
requireLowercase: true; // 小文字必須
requireNumbers: true; // 数字必須
requireSpecialChars: true; // 特殊文字必須
maxAge: 90; // 90日で有効期限切れ
historyCount: 5; // 過去5回と同じパスワード不可
lockoutThreshold: 5; // 5回失敗でアカウントロック
lockoutDuration: 30; // ロック時間30分
}
セキュリティ要件テンプレート
interface SecurityRequirement {
id: string; // 要件ID
category: "認証" | "認可" | "データ保護" | "運用";
title: string; // 要件タイトル
description: string; // 詳細説明
strideThreat: string; // 対応するSTRIDE脅威
dreadScore: number; // DREADスコア
acceptanceCriteria: string[]; // 受け入れ基準
testMethod: string; // テスト方法
priority: "Must" | "Should" | "Could";
}
// 要件定義の例
const securityRequirements: SecurityRequirement[] = [
{
id: "SEC-AUTH-001",
category: "認証",
title: "アカウントロックアウト",
description: "連続ログイン失敗時にアカウントを一時的にロックする",
strideThreat: "S: ブルートフォースによるなりすまし",
dreadScore: 6.8,
acceptanceCriteria: [
"5回連続でログインに失敗した場合、30分間アカウントをロックする",
"ロック中のログイン試行は理由を明示してエラーを返す",
"ロック解除後は正常にログインできる",
"管理者は手動でロックを解除できる",
],
testMethod: "自動テスト + ペネトレーションテスト",
priority: "Must",
},
{
id: "SEC-AUTHZ-001",
category: "認可",
title: "リソースの所有者チェック",
description: "APIエンドポイントでリソースの所有者を検証する",
strideThreat: "E: IDOR による他ユーザーのデータアクセス",
dreadScore: 7.4,
acceptanceCriteria: [
"ユーザーは自分が所有するリソースのみ取得・更新・削除できる",
"他ユーザーのリソースへのアクセスは403 Forbiddenを返す",
"管理者は全リソースにアクセスできる",
],
testMethod: "自動テスト(異なるユーザーでのアクセス確認)",
priority: "Must",
},
{
id: "SEC-DATA-001",
category: "データ保護",
title: "個人情報の暗号化",
description: "データベースに保存する個人情報を暗号化する",
strideThreat: "I: データベースからの個人情報漏洩",
dreadScore: 8.2,
acceptanceCriteria: [
"メールアドレス、電話番号、住所はAES-256で暗号化して保存する",
"暗号化キーはアプリケーションコードから分離して管理する",
"暗号化されたデータはアプリケーション経由でのみ復号できる",
],
testMethod: "DBの直接参照で暗号化を確認",
priority: "Must",
},
];
セキュリティ要件マトリクス
OWASP ASVSを参考に、セキュリティ要件をレベル別に整理できます。
| レベル | 対象 | 要件例 |
|---|---|---|
| Level 1 | 全アプリケーション | 入力バリデーション、HTTPS、パスワードハッシュ化 |
| Level 2 | 機密データを扱うアプリ | 暗号化、MFA、監査ログ、セッション管理 |
| Level 3 | 高リスクアプリ(金融等) | HSM、リアルタイム監視、ペネトレーションテスト |
// レベル別のセキュリティ要件チェック
const securityLevelRequirements = {
level1: {
authentication: [
"パスワードは bcrypt/scrypt/argon2 でハッシュ化",
"HTTPS必須(HTTP→HTTPSリダイレクト)",
"セッションタイムアウト(30分以内)",
],
authorization: [
"全エンドポイントに認可チェック",
"デフォルトdeny(明示的に許可しない限りアクセス拒否)",
],
input: [
"全入力のバリデーション(ホワイトリスト方式)",
"SQLインジェクション対策(パラメータ化クエリ)",
"XSS対策(出力エスケープ)",
],
},
level2: {
authentication: [
"多要素認証(MFA)のサポート",
"パスワードの複雑性要件(12文字以上)",
"アカウントロックアウト機能",
],
dataProtection: [
"保存時暗号化(AES-256)",
"個人情報のマスキング",
"バックアップの暗号化",
],
logging: [
"認証イベントの監査ログ",
"データアクセスの監査ログ",
"ログの改ざん防止",
],
},
};
まとめ
| ポイント | 内容 |
|---|---|
| 要件分類 | 認証・認可・データ保護・運用の4分類 |
| SMART原則 | 具体的で計測可能な要件を書く |
| 受け入れ基準 | テスト可能な条件を定義する |
| レベル別管理 | アプリのリスクに応じた要件レベル |
チェックリスト
- セキュリティ要件の4つの分類を理解した
- SMART原則に基づく要件の書き方を学んだ
- セキュリティ要件テンプレートの使い方を把握した
- レベル別の要件管理を理解した
次のステップへ
次は「セキュアな設計パターン」を学びます。脅威に対抗するための、実装で使える設計パターンを身につけましょう。
推定読了時間: 30分