threat-modeling について
threat-modelingは、システム設計時の脅威特定と軽減を支援するスキルで、開発・運用・セキュリティチームの協業を想定しています。STRIDE、データフロー図、脅威ライブラリ、リスク評価などの手法を提供します。
主な機能
- 01STRIDEによる脅威の分類
- 02データフローと信頼境界の図示
- 03再利用可能な脅威ライブラリの管理
- 04可能性と影響に基づくリスク評価
- 05対応方針と緩和策の記録
活用シーン
- 01システムや機能の設計時に脅威を評価
- 02アーキテクチャ変更や外部連携を確認
- 03セキュリティ監査やコンプライアンス審査の準備
- 04セキュリティインシデント後の防御改善
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill threat-modelingインストール後、Claude Code で/threat-modelingを入力して読み込まれたか確認します。
同梱ファイルreferences/threat-model-template.md
詳細
脅威モデリング
システム設計中にセキュリティ上の脅威を特定し、軽減します。
このスキルを使うタイミング
次の場合にこのスキルを使用します。
- 新しいシステム、サービス、機能を設計するとき
- 既存システムに大規模なアーキテクチャ変更を加えるとき
- 新しいサードパーティ統合や依存関係を導入するとき
- セキュリティ監査やコンプライアンスレビューに備えるとき
- 防御を強化するためにセキュリティインシデントに対応するとき
- 信頼境界に影響するインフラストラクチャの変更をレビューするとき
前提条件
- システムアーキテクチャのドキュメントまたは設計図
- 背景情報を得るための開発チームおよび運用チームへのアクセス
- システムのデータ分類(PII、PHI、財務情報など)に関する理解
- OWASP Threat Dragon または Microsoft Threat Modeling Tool(任意ですが、あると便利です)
- 共同作業に使用するホワイトボードまたは作図ツール
STRIDE 手法
| 脅威 | 説明 | 侵害される特性 | 軽減策の例 |
|---|---|---|---|
| Spoofing(なりすまし) | 別のユーザーまたはシステムになりすますこと | 認証 | MFA、mTLS、API キーの検証、証明書のピン留め |
| Tampering(改ざん) | 転送中または保存中のデータを変更すること | 完全性 | HMAC、デジタル署名、チェックサム、変更不可のログ |
| Repudiation(否認) | アクションを実行したことを否定すること | 否認防止 | 監査ログ、デジタル署名、改ざん検知可能なログ |
| Information Disclosure(情報漏えい) | 権限のない相手にデータを公開すること | 機密性 | 暗号化(TLS、AES)、アクセス制御、データマスキング |
| Denial of Service(サービス拒否) | サービスを利用不能にすること | 可用性 | レート制限、オートスケーリング、CDN、サーキットブレーカー |
| Elevation of Privilege(権限昇格) | 権限のない、より高いアクセス権を得ること | 認可 | RBAC、最小権限の原則、入力検証 |
STRIDE ワークシートテンプレート
# stride-worksheet.yaml - Fill out one per component/trust boundary crossing
component:
name: "API Gateway"
owner: "Platform Team"
data_classification: "Confidential"
trust_boundary: "External -> Internal"
threats:
- id: T001
category: Spoofing
description: "Attacker forges JWT tokens to impersonate users"
attack_vector: "Stolen signing key or weak algorithm (HS256 with guessable secret)"
likelihood: Medium
impact: Critical
risk_score: 15 # likelihood(3) x impact(5)
existing_controls:
- "JWT validation on every request"
- "RS256 algorithm with rotated keys"
gaps:
- "No token binding to device/IP"
recommended_mitigations:
- "Add token binding claims"
- "Implement short-lived tokens (15 min) with refresh"
- "Monitor for token reuse from different IPs"
status: "Mitigated (partial)"
owner: "Auth Team"
- id: T002
category: Tampering
description: "Man-in-the-middle modifies API requests"
attack_vector: "Compromised network between client and gateway"
likelihood: Low
impact: High
risk_score: 8
existing_controls:
- "TLS 1.3 enforced"
- "HSTS enabled"
gaps: []
recommended_mitigations:
- "Certificate pinning for mobile clients"
status: "Mitigated"
owner: "Platform Team"
- id: T003
category: Information Disclosure
description: "Verbose error messages leak internal details"
attack_vector: "Triggering errors returns stack traces, internal IPs, DB schema"
likelihood: High
impact: Medium
risk_score: 12
existing_controls:
- "Generic error pages in production"
gaps:
- "Some microservices return raw exceptions"
recommended_mitigations:
- "Centralized error handling middleware"
- "Error response schema validation"
status: "Open"
owner: "Backend Team"
- id: T004
category: Denial of Service
description: "API rate limiting bypass through distributed requests"
attack_vector: "Botnet sending requests below per-IP threshold"
likelihood: Medium
impact: High
risk_score: 12
existing_controls:
- "Per-IP rate limiting at WAF"
gaps:
- "No aggregate rate limiting"
- "No bot detection"
recommended_mitigations:
- "Add aggregate rate limiting per endpoint"
- "Deploy bot detection (Cloudflare Bot Management)"
- "Implement circuit breaker pattern"
status: "Open"
owner: "Platform Team"
- id: T005
category: Elevation of Privilege
description: "IDOR allows accessing other users' data"
attack_vector: "Manipulating resource IDs in API calls"
likelihood: Medium
impact: Critical
risk_score: 15
existing_controls:
- "Authentication required"
gaps:
- "Authorization checks inconsistent across endpoints"
recommended_mitigations:
- "Enforce ownership checks on all resource access"
- "Use opaque IDs instead of sequential integers"
- "Add authorization integration tests"
status: "Open"
owner: "Backend Team"
データフロー図
テキスト形式の DFD 表記
Trust Boundary: Internet
==========================
|
[External User]
|
HTTPS/443
|
==========================
Trust Boundary: DMZ
==========================
|
(WAF / CDN)
|
[API Gateway]---->[Auth Service]--->[Identity DB]
|
==========================
Trust Boundary: Internal
==========================
|
[App Service]
/ \
/ \
[Cache] [Message Queue]
|
[Worker Service]
|
==========================
Trust Boundary: Data
==========================
|
[Primary DB]--->[Replica DB]
|
[Object Store]
Legend:
[Box] = Process
(Parens) = External entity / proxy
==== = Trust boundary
---> = Data flow
Threat Dragon モデル(JSON)
{
"summary": {
"title": "E-Commerce Platform",
"owner": "Security Team",
"description": "Threat model for the e-commerce API platform"
},
"detail": {
"diagrams": [
{
"title": "API Data Flow",
"diagramType": "STRIDE",
"cells": [
{
"type": "tm.Actor",
"name": "Web Client",
"threats": []
},
{
"type": "tm.Process",
"name": "API Gateway",
"threats": ["T001", "T002", "T003", "T004"]
},
{
"type": "tm.Process",
"name": "Order Service",
"threats": ["T005"]
},
{
"type": "tm.Store",
"name": "Orders Database",
"threats": ["T006"]
},
{
"type": "tm.Boundary",
"name": "DMZ"
},
{
"type": "tm.Boundary",
"name": "Internal Network"
}
]
}
]
}
}
脅威ライブラリ
# threat-library.yaml - Reusable threat patterns
categories:
authentication:
- id: TL-AUTH-001
name: "Credential stuffing"
description: "Attacker uses leaked credential databases to attempt logins"
applicable_to: ["login endpoints", "API authentication"]
mitigations: ["MFA", "rate limiting", "credential breach monitoring", "CAPTCHA"]
- id: TL-AUTH-002
name: "Session hijacking"
description: "Attacker steals session tokens via XSS or network sniffing"
applicable_to: ["web applications", "APIs with session tokens"]
mitigations: ["HttpOnly cookies", "TLS", "session binding", "short TTL"]
- id: TL-AUTH-003
name: "OAuth token theft"
description: "Access tokens stolen from logs, URLs, or insecure storage"
applicable_to: ["OAuth/OIDC integrations"]
mitigations: ["PKCE", "short-lived tokens", "token binding", "secure storage"]
injection:
- id: TL-INJ-001
name: "SQL injection"
description: "Malicious SQL in user input executes unauthorized queries"
applicable_to: ["database-backed endpoints", "search functionality"]
mitigations: ["parameterized queries", "ORM", "input validation", "WAF"]
- id: TL-INJ-002
name: "Command injection"
description: "User input passed to system commands without sanitization"
applicable_to: ["file processing", "system administration features"]
mitigations: ["avoid shell commands", "input allowlisting", "sandboxing"]
- id: TL-INJ-003
name: "SSRF (Server-Side Request Forgery)"
description: "Attacker makes server send requests to internal resources"
applicable_to: ["URL fetching features", "webhook handlers", "PDF generators"]
mitigations: ["URL allowlisting", "network segmentation", "metadata endpoint blocking"]
supply_chain:
- id: TL-SC-001
name: "Dependency confusion"
description: "Malicious package with internal name published to public registry"
applicable_to: ["npm, pip, maven projects using private packages"]
mitigations: ["namespace scoping", "registry prioritization", "SBOM monitoring"]
- id: TL-SC-002
name: "Compromised CI/CD pipeline"
description: "Attacker injects malicious code through build system compromise"
applicable_to: ["all software builds"]
mitigations: ["SLSA compliance", "signed commits", "ephemeral builders", "provenance"]
data:
- id: TL-DATA-001
name: "Unencrypted data at rest"
description: "Sensitive data stored without encryption on disk or in database"
applicable_to: ["databases", "object storage", "backups"]
mitigations: ["AES-256 encryption", "KMS-managed keys", "encrypted volumes"]
- id: TL-DATA-002
name: "PII exposure in logs"
description: "Personal data written to application or infrastructure logs"
applicable_to: ["all services handling PII"]
mitigations: ["log sanitization", "structured logging", "PII detection scanning"]
リスク評価マトリクス
可能性の評価
| スコア | レベル | 説明 |
|---|---|---|
| 1 | 非常に低い | 国家レベルのリソースが必要で、既知のエクスプロイトはありません |
| 2 | 低い | 高度な専門知識と特定の条件が必要です |
| 3 | 中程度 | 利用可能なツールを使う、ある程度のスキルを持つ攻撃者です |
| 4 | 高い | 初心者レベルで実行でき、公開されているエクスプロイトがあります |
| 5 | 非常に高い | 簡単に悪用でき、自動スキャンで検出されます |
影響度の評価
| スコア | レベル | 説明 |
|---|---|---|
| 1 | 無視できる | データ漏えいはなく、外観上の問題のみです |
| 2 | 軽微 | 限定的なデータ漏えいがあり、影響を受けるのは単一のユーザーです |
| 3 | 中程度 | 重大なデータ漏えいがあり、サービスの性能が低下します |
| 4 | 重大 | 大規模なデータ侵害があり、長時間のサービス停止が発生します |
| 5 | 致命的 | システムが完全に侵害され、規制違反が発生します |
リスクマトリクス
Impact -> 1 2 3 4 5
Likelihood
5 Medium High High Critical Critical
4 Low Medium High High Critical
3 Low Low Medium High High
2 Info Low Low Medium High
1 Info Info Low Low Medium
リスク対応の判断
risk_treatment:
critical: # Score >= 20
action: "Immediate remediation required"
sla: "24 hours"
approval: "CISO"
high: # Score 12-19
action: "Remediation in current sprint"
sla: "1 week"
approval: "Security Lead"
medium: # Score 6-11
action: "Remediation in next sprint"
sla: "1 month"
approval: "Team Lead"
low: # Score 2-5
action: "Track and address in backlog"
sla: "1 quarter"
approval: "Team Lead"
info: # Score 1
action: "Accept risk and document"
sla: "None"
approval: "Team Lead"
OWASP Threat Dragon のセットアップ
# Run Threat Dragon locally with Docker
docker run -d \
--name threat-dragon \
-p 3000:3000 \
-e ENCRYPTION_KEYS='["threat-dragon-encryption-key-change-me"]' \
-e NODE_ENV=production \
owasp/threat-dragon:v2.2.0
# Access at http://localhost:3000
# Or install as desktop application
# Download from: https://github.com/OWASP/threat-dragon/releases
CI/CD との統合
# .github/workflows/threat-model-review.yml
name: Threat Model Review
on:
pull_request:
paths:
- 'docs/threat-model/**'
- 'architecture/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate threat model files
run: |
for model in docs/threat-model/*.yaml; do
echo "Validating $model..."
python -c "
import yaml, sys
with open('$model') as f:
data = yaml.safe_load(f)
required = ['component', 'threats']
for r in required:
if r not in data:
print(f'ERROR: Missing required field: {r}')
sys.exit(1)
for t in data.get('threats', []):
if t.get('status') == 'Open' and t.get('risk_score', 0) >= 12:
print(f'WARNING: High-risk open threat: {t[\"id\"]} - {t[\"description\"]}')
print(f'OK: {len(data[\"threats\"])} threats documented')
"
done
- name: Check for unaddressed critical threats
run: |
CRITICAL=$(grep -r "risk_score: \(1[5-9]\|2[0-5]\)" docs/threat-model/*.yaml | grep "status: \"Open\"" | wc -l)
if [ "$CRITICAL" -gt 0 ]; then
echo "WARNING: $CRITICAL critical/high-risk threats still open"
echo "Review required before merging architectural changes"
fi
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 脅威モデリングのセッションで成果が得られない | 参加者がシステムを理解していません | セッション前にアーキテクチャのドキュメントを共有し、システムの概要説明を行います |
| 特定される脅威が多すぎる | 範囲が広すぎます | セッションごとに 1 つのコンポーネントまたは信頼境界に絞ります |
| 脅威が漠然としすぎている | 構造化された手法がありません | 要素ごとに STRIDE を適用し、それぞれについてワークシートテンプレートに記入します |
| チームが調査結果に対応しない | 担当者や追跡手段がありません | 各脅威を SLA とともにチームに割り当て、課題管理ツールで追跡します |
| 脅威モデルが古くなっている | 更新のきっかけがありません | アーキテクチャ変更時にレビューを必須にします(図の変更時に CI/CD でゲートします) |
| リスクスコアについて意見が一致しない | 評価が主観的です | 評価マトリクスを一貫して使用し、過去のインシデントを基に評価基準を調整します |
ベストプラクティス
- 設計フェーズでSDLCに脅威モデリングを組み込みます
- アーキテクチャに変更があった場合は、脅威モデルをレビューします
- セッションには開発、運用、セキュリティの担当者を参加させます
- 脅威ライブラリを活用して、一貫性のある網羅性を確保します
- リスク受容に関するすべての判断を、根拠とともに文書化します
- 他の作業項目と同じシステムで脅威を追跡します
- 有効なすべての脅威モデルを毎年レビューします
- 最も重要なデータフローから始め、範囲を広げます
- セッションの時間を最大90分に制限します
- 新たなパターンを取り入れて、常に更新される脅威ライブラリを維持します
関連スキル
- sast-scanning - コード分析
- penetration-testing - 脅威モデルの調査結果の検証
- incident-response - 脅威が顕在化した際の対応
コメント
Markdown 対応