mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
462 lines
16 KiB
Markdown
462 lines
16 KiB
Markdown
---
|
|
name: threat-modeling
|
|
description: Conduct threat modeling using STRIDE methodology. Identify threats, assess risks, and design security controls. Use when designing secure systems or assessing application security.
|
|
license: MIT
|
|
metadata:
|
|
author: devops-skills
|
|
version: "1.0"
|
|
---
|
|
|
|
# Threat Modeling
|
|
|
|
Identify and mitigate security threats during system design.
|
|
|
|
## When to Use This Skill
|
|
|
|
Use this skill when:
|
|
- Designing a new system, service, or feature
|
|
- Making significant architectural changes to existing systems
|
|
- Onboarding a new third-party integration or dependency
|
|
- Preparing for security audits or compliance reviews
|
|
- Responding to a security incident to improve defenses
|
|
- Reviewing infrastructure changes that affect trust boundaries
|
|
|
|
## Prerequisites
|
|
|
|
- System architecture documentation or design diagrams
|
|
- Access to development and operations teams for context
|
|
- Understanding of the system's data classification (PII, PHI, financial, etc.)
|
|
- OWASP Threat Dragon or Microsoft Threat Modeling Tool (optional but helpful)
|
|
- Whiteboard or diagramming tool for collaborative sessions
|
|
|
|
## STRIDE Methodology
|
|
|
|
| Threat | Description | Property Violated | Mitigation Examples |
|
|
|--------|-------------|-------------------|---------------------|
|
|
| **S**poofing | Pretending to be another user or system | Authentication | MFA, mTLS, API key validation, certificate pinning |
|
|
| **T**ampering | Modifying data in transit or at rest | Integrity | HMAC, digital signatures, checksums, immutable logs |
|
|
| **R**epudiation | Denying having performed an action | Non-repudiation | Audit logging, digital signatures, tamper-evident logs |
|
|
| **I**nformation Disclosure | Exposing data to unauthorized parties | Confidentiality | Encryption (TLS, AES), access controls, data masking |
|
|
| **D**enial of Service | Making service unavailable | Availability | Rate limiting, autoscaling, CDN, circuit breakers |
|
|
| **E**levation of Privilege | Gaining unauthorized higher access | Authorization | RBAC, principle of least privilege, input validation |
|
|
|
|
## STRIDE Worksheet Template
|
|
|
|
```yaml
|
|
# 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"
|
|
```
|
|
|
|
## Data Flow Diagram
|
|
|
|
### Text-Based DFD Notation
|
|
|
|
```
|
|
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 Model (JSON)
|
|
|
|
```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
|
|
# 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"]
|
|
```
|
|
|
|
## Risk Scoring Matrix
|
|
|
|
### Likelihood Rating
|
|
|
|
| Score | Level | Description |
|
|
|-------|-------|-------------|
|
|
| 1 | Very Low | Requires nation-state resources; no known exploits |
|
|
| 2 | Low | Requires significant expertise and specific conditions |
|
|
| 3 | Medium | Moderately skilled attacker with available tools |
|
|
| 4 | High | Script-kiddie level; public exploits available |
|
|
| 5 | Very High | Trivial to exploit; automated scanning detects it |
|
|
|
|
### Impact Rating
|
|
|
|
| Score | Level | Description |
|
|
|-------|-------|-------------|
|
|
| 1 | Negligible | No data exposure; cosmetic only |
|
|
| 2 | Minor | Limited data exposure; single user affected |
|
|
| 3 | Moderate | Significant data exposure; service degradation |
|
|
| 4 | Major | Large-scale data breach; extended outage |
|
|
| 5 | Critical | Complete system compromise; regulatory breach |
|
|
|
|
### Risk Matrix
|
|
|
|
```
|
|
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 Decisions
|
|
|
|
```yaml
|
|
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 Setup
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
### Integration with CI/CD
|
|
|
|
```yaml
|
|
# .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
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
| Problem | Cause | Solution |
|
|
|---------|-------|----------|
|
|
| Threat model sessions are unproductive | Participants don't understand the system | Share architecture docs before the session; include a system walkthrough |
|
|
| Too many threats identified | Scope too broad | Focus on one component or trust boundary per session |
|
|
| Threats are too vague | No structured methodology | Use STRIDE per element; fill in the worksheet template for each |
|
|
| Team doesn't follow up on findings | No ownership or tracking | Assign each threat to a team with SLA; track in issue tracker |
|
|
| Threat model becomes stale | No trigger to update | Require review on architecture changes (CI/CD gate on diagram changes) |
|
|
| Disagreements on risk scores | Subjective scoring | Use the scoring matrix consistently; calibrate with historical incidents |
|
|
|
|
## Best Practices
|
|
|
|
- Integrate threat modeling into the SDLC at the design phase
|
|
- Review threat models when architecture changes occur
|
|
- Include developers, ops, and security in sessions
|
|
- Use the threat library to ensure consistent coverage
|
|
- Document all risk acceptance decisions with rationale
|
|
- Track threats in the same system as other work items
|
|
- Conduct annual reviews of all active threat models
|
|
- Start with the most critical data flows and expand
|
|
- Keep sessions timeboxed (90 minutes maximum)
|
|
- Maintain a living threat library updated with new patterns
|
|
|
|
## Related Skills
|
|
|
|
- [sast-scanning](../../scanning/sast-scanning/) - Code analysis
|
|
- [penetration-testing](../penetration-testing/) - Validation of threat model findings
|
|
- [incident-response](../incident-response/) - Response when threats materialize
|