ドキュメント / 詳細設計 / 非機能系
•
PART 03 / 03
•
2026.06.18
•
20 min read
PART 03 — セキュリティ設計書
認証・認可・暗号化・脆弱性対策の定義
セキュリティ設計書は「攻撃への備えの設計書」だ。要件定義で策定したセキュリティ要件を、詳細設計フェーズで具体的な実装方針に落とし込む。後から追加するセキュリティ対策は高コストになる。
セキュリティ設計書の位置づけ
セキュリティ設計書は OWASP Top 10 などの脅威を意識しながら、認証・認可・暗号化・通信制御・脆弱性対策の実装方針を定める文書だ。設計段階で対策を盛り込むことで、実装後の改修コストを最小化できる。
💡 OWASP Top 10(2021)主要脅威
A01 アクセス制御の不備 / A02 暗号化の失敗 / A03 インジェクション / A04 安全でない設計 / A05 セキュリティの設定ミス / A06 脆弱で古いコンポーネント / A07 識別と認証の失敗 — これらを設計で防ぐ方針を定める。
認証設計
| 項目 | 方針 |
| 認証方式 | JWT(RS256 署名)。秘密鍵はHSM or KMS で管理 |
| パスワードハッシュ | bcrypt(コストファクタ 12以上)。SHA-1/MD5 は禁止 |
| アクセストークン有効期限 | 15分(短命・ステートレス) |
| リフレッシュトークン有効期限 | 7日(DB に保存・失効管理) |
| MFA(多要素認証) | 管理者アカウントは TOTP(RFC6238)必須 |
| セッション管理 | サーバーサイドセッション不使用(JWT のみ) |
| ブルートフォース対策 | 5回連続失敗で 30分ロック + メール通知 |
| パスワードポリシー | 8文字以上・英大小数記号各1文字以上・辞書語禁止 |
認可設計
| ロール | 許可操作 | 禁止操作 |
| ADMIN | 全操作(ユーザー管理・設定変更含む) | — |
| USER | 自分のデータの参照・更新・注文 | 他ユーザーデータへのアクセス・管理操作 |
| READONLY | 参照のみ(自分のデータ) | 更新・削除操作 |
暗号化設計
| 対象 | 暗号化方式 | 備考 |
| 通信(HTTPS) | TLS 1.2以上(TLS 1.0/1.1は無効化) | HSTS 設定必須 |
| パスワード | bcrypt(コストファクタ 12) | 平文保存・MD5禁止 |
| 個人情報(DB) | AES-256-GCM | KMS でキー管理 |
| JWT 署名 | RS256(RSA 2048bit) | 秘密鍵は環境変数管理 |
| ファイル転送(SFTP) | SSH-2(RSA 4096bit) | パスワード認証禁止 |
脆弱性対策
| 脅威 | 対策 |
| SQLインジェクション | プレースホルダー(バインド変数)必須。動的SQLの生文字列結合禁止 |
| XSS | テンプレートエンジンの自動エスケープ有効化。innerHTML 使用禁止 |
| CSRF | SameSite=Strict Cookie + CSRF トークン(状態変更リクエスト) |
| パスワード漏洩 | bcrypt ハッシュ保存。ログ・レスポンスへの平文出力禁止 |
| 不正ファイルアップロード | ファイル種別ホワイトリスト・ウイルススキャン・保存先はWebルート外 |
| 依存ライブラリの脆弱性 | CI/CD で dependabot + trivy によるスキャン(後述) |
監査ログ設計
| 監査対象操作 | 記録項目 | 保持期間 |
| ログイン・ログアウト | userId, ip, timestamp, 成否 | 5年 |
| 個人情報の参照 | userId, 対象データ種別, timestamp | 5年 |
| 重要データの更新・削除 | userId, 対象ID, 変更前後の値, timestamp | 5年 |
| ユーザー権限変更 | 変更者userId, 対象userId, 変更内容, timestamp | 5年 |
Python Tips — 依存パッケージの脆弱性スキャン
Python — pip-audit による脆弱性スキャン
"""
pip-audit で依存パッケージの既知脆弱性をスキャンする
pip install pip-audit
"""
import subprocess, json
def run_audit(format_json=True) -> dict | str:
cmd = ["pip-audit", "--format", "json"] if format_json else ["pip-audit"]
result = subprocess.run(cmd, capture_output=True, text=True)
if format_json:
try:
return json.loads(result.stdout)
except json.JSONDecodeError:
return {"error": result.stdout + result.stderr}
return result.stdout
def summarize(audit_result: dict) -> None:
vulnerabilities = audit_result.get("vulnerabilities", [])
if not vulnerabilities:
print("✅ 既知の脆弱性は検出されませんでした")
return
print(f"⚠️ {len(vulnerabilities)} 件の脆弱性を検出:")
for v in vulnerabilities:
for fix in v.get("fix_versions", []):
print(f" 📦 {v['name']} {v['version']} → {fix} にアップデート推奨")
for alias in v.get("aliases", [])[:2]:
print(f" CVE: {alias}")
result = run_audit()
summarize(result)
# CI/CD に組み込む場合(GitHub Actions 例)
# - name: Security scan
# run: |
# pip install pip-audit
# pip-audit --format json -o audit.json
# python check_audit.py ← このスクリプト
レビューチェックリスト
| # | チェック項目 |
| 1 | パスワードが bcrypt 等の強力なハッシュで保存されているか |
| 2 | JWT の有効期限・署名アルゴリズムが定義されているか |
| 3 | TLS 1.2以上・HSTS が設定されているか |
| 4 | SQLインジェクション対策(バインド変数)が徹底されているか |
| 5 | CSRF対策が定義されているか |
| 6 | 監査ログの対象操作・保持期間が定義されているか |
| 7 | 依存ライブラリの脆弱性スキャンが CI/CD に組み込まれているか |