セキュリティ設計書の位置づけ

セキュリティ設計書は 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-GCMKMS でキー管理
JWT 署名RS256(RSA 2048bit)秘密鍵は環境変数管理
ファイル転送(SFTP)SSH-2(RSA 4096bit)パスワード認証禁止

脆弱性対策

脅威対策
SQLインジェクションプレースホルダー(バインド変数)必須。動的SQLの生文字列結合禁止
XSSテンプレートエンジンの自動エスケープ有効化。innerHTML 使用禁止
CSRFSameSite=Strict Cookie + CSRF トークン(状態変更リクエスト)
パスワード漏洩bcrypt ハッシュ保存。ログ・レスポンスへの平文出力禁止
不正ファイルアップロードファイル種別ホワイトリスト・ウイルススキャン・保存先はWebルート外
依存ライブラリの脆弱性CI/CD で dependabot + trivy によるスキャン(後述)

監査ログ設計

監査対象操作記録項目保持期間
ログイン・ログアウトuserId, ip, timestamp, 成否5年
個人情報の参照userId, 対象データ種別, timestamp5年
重要データの更新・削除userId, 対象ID, 変更前後の値, timestamp5年
ユーザー権限変更変更者userId, 対象userId, 変更内容, timestamp5年

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 等の強力なハッシュで保存されているか
2JWT の有効期限・署名アルゴリズムが定義されているか
3TLS 1.2以上・HSTS が設定されているか
4SQLインジェクション対策(バインド変数)が徹底されているか
5CSRF対策が定義されているか
6監査ログの対象操作・保持期間が定義されているか
7依存ライブラリの脆弱性スキャンが CI/CD に組み込まれているか